Full Code of luqmana/rust-opencl for AI

master a104f56efb9c cached
20 files
137.0 KB
33.2k tokens
306 symbols
1 requests
Download .txt
Repository: luqmana/rust-opencl
Branch: master
Commit: a104f56efb9c
Files: 20
Total size: 137.0 KB

Directory structure:
gitextract_m_jlpnxy/

├── .gitignore
├── .travis.yml
├── COPYRIGHT
├── Cargo.toml
├── LICENSE-APACHE
├── LICENSE-MIT
├── Makefile
├── examples/
│   ├── demo/
│   │   ├── demo.ocl
│   │   └── main.rs
│   └── platform/
│       └── main.rs
├── src/
│   ├── OpenCL/
│   │   └── error.rs
│   ├── array.rs
│   ├── cl.rs
│   ├── error.rs
│   ├── ext.rs
│   ├── hl.rs
│   ├── lib.rs
│   ├── mem.rs
│   └── util.rs
└── tests/
    └── test.rs

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
*~
*.so
*.dylib
*.dSYM
opencl-test
target/
.rust
bin/
doc/
Cargo.lock
build/


================================================
FILE: .travis.yml
================================================
language: rust
rust: nightly

env:
  global:
    - secure: TUA5IHO5hwaQvgA1gAvslQ4QWhHEym5bFmmm7nAKHVIxRDchpCmjaLPmu3DirxRJBXi0b5zOZypIH75TMlivfnciQSWr9rj3PaaK+P6LpGScHvYsi/JEawtPJ8V5+xAvOKJ/HsNk5wGS+BBDv4YCPAG5itixMaFxQAVmKw1VMeo=
    - RUST_THREADS=4

install:
  - sudo apt-get update
  - sudo apt-get install fglrx opencl-headers

after_script:
- curl http://www.rust-ci.org/artifacts/put?t=$RUSTCI_TOKEN | sh

================================================
FILE: COPYRIGHT
================================================
rust-opencl - OpenCL Binding and Higher Level Wrapper for Rust.
Copyright (C) 2013 - The rust-opencl Developers

Licensed under the Apache License, Version 2.0 <http://www.apache.org/licenses/LICENSE-2.0>
or the MIT license <http://opensource.org/licenses/MIT>, at your option. All files in the project
may not be copied, modified, or distributed except according to those terms.

Copies of both licenses are included: LICENSE-APACHE and LICENSE-MIT


================================================
FILE: Cargo.toml
================================================
[package]
name = "opencl"
version = "0.3.0-dev"
authors = [ "Colin Sherratt <colin.sherratt@gmail.com>",
            "Eric Holk <eholk@cs.indiana.edu>",
            "Ian Daniher <it.daniher@gmail.com>",
            "Luqman Aden <me@luqman.ca>",
            "Milinda Pathirage <milinda.pathirage@gmail.com>",
            "Sébastien Crozet <developer@crozet.re>",
            "Mathijs Henquet <mathijs.henquet@gmail.com>"
          ]
repository = "https://github.com/luqmana/rust-opencl"
license = "MIT/Apache-2.0"
description = "OpenCL bindings for Rust."
keywords = ["opencl", "bindings", "ffi", "gpu", "compute"]

[lib]
name = "opencl"

[[example]]
name = "demo"
path = "examples/demo/main.rs"

[[example]]
name = "platform"
path = "examples/platform/main.rs"

[dependencies]
log = "^0.3.1"
libc = "^0.1.8"

================================================
FILE: LICENSE-APACHE
================================================
                              Apache License
                        Version 2.0, January 2004
                     http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

1. Definitions.

   "License" shall mean the terms and conditions for use, reproduction,
   and distribution as defined by Sections 1 through 9 of this document.

   "Licensor" shall mean the copyright owner or entity authorized by
   the copyright owner that is granting the License.

   "Legal Entity" shall mean the union of the acting entity and all
   other entities that control, are controlled by, or are under common
   control with that entity. For the purposes of this definition,
   "control" means (i) the power, direct or indirect, to cause the
   direction or management of such entity, whether by contract or
   otherwise, or (ii) ownership of fifty percent (50%) or more of the
   outstanding shares, or (iii) beneficial ownership of such entity.

   "You" (or "Your") shall mean an individual or Legal Entity
   exercising permissions granted by this License.

   "Source" form shall mean the preferred form for making modifications,
   including but not limited to software source code, documentation
   source, and configuration files.

   "Object" form shall mean any form resulting from mechanical
   transformation or translation of a Source form, including but
   not limited to compiled object code, generated documentation,
   and conversions to other media types.

   "Work" shall mean the work of authorship, whether in Source or
   Object form, made available under the License, as indicated by a
   copyright notice that is included in or attached to the work
   (an example is provided in the Appendix below).

   "Derivative Works" shall mean any work, whether in Source or Object
   form, that is based on (or derived from) the Work and for which the
   editorial revisions, annotations, elaborations, or other modifications
   represent, as a whole, an original work of authorship. For the purposes
   of this License, Derivative Works shall not include works that remain
   separable from, or merely link (or bind by name) to the interfaces of,
   the Work and Derivative Works thereof.

   "Contribution" shall mean any work of authorship, including
   the original version of the Work and any modifications or additions
   to that Work or Derivative Works thereof, that is intentionally
   submitted to Licensor for inclusion in the Work by the copyright owner
   or by an individual or Legal Entity authorized to submit on behalf of
   the copyright owner. For the purposes of this definition, "submitted"
   means any form of electronic, verbal, or written communication sent
   to the Licensor or its representatives, including but not limited to
   communication on electronic mailing lists, source code control systems,
   and issue tracking systems that are managed by, or on behalf of, the
   Licensor for the purpose of discussing and improving the Work, but
   excluding communication that is conspicuously marked or otherwise
   designated in writing by the copyright owner as "Not a Contribution."

   "Contributor" shall mean Licensor and any individual or Legal Entity
   on behalf of whom a Contribution has been received by Licensor and
   subsequently incorporated within the Work.

2. Grant of Copyright License. Subject to the terms and conditions of
   this License, each Contributor hereby grants to You a perpetual,
   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
   copyright license to reproduce, prepare Derivative Works of,
   publicly display, publicly perform, sublicense, and distribute the
   Work and such Derivative Works in Source or Object form.

3. Grant of Patent License. Subject to the terms and conditions of
   this License, each Contributor hereby grants to You a perpetual,
   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
   (except as stated in this section) patent license to make, have made,
   use, offer to sell, sell, import, and otherwise transfer the Work,
   where such license applies only to those patent claims licensable
   by such Contributor that are necessarily infringed by their
   Contribution(s) alone or by combination of their Contribution(s)
   with the Work to which such Contribution(s) was submitted. If You
   institute patent litigation against any entity (including a
   cross-claim or counterclaim in a lawsuit) alleging that the Work
   or a Contribution incorporated within the Work constitutes direct
   or contributory patent infringement, then any patent licenses
   granted to You under this License for that Work shall terminate
   as of the date such litigation is filed.

4. Redistribution. You may reproduce and distribute copies of the
   Work or Derivative Works thereof in any medium, with or without
   modifications, and in Source or Object form, provided that You
   meet the following conditions:

   (a) You must give any other recipients of the Work or
       Derivative Works a copy of this License; and

   (b) You must cause any modified files to carry prominent notices
       stating that You changed the files; and

   (c) You must retain, in the Source form of any Derivative Works
       that You distribute, all copyright, patent, trademark, and
       attribution notices from the Source form of the Work,
       excluding those notices that do not pertain to any part of
       the Derivative Works; and

   (d) If the Work includes a "NOTICE" text file as part of its
       distribution, then any Derivative Works that You distribute must
       include a readable copy of the attribution notices contained
       within such NOTICE file, excluding those notices that do not
       pertain to any part of the Derivative Works, in at least one
       of the following places: within a NOTICE text file distributed
       as part of the Derivative Works; within the Source form or
       documentation, if provided along with the Derivative Works; or,
       within a display generated by the Derivative Works, if and
       wherever such third-party notices normally appear. The contents
       of the NOTICE file are for informational purposes only and
       do not modify the License. You may add Your own attribution
       notices within Derivative Works that You distribute, alongside
       or as an addendum to the NOTICE text from the Work, provided
       that such additional attribution notices cannot be construed
       as modifying the License.

   You may add Your own copyright statement to Your modifications and
   may provide additional or different license terms and conditions
   for use, reproduction, or distribution of Your modifications, or
   for any such Derivative Works as a whole, provided Your use,
   reproduction, and distribution of the Work otherwise complies with
   the conditions stated in this License.

5. Submission of Contributions. Unless You explicitly state otherwise,
   any Contribution intentionally submitted for inclusion in the Work
   by You to the Licensor shall be under the terms and conditions of
   this License, without any additional terms or conditions.
   Notwithstanding the above, nothing herein shall supersede or modify
   the terms of any separate license agreement you may have executed
   with Licensor regarding such Contributions.

6. Trademarks. This License does not grant permission to use the trade
   names, trademarks, service marks, or product names of the Licensor,
   except as required for reasonable and customary use in describing the
   origin of the Work and reproducing the content of the NOTICE file.

7. Disclaimer of Warranty. Unless required by applicable law or
   agreed to in writing, Licensor provides the Work (and each
   Contributor provides its Contributions) on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
   implied, including, without limitation, any warranties or conditions
   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
   PARTICULAR PURPOSE. You are solely responsible for determining the
   appropriateness of using or redistributing the Work and assume any
   risks associated with Your exercise of permissions under this License.

8. Limitation of Liability. In no event and under no legal theory,
   whether in tort (including negligence), contract, or otherwise,
   unless required by applicable law (such as deliberate and grossly
   negligent acts) or agreed to in writing, shall any Contributor be
   liable to You for damages, including any direct, indirect, special,
   incidental, or consequential damages of any character arising as a
   result of this License or out of the use or inability to use the
   Work (including but not limited to damages for loss of goodwill,
   work stoppage, computer failure or malfunction, or any and all
   other commercial damages or losses), even if such Contributor
   has been advised of the possibility of such damages.

9. Accepting Warranty or Additional Liability. While redistributing
   the Work or Derivative Works thereof, You may choose to offer,
   and charge a fee for, acceptance of support, warranty, indemnity,
   or other liability obligations and/or rights consistent with this
   License. However, in accepting such obligations, You may act only
   on Your own behalf and on Your sole responsibility, not on behalf
   of any other Contributor, and only if You agree to indemnify,
   defend, and hold each Contributor harmless for any liability
   incurred by, or claims asserted against, such Contributor by reason
   of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

   To apply the Apache License to your work, attach the following
   boilerplate notice, with the fields enclosed by brackets "[]"
   replaced with your own identifying information. (Don't include
   the brackets!)  The text should be enclosed in the appropriate
   comment syntax for the file format. We also recommend that a
   file or class name and description of purpose be included on the
   same "printed page" as the copyright notice for easier
   identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

	http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.


================================================
FILE: LICENSE-MIT
================================================
MIT License
http://opensource.org/licenses/MIT

Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.


================================================
FILE: Makefile
================================================

ifndef RUSTC
	RUSTC = rustc
endif

ifndef TARGET_DIR
	TARGET_DIR = target/
endif

RUSTC_OPTS = -g -L $(TARGET_DIR) --out-dir $(TARGET_DIR)

OPENCL_SRC = \
	lib.rs \
	CL.rs \
	error.rs \
	hl.rs \
	util.rs \
	mem.rs \
	array.rs

OPENCL_ROOT = $(shell pwd)

.PHONY: all
all: lib


.PHONY: debug
debug: lib demo
	gdb --cd=./ target/demo


.PHONY: lib
lib: target_dir $(TARGET_DIR)libopencl.rlib

$(TARGET_DIR)libopencl.rlib: src/*
	rustc $(RUSTC_OPTS) src/lib.rs


.PHONY: target_dir
target_dir: $(TARGET_DIR)

$(TARGET_DIR):
	mkdir -p $(TARGET_DIR)


.PHONY: demo
demo: target_dir $(TARGET_DIR)demo

$(TARGET_DIR)demo: $(TARGET_DIR)libopencl.rlib test/demo.rs
	env OPENCL_ROOT=$(OPENCL_ROOT) rustc $(RUSTC_OPTS) test/demo.rs


.PHONY: check
check: lib
	rustc $(RUSTC_OPTS) --test test/test.rs
	$(TARGET_DIR)test


.PHONY: clean
clean:
	rm -rf $(TARGET_DIR)

.PHONY: docs
docs:
	rustdoc src/lib.rs


================================================
FILE: examples/demo/demo.ocl
================================================
__kernel void vector_add(__global const long *A, __global const long *B, __global long *C) {
	int i = get_global_id(0);
	C[i] = A[i] + B[i];
}


================================================
FILE: examples/demo/main.rs
================================================
extern crate opencl;

use opencl::mem::CLBuffer;
use std::fmt;

fn main()
{
    let ker = include_str!("demo.ocl");
    println!("ker {}", ker);

    let vec_a = vec![0isize, 1, 2, -3, 4, 5, 6, 7];
    let vec_b = vec![-7isize, -6, 5, -4, 0, -1, 2, 3];

    let (device, ctx, queue) = opencl::util::create_compute_context().unwrap();

    println!("{}", device.name());

    let a: CLBuffer<isize> = ctx.create_buffer(vec_a.len(), opencl::cl::CL_MEM_READ_ONLY);
    let b: CLBuffer<isize> = ctx.create_buffer(vec_a.len(), opencl::cl::CL_MEM_READ_ONLY);
    let c: CLBuffer<isize> = ctx.create_buffer(vec_a.len(), opencl::cl::CL_MEM_WRITE_ONLY);

    queue.write(&a, &&vec_a[..], ());
    queue.write(&b, &&vec_b[..], ());

    let program = ctx.create_program_from_source(ker);
    program.build(&device).ok().expect("Couldn't build program.");


    let kernel = program.create_kernel("vector_add");

    kernel.set_arg(0, &a);
    kernel.set_arg(1, &b);
    kernel.set_arg(2, &c);

    let event = queue.enqueue_async_kernel(&kernel, vec_a.len(), None, ());

    let vec_c: Vec<isize> = queue.get(&c, &event);

    println!("  {}", string_from_slice(&vec_a[..]));
    println!("+ {}", string_from_slice(&vec_b[..]));
    println!("= {}", string_from_slice(&vec_c[..]));
}

fn string_from_slice<T: fmt::Display>(slice: &[T]) -> String {
    let mut st = String::from("[");
    let mut first = true;

    for i in slice.iter() {
        if !first {
            st.push_str(", ");
        }
        else {
            first = false;
        }
        st.push_str(&*i.to_string())
    }

    st.push_str("]");
    return st
}


================================================
FILE: examples/platform/main.rs
================================================
extern crate opencl;

use opencl::hl;

fn main() {
    for platform in hl::get_platforms().iter() {
        println!("Platform: {}", platform.name());
        println!("Platform Version: {}", platform.version());
        println!("Vendor:   {}", platform.vendor());
        println!("Profile:  {}", platform.profile());
        println!("Available extensions: {}", platform.extensions());
        println!("Available devices:");
        for device in platform.get_devices().iter() {
            println!("   Name: {}", device.name());
            println!("   Type: {}", device.device_type());
            println!("   Profile: {}", device.profile());
            println!("   Compute Units: {}", device.compute_units());
        }
    }
}


================================================
FILE: src/OpenCL/error.rs
================================================
//! Error handling utilities.

use CL::*;
use std::fmt::{Show, Formatter, Result};

impl Show for CLStatus {
    fn fmt(&self, f: &mut Formatter) -> Result {
        write!(f.buf, "{:?}", *self)
    }
}

macro_rules! convert(
    ($e: expr, $x: ident) => (if $e == $x as cl_int {
        Some($x)
    } else { None });

    ($e: expr, $x: ident, $($xs: ident),+) => (if $e == $x as cl_int {
        Some($x)
    } else { convert!($e, $($xs),+) })
)

pub fn try_convert(status: cl_int) -> Option<CLStatus> {
    convert!(status,
             CL_SUCCESS,
             CL_DEVICE_NOT_FOUND,
             CL_DEVICE_NOT_AVAILABLE,
             CL_COMPILER_NOT_AVAILABLE,
             CL_MEM_OBJECT_ALLOCATION_FAILURE,
             CL_OUT_OF_RESOURCES,
             CL_OUT_OF_HOST_MEMORY,
             CL_PROFILING_INFO_NOT_AVAILABLE,
             CL_MEM_COPY_OVERLAP,
             CL_IMAGE_FORMAT_MISMATCH,
             CL_IMAGE_FORMAT_NOT_SUPPORTED,
             CL_BUILD_PROGRAM_FAILURE,
             CL_MAP_FAILURE,
             CL_MISALIGNED_SUB_BUFFER_OFFSET,
             CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST,
             CL_INVALID_VALUE,
             CL_INVALID_DEVICE_TYPE,
             CL_INVALID_PLATFORM,
             CL_INVALID_DEVICE,
             CL_INVALID_CONTEXT,
             CL_INVALID_QUEUE_PROPERTIES,
             CL_INVALID_COMMAND_QUEUE,
             CL_INVALID_HOST_PTR,
             CL_INVALID_MEM_OBJECT,
             CL_INVALID_IMAGE_FORMAT_DESCRIPTOR,
             CL_INVALID_IMAGE_SIZE,
             CL_INVALID_SAMPLER,
             CL_INVALID_BINARY,
             CL_INVALID_BUILD_OPTIONS,
             CL_INVALID_PROGRAM,
             CL_INVALID_PROGRAM_EXECUTABLE,
             CL_INVALID_KERNEL_NAME,
             CL_INVALID_KERNEL_DEFINITION,
             CL_INVALID_KERNEL,
             CL_INVALID_ARG_INDEX,
             CL_INVALID_ARG_VALUE,
             CL_INVALID_ARG_SIZE,
             CL_INVALID_KERNEL_ARGS,
             CL_INVALID_WORK_DIMENSION,
             CL_INVALID_WORK_GROUP_SIZE,
             CL_INVALID_WORK_ITEM_SIZE,
             CL_INVALID_GLOBAL_OFFSET,
             CL_INVALID_EVENT_WAIT_LIST,
             CL_INVALID_EVENT,
             CL_INVALID_OPERATION,
             CL_INVALID_GL_OBJECT,
             CL_INVALID_BUFFER_SIZE,
             CL_INVALID_MIP_LEVEL,
             CL_INVALID_GLOBAL_WORK_SIZE,
             CL_INVALID_PROPERTY)
}

pub fn convert(status: cl_int) -> CLStatus {
    match try_convert(status) {
        Some(s) => s,
        None => fail!(format!("Unknown OpenCL Status Code: {:?}", status))
    }
}

fn error_str(status: cl_int) -> ~str {
    match try_convert(status) {
        Some(s) => s.to_str(),
        None => format!("Unknown Error: {:?}", status)
    }
}

pub fn check(status: cl_int, message: &str) {
    if status != CL_SUCCESS as cl_int {
        fail!(format!("{:?} ({:?})", message, error_str(status)))
    }
}


================================================
FILE: src/array.rs
================================================
//! Two- and three-dimensional array support.

use cl::*;
use cl::ll::*;
use mem::*;
use std::marker::PhantomData;
use std::mem;
use std::vec::Vec;
use libc::{size_t, c_void};

use hl::KernelArg;

pub struct Array3D<T> {
    width: usize,
    height: usize,
    depth: usize,
    dat: Vec<T>
}

pub struct Array3DCL<T> {
    width: usize,
    height: usize,
    depth: usize,
    buf: cl_mem,
    phantom: PhantomData<T>,
}

impl<T: Clone> Array3D<T> {
    pub fn new<F>(width: usize, height: usize, depth: usize,
                  val: F)
               -> Array3D<T>
        where F: Fn(usize, usize, usize) -> T
    {
        let mut dat: Vec<T> = Vec::new();
        for x in 0 .. width {
            for y in 0 .. height {
                for z in 0 .. depth {
                    dat.push(val(x, y, z));
                }
            }
        }

        Array3D {
            width: width,
            height: height,
            depth: depth,
            dat: dat
        }
    }

    pub fn set(&mut self, x: usize, y: usize, z: usize, val: T)
    {
        self.dat[self.width*self.height*z + self.width*y + x] = val;
    }

    pub fn get(&self, x: usize, y: usize, z: usize) -> T
    {
        (&self.dat[..])[self.width*self.height*z + self.width*y + x].clone()
    }
}

impl<T> Drop for Array3DCL<T> {
    fn drop(&mut self) {
        unsafe {
            clReleaseMemObject(self.buf);
        }
    }
}

impl<'r, T> Put<Array3D<T>, Array3DCL<T>> for &'r Array3D<T>
{
    fn put<F>(&self, f: F)
           -> Array3DCL<T>
        where F: FnOnce(*const c_void, size_t) -> cl_mem
    {
        let p = self.dat.as_ptr();
        let len = self.dat.len();
        let out = f(p as *const c_void, (len * mem::size_of::<T>()) as size_t);

        Array3DCL{
            width: self.width,
            height: self.height,
            depth: self.depth,
            buf: out,
            phantom: PhantomData,
        }
    }
}


impl<T> Get<Array3DCL<T>, Array3D<T>> for Array3D<T>
{
    fn get<F>(arr: &Array3DCL<T>, f: F)
           -> Array3D<T>
        where F: FnOnce(size_t, *mut c_void, size_t)
    {
        let mut v: Vec<T> = Vec::with_capacity(arr.len());
        unsafe {
            v.set_len(arr.len());
        }

        let p = v.as_mut_ptr();
        let len = v.len();
        f(0, p as *mut c_void, (len * mem::size_of::<T>()) as size_t);

        Array3D {
            width: arr.width,
            height: arr.height,
            depth: arr.depth,
            dat: v,
        }
    }
}

impl<T> Write for Array3D<T> {
    fn write<F>(&self, f: F)
        where F: FnOnce(size_t, *const c_void, size_t)
    {
        let p = self.dat.as_ptr();
        let len = self.dat.len();
        f(0, p as *const c_void, (len * mem::size_of::<T>()) as size_t)
    }
}

impl<T> Read for Array3D<T> {
    fn read<F>(&mut self, f: F)
        where F: FnOnce(size_t, *mut c_void, size_t)
    {
        let p = self.dat.as_ptr();
        let len = self.dat.len();
        f(0, p as *mut c_void, (len * mem::size_of::<T>()) as size_t)
    }
}

impl<T> Buffer<T> for Array3DCL<T> {
    unsafe fn id_ptr(&self) -> *const cl_mem {
        &self.buf as *const cl_mem
    }

    fn len(&self) -> usize {
        self.width * self.height * self.depth
    }
}

impl<T> KernelArg for Array3DCL<T> {
    fn get_value(&self) -> (size_t, *const c_void)
    {
        (mem::size_of::<cl_mem>() as size_t,
         unsafe { self.id_ptr() } as *const c_void)
    }
}

pub struct Array2D<T> {
    width: usize,
    height: usize,
    dat: Vec<T>,
}

pub struct Array2DCL<T> {
    width: usize,
    height: usize,
    buf: cl_mem,
    phantom: PhantomData<T>,
}

impl<T: Clone> Array2D<T> {
    pub fn new<F>(width: usize, height: usize, val: F) -> Array2D<T>
        where F: Fn(usize, usize) -> T
    {
        let mut dat: Vec<T> = Vec::new();
        for x in 0 .. width {
            for y in 0 .. height {
                dat.push(val(x, y));
            }
        }
        Array2D {
            width: width,
            height: height,
            dat: dat,
        }
    }

    pub fn set(&mut self, x: usize, y: usize, val: T) {
        self.dat[self.width*y + x] = val;
    }

    pub fn get(&self, x: usize, y: usize) -> T {
        (&self.dat[..])[self.width*y + x].clone()
    }
}

impl<T> Drop for Array2DCL<T> {
    fn drop(&mut self) {
        unsafe {
            clReleaseMemObject(self.buf);
        }
    }
}

impl<'r, T> Put<Array2D<T>, Array2DCL<T>> for &'r Array2D<T>
{
    fn put<F>(&self, f: F) -> Array2DCL<T>
        where F: FnOnce(*const c_void, size_t) -> cl_mem
    {
        let p = self.dat.as_ptr();
        let len = self.dat.len();
        let out = f(p as *const c_void, (len * mem::size_of::<T>()) as size_t);

        Array2DCL{
            width: self.width,
            height: self.height,
            buf: out,
            phantom: PhantomData,
        }
    }
}


impl<T> Get<Array2DCL<T>, Array2D<T>> for Array2D<T>
{
    fn get<F>(arr: &Array2DCL<T>, f: F)
           -> Array2D<T>
        where F: FnOnce(size_t, *mut c_void, size_t)
    {
        let mut v: Vec<T> = Vec::with_capacity(arr.len());
        unsafe {
            v.set_len(arr.len())
        }

        let p = v.as_mut_ptr();
        let len = v.len();
        f(0, p as *mut c_void, (len * mem::size_of::<T>()) as size_t);

        Array2D {
            width: arr.width,
            height: arr.height,
            dat: v
        }
    }
}

impl<T> Write for Array2D<T> {
    fn write<F>(&self, f: F)
        where F: FnOnce(size_t, *const c_void, size_t)
    {
        let p = self.dat.as_ptr();
        let len = self.dat.len();
        f(0, p as *const c_void, (len * mem::size_of::<T>()) as size_t)
    }
}

impl<T> Read for Array2D<T> {
    fn read<F>(&mut self, f: F)
        where F: FnOnce(size_t, *mut c_void, size_t)
    {
        let p = self.dat.as_ptr();
        let len = self.dat.len();
        f(0, p as *mut c_void, (len * mem::size_of::<T>()) as size_t)
    }
}

impl<T> Buffer<T> for Array2DCL<T> {
    unsafe fn id_ptr(&self) -> *const cl_mem {
        &self.buf as *const cl_mem
    }

    fn len(&self) -> usize {
        self.width * self.height
    }
}

impl<T> KernelArg for Array2DCL<T> {
    fn get_value(&self) -> (size_t, *const c_void)
    {
        (mem::size_of::<cl_mem>() as size_t,
         unsafe { self.id_ptr() } as *const c_void)
    }
}


================================================
FILE: src/cl.rs
================================================
#![allow(non_camel_case_types, dead_code)]

extern crate std;

use libc;
use std::fmt;

/* Opaque types */
pub type cl_platform_id     = *mut libc::c_void;
pub type cl_device_id       = *mut libc::c_void;
pub type cl_context         = *mut libc::c_void;
pub type cl_command_queue   = *mut libc::c_void;
pub type cl_mem             = *mut libc::c_void;
pub type cl_program         = *mut libc::c_void;
pub type cl_kernel          = *mut libc::c_void;
pub type cl_event           = *mut libc::c_void;
pub type cl_sampler         = *mut libc::c_void;

/* Scalar types */
pub type cl_char    = i8;
pub type cl_uchar   = u8;
pub type cl_short   = i16;
pub type cl_ushort  = u16;
pub type cl_int     = i32;
pub type cl_uint    = u32;
pub type cl_long    = i64;
pub type cl_ulong   = u64;

pub type cl_half    = u16;
pub type cl_float   = f32;
pub type cl_double  = f64;

pub type cl_bool                        = cl_uint;
pub type cl_bitfield                    = cl_ulong;
pub type cl_device_type                 = cl_bitfield;
pub type cl_platform_info               = cl_uint;
pub type cl_device_info                 = cl_uint;
pub type cl_device_fp_config            = cl_bitfield;
pub type cl_device_mem_cache_type       = cl_uint;
pub type cl_device_local_mem_type       = cl_uint;
pub type cl_device_exec_capabilities    = cl_bitfield;
pub type cl_command_queue_properties    = cl_bitfield;

pub type cl_context_properties          = libc::intptr_t;
pub type cl_context_info                = cl_uint;
pub type cl_command_queue_info          = cl_uint;
pub type cl_channel_order               = cl_uint;
pub type cl_channel_type                = cl_uint;
pub type cl_mem_flags                   = cl_bitfield;
pub type cl_mem_object_type             = cl_uint;
pub type cl_mem_info                    = cl_uint;
pub type cl_image_info                  = cl_uint;
pub type cl_buffer_create_type          = cl_uint;
pub type cl_addressing_mode             = cl_uint;
pub type cl_filter_mode                 = cl_uint;
pub type cl_sampler_info                = cl_uint;
pub type cl_map_flags                   = cl_bitfield;
pub type cl_program_info                = cl_uint;
pub type cl_program_build_info          = cl_uint;
pub type cl_build_status                = cl_int;
pub type cl_kernel_info                 = cl_uint;
pub type cl_kernel_work_group_info      = cl_uint;
pub type cl_event_info                  = cl_uint;
pub type cl_command_type                = cl_uint;
pub type cl_profiling_info              = cl_uint;

pub struct cl_image_format {
    image_channel_order:        cl_channel_order,
    image_channel_data_type:    cl_channel_type
}

pub struct cl_buffer_region {
    origin:     libc::size_t,
    size:       libc::size_t
}


/// OpenCL error codes.
#[derive(PartialEq, Debug)]
#[repr()]
pub enum CLStatus {
    CL_SUCCESS = 0,
    CL_DEVICE_NOT_FOUND = -1,
    CL_DEVICE_NOT_AVAILABLE = -2,
    CL_COMPILER_NOT_AVAILABLE = -3,
    CL_MEM_OBJECT_ALLOCATION_FAILURE = -4,
    CL_OUT_OF_RESOURCES = -5,
    CL_OUT_OF_HOST_MEMORY = -6,
    CL_PROFILING_INFO_NOT_AVAILABLE = -7,
    CL_MEM_COPY_OVERLAP = -8,
    CL_IMAGE_FORMAT_MISMATCH = -9,
    CL_IMAGE_FORMAT_NOT_SUPPORTED = -10,
    CL_BUILD_PROGRAM_FAILURE = -11,
    CL_MAP_FAILURE = -12,
    CL_MISALIGNED_SUB_BUFFER_OFFSET = -13,
    CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST = -14,
    CL_INVALID_VALUE = -30,
    CL_INVALID_DEVICE_TYPE = -31,
    CL_INVALID_PLATFORM = -32,
    CL_INVALID_DEVICE = -33,
    CL_INVALID_CONTEXT = -34,
    CL_INVALID_QUEUE_PROPERTIES = -35,
    CL_INVALID_COMMAND_QUEUE = -36,
    CL_INVALID_HOST_PTR = -37,
    CL_INVALID_MEM_OBJECT = -38,
    CL_INVALID_IMAGE_FORMAT_DESCRIPTOR = -39,
    CL_INVALID_IMAGE_SIZE = -40,
    CL_INVALID_SAMPLER = -41,
    CL_INVALID_BINARY = -42,
    CL_INVALID_BUILD_OPTIONS = -43,
    CL_INVALID_PROGRAM = -44,
    CL_INVALID_PROGRAM_EXECUTABLE = -45,
    CL_INVALID_KERNEL_NAME = -46,
    CL_INVALID_KERNEL_DEFINITION = -47,
    CL_INVALID_KERNEL = -48,
    CL_INVALID_ARG_INDEX = -49,
    CL_INVALID_ARG_VALUE = -50,
    CL_INVALID_ARG_SIZE = -51,
    CL_INVALID_KERNEL_ARGS = -52,
    CL_INVALID_WORK_DIMENSION = -53,
    CL_INVALID_WORK_GROUP_SIZE = -54,
    CL_INVALID_WORK_ITEM_SIZE = -55,
    CL_INVALID_GLOBAL_OFFSET = -56,
    CL_INVALID_EVENT_WAIT_LIST = -57,
    CL_INVALID_EVENT = -58,
    CL_INVALID_OPERATION = -59,
    CL_INVALID_GL_OBJECT = -60,
    CL_INVALID_BUFFER_SIZE = -61,
    CL_INVALID_MIP_LEVEL = -62,
    CL_INVALID_GLOBAL_WORK_SIZE = -63,
    CL_INVALID_PROPERTY = -64,
    CL_PLATFORM_NOT_FOUND_KHR = -1001,
}

impl fmt::Display for CLStatus {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

/* OpenCL Version */
pub static CL_VERSION_1_0:                               cl_bool = 1;
pub static CL_VERSION_1_1:                               cl_bool = 1;

/* cl_bool */
pub static CL_FALSE:                                     cl_bool = 0;
pub static CL_TRUE:                                      cl_bool = 1;

/* cl_platform_info */
pub static CL_PLATFORM_PROFILE:                          cl_uint = 0x0900;
pub static CL_PLATFORM_VERSION:                          cl_uint = 0x0901;
pub static CL_PLATFORM_NAME:                             cl_uint = 0x0902;
pub static CL_PLATFORM_VENDOR:                           cl_uint = 0x0903;
pub static CL_PLATFORM_EXTENSIONS:                       cl_uint = 0x0904;

/* cl_device_type - bitfield */
pub static CL_DEVICE_TYPE_DEFAULT:                       cl_bitfield = 1 << 0;
pub static CL_DEVICE_TYPE_CPU:                           cl_bitfield = 1 << 1;
pub static CL_DEVICE_TYPE_GPU:                           cl_bitfield = 1 << 2;
pub static CL_DEVICE_TYPE_ACCELERATOR:                   cl_bitfield = 1 << 3;
pub static CL_DEVICE_TYPE_ALL:                           cl_bitfield = 0xFFFFFFFF;

/* cl_device_info */
pub static CL_DEVICE_TYPE:                               cl_uint = 0x1000;
pub static CL_DEVICE_VENDOR_ID:                          cl_uint = 0x1001;
pub static CL_DEVICE_MAX_COMPUTE_UNITS:                  cl_uint = 0x1002;
pub static CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS:           cl_uint = 0x1003;
pub static CL_DEVICE_MAX_WORK_GROUP_SIZE:                cl_uint = 0x1004;
pub static CL_DEVICE_MAX_WORK_ITEM_SIZES:                cl_uint = 0x1005;
pub static CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR:        cl_uint = 0x1006;
pub static CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT:       cl_uint = 0x1007;
pub static CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT:         cl_uint = 0x1008;
pub static CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG:        cl_uint = 0x1009;
pub static CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT:       cl_uint = 0x100A;
pub static CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE:      cl_uint = 0x100B;
pub static CL_DEVICE_MAX_CLOCK_FREQUENCY:                cl_uint = 0x100C;
pub static CL_DEVICE_ADDRESS_BITS:                       cl_uint = 0x100D;
pub static CL_DEVICE_MAX_READ_IMAGE_ARGS:                cl_uint = 0x100E;
pub static CL_DEVICE_MAX_WRITE_IMAGE_ARGS:               cl_uint = 0x100F;
pub static CL_DEVICE_MAX_MEM_ALLOC_SIZE:                 cl_uint = 0x1010;
pub static CL_DEVICE_IMAGE2D_MAX_WIDTH:                  cl_uint = 0x1011;
pub static CL_DEVICE_IMAGE2D_MAX_HEIGHT:                 cl_uint = 0x1012;
pub static CL_DEVICE_IMAGE3D_MAX_WIDTH:                  cl_uint = 0x1013;
pub static CL_DEVICE_IMAGE3D_MAX_HEIGHT:                 cl_uint = 0x1014;
pub static CL_DEVICE_IMAGE3D_MAX_DEPTH:                  cl_uint = 0x1015;
pub static CL_DEVICE_IMAGE_SUPPORT:                      cl_uint = 0x1016;
pub static CL_DEVICE_MAX_PARAMETER_SIZE:                 cl_uint = 0x1017;
pub static CL_DEVICE_MAX_SAMPLERS:                       cl_uint = 0x1018;
pub static CL_DEVICE_MEM_BASE_ADDR_ALIGN:                cl_uint = 0x1019;
pub static CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE:           cl_uint = 0x101A;
pub static CL_DEVICE_SINGLE_FP_CONFIG:                   cl_uint = 0x101B;
pub static CL_DEVICE_GLOBAL_MEM_CACHE_TYPE:              cl_uint = 0x101C;
pub static CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE:          cl_uint = 0x101D;
pub static CL_DEVICE_GLOBAL_MEM_CACHE_SIZE:              cl_uint = 0x101E;
pub static CL_DEVICE_GLOBAL_MEM_SIZE:                    cl_uint = 0x101F;
pub static CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE:           cl_uint = 0x1020;
pub static CL_DEVICE_MAX_CONSTANT_ARGS:                  cl_uint = 0x1021;
pub static CL_DEVICE_LOCAL_MEM_TYPE:                     cl_uint = 0x1022;
pub static CL_DEVICE_LOCAL_MEM_SIZE:                     cl_uint = 0x1023;
pub static CL_DEVICE_ERROR_CORRECTION_SUPPORT:           cl_uint = 0x1024;
pub static CL_DEVICE_PROFILING_TIMER_RESOLUTION:         cl_uint = 0x1025;
pub static CL_DEVICE_ENDIAN_LITTLE:                      cl_uint = 0x1026;
pub static CL_DEVICE_AVAILABLE:                          cl_uint = 0x1027;
pub static CL_DEVICE_COMPILER_AVAILABLE:                 cl_uint = 0x1028;
pub static CL_DEVICE_EXECUTION_CAPABILITIES:             cl_uint = 0x1029;
pub static CL_DEVICE_QUEUE_PROPERTIES:                   cl_uint = 0x102A;
pub static CL_DEVICE_NAME:                               cl_uint = 0x102B;
pub static CL_DEVICE_VENDOR:                             cl_uint = 0x102C;
pub static CL_DRIVER_VERSION:                            cl_uint = 0x102D;
pub static CL_DEVICE_PROFILE:                            cl_uint = 0x102E;
pub static CL_DEVICE_VERSION:                            cl_uint = 0x102F;
pub static CL_DEVICE_EXTENSIONS:                         cl_uint = 0x1030;
pub static CL_DEVICE_PLATFORM:                           cl_uint = 0x1031;
/* 0x1032 reserved for CL_DEVICE_DOUBLE_FP_CONFIG */
/* 0x1033 reserved for CL_DEVICE_HALF_FP_CONFIG */
pub static CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF:        cl_uint = 0x1034;
pub static CL_DEVICE_HOST_UNIFIED_MEMORY:                cl_uint = 0x1035;
pub static CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR:           cl_uint = 0x1036;
pub static CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT:          cl_uint = 0x1037;
pub static CL_DEVICE_NATIVE_VECTOR_WIDTH_INT:            cl_uint = 0x1038;
pub static CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG:           cl_uint = 0x1039;
pub static CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT:          cl_uint = 0x103A;
pub static CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE:         cl_uint = 0x103B;
pub static CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF:           cl_uint = 0x103C;
pub static CL_DEVICE_OPENCL_C_VERSION:                   cl_uint = 0x103D;

/* cl_device_fp_config - bitfield */
pub static CL_FP_DENORM:                                 cl_bitfield = 1 << 0;
pub static CL_FP_INF_NAN:                                cl_bitfield = 1 << 1;
pub static CL_FP_ROUND_TO_NEAREST:                       cl_bitfield = 1 << 2;
pub static CL_FP_ROUND_TO_ZERO:                          cl_bitfield = 1 << 3;
pub static CL_FP_ROUND_TO_INF:                           cl_bitfield = 1 << 4;
pub static CL_FP_FMA:                                    cl_bitfield = 1 << 5;
pub static CL_FP_SOFT_FLOAT:                             cl_bitfield = 1 << 6;

/* cl_device_mem_cache_type */
pub static CL_NONE:                                      cl_uint = 0x0;
pub static CL_READ_ONLY_CACHE:                           cl_uint = 0x1;
pub static CL_READ_WRITE_CACHE:                          cl_uint = 0x2;

/* cl_device_local_mem_type */
pub static CL_LOCAL:                                     cl_uint = 0x1;
pub static CL_GLOBAL:                                    cl_uint = 0x2;

/* cl_device_exec_capabilities - bitfield */
pub static CL_EXEC_KERNEL:                               cl_bitfield = 1 << 0;
pub static CL_EXEC_NATIVE_KERNEL:                        cl_bitfield = 1 << 1;

/* cl_command_queue_properties - bitfield */
pub static CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE:       cl_bitfield = 1 << 0;
pub static CL_QUEUE_PROFILING_ENABLE:                    cl_bitfield = 1 << 1;

/* cl_context_info  */
pub static CL_CONTEXT_REFERENCE_COUNT:                   cl_uint = 0x1080;
pub static CL_CONTEXT_DEVICES:                           cl_uint = 0x1081;
pub static CL_CONTEXT_PROPERTIES:                        cl_uint = 0x1082;
pub static CL_CONTEXT_NUM_DEVICES:                       cl_uint = 0x1083;

/* cl_context_info + cl_context_properties */
pub static CL_CONTEXT_PLATFORM:                          libc::intptr_t = 0x1084;

/* cl_command_queue_info */
pub static CL_QUEUE_CONTEXT:                             cl_uint = 0x1090;
pub static CL_QUEUE_DEVICE:                              cl_uint = 0x1091;
pub static CL_QUEUE_REFERENCE_COUNT:                     cl_uint = 0x1092;
pub static CL_QUEUE_PROPERTIES:                          cl_uint = 0x1093;

/* cl_mem_flags - bitfield */
pub static CL_MEM_READ_WRITE:                            cl_bitfield = 1 << 0;
pub static CL_MEM_WRITE_ONLY:                            cl_bitfield = 1 << 1;
pub static CL_MEM_READ_ONLY:                             cl_bitfield = 1 << 2;
pub static CL_MEM_USE_HOST_PTR:                          cl_bitfield = 1 << 3;
pub static CL_MEM_ALLOC_HOST_PTR:                        cl_bitfield = 1 << 4;
pub static CL_MEM_COPY_HOST_PTR:                         cl_bitfield = 1 << 5;

/* cl_channel_order */
pub static CL_R:                                         cl_uint = 0x10B0;
pub static CL_A:                                         cl_uint = 0x10B1;
pub static CL_RG:                                        cl_uint = 0x10B2;
pub static CL_RA:                                        cl_uint = 0x10B3;
pub static CL_RGB:                                       cl_uint = 0x10B4;
pub static CL_RGBA:                                      cl_uint = 0x10B5;
pub static CL_BGRA:                                      cl_uint = 0x10B6;
pub static CL_ARGB:                                      cl_uint = 0x10B7;
pub static CL_INTENSITY:                                 cl_uint = 0x10B8;
pub static CL_LUMINANCE:                                 cl_uint = 0x10B9;
pub static CL_Rx:                                        cl_uint = 0x10BA;
pub static CL_RGx:                                       cl_uint = 0x10BB;
pub static CL_RGBx:                                      cl_uint = 0x10BC;

/* cl_channel_type */
pub static CL_SNORM_INT8:                                cl_uint = 0x10D0;
pub static CL_SNORM_INT16:                               cl_uint = 0x10D1;
pub static CL_UNORM_INT8:                                cl_uint = 0x10D2;
pub static CL_UNORM_INT16:                               cl_uint = 0x10D3;
pub static CL_UNORM_SHORT_565:                           cl_uint = 0x10D4;
pub static CL_UNORM_SHORT_555:                           cl_uint = 0x10D5;
pub static CL_UNORM_INT_101010:                          cl_uint = 0x10D6;
pub static CL_SIGNED_INT8:                               cl_uint = 0x10D7;
pub static CL_SIGNED_INT16:                              cl_uint = 0x10D8;
pub static CL_SIGNED_INT32:                              cl_uint = 0x10D9;
pub static CL_UNSIGNED_INT8:                             cl_uint = 0x10DA;
pub static CL_UNSIGNED_INT16:                            cl_uint = 0x10DB;
pub static CL_UNSIGNED_INT32:                            cl_uint = 0x10DC;
pub static CL_HALF_FLOAT:                                cl_uint = 0x10DD;
pub static CL_FLOAT:                                     cl_uint = 0x10DE;

/* cl_mem_object_type */
pub static CL_MEM_OBJECT_BUFFER:                         cl_uint = 0x10F0;
pub static CL_MEM_OBJECT_IMAGE2D:                        cl_uint = 0x10F1;
pub static CL_MEM_OBJECT_IMAGE3D:                        cl_uint = 0x10F2;

/* cl_mem_info */
pub static CL_MEM_TYPE:                                  cl_uint = 0x1100;
pub static CL_MEM_FLAGS:                                 cl_uint = 0x1101;
pub static CL_MEM_SIZE:                                  cl_uint = 0x1102;
pub static CL_MEM_HOST_PTR:                              cl_uint = 0x1103;
pub static CL_MEM_MAP_COUNT:                             cl_uint = 0x1104;
pub static CL_MEM_REFERENCE_COUNT:                       cl_uint = 0x1105;
pub static CL_MEM_CONTEXT:                               cl_uint = 0x1106;
pub static CL_MEM_ASSOCIATED_MEMOBJECT:                  cl_uint = 0x1107;
pub static CL_MEM_OFFSET:                                cl_uint = 0x1108;

/* cl_image_info */
pub static CL_IMAGE_FORMAT:                              cl_uint = 0x1110;
pub static CL_IMAGE_ELEMENT_SIZE:                        cl_uint = 0x1111;
pub static CL_IMAGE_ROW_PITCH:                           cl_uint = 0x1112;
pub static CL_IMAGE_SLICE_PITCH:                         cl_uint = 0x1113;
pub static CL_IMAGE_WIDTH:                               cl_uint = 0x1114;
pub static CL_IMAGE_HEIGHT:                              cl_uint = 0x1115;
pub static CL_IMAGE_DEPTH:                               cl_uint = 0x1116;

/* cl_addressing_mode */
pub static CL_ADDRESS_NONE:                              cl_uint = 0x1130;
pub static CL_ADDRESS_CLAMP_TO_EDGE:                     cl_uint = 0x1131;
pub static CL_ADDRESS_CLAMP:                             cl_uint = 0x1132;
pub static CL_ADDRESS_REPEAT:                            cl_uint = 0x1133;
pub static CL_ADDRESS_MIRRORED_REPEAT:                   cl_uint = 0x1134;

/* cl_filter_mode */
pub static CL_FILTER_NEAREST:                            cl_uint = 0x1140;
pub static CL_FILTER_LINEAR:                             cl_uint = 0x1141;

/* cl_sampler_info */
pub static CL_SAMPLER_REFERENCE_COUNT:                   cl_uint = 0x1150;
pub static CL_SAMPLER_CONTEXT:                           cl_uint = 0x1151;
pub static CL_SAMPLER_NORMALIZED_COORDS:                 cl_uint = 0x1152;
pub static CL_SAMPLER_ADDRESSING_MODE:                   cl_uint = 0x1153;
pub static CL_SAMPLER_FILTER_MODE:                       cl_uint = 0x1154;

/* cl_map_flags - bitfield */
pub static CL_MAP_READ:                                  cl_bitfield = 1 << 0;
pub static CL_MAP_WRITE:                                 cl_bitfield = 1 << 1;

/* cl_program_info */
pub static CL_PROGRAM_REFERENCE_COUNT:                   cl_uint = 0x1160;
pub static CL_PROGRAM_CONTEXT:                           cl_uint = 0x1161;
pub static CL_PROGRAM_NUM_DEVICES:                       cl_uint = 0x1162;
pub static CL_PROGRAM_DEVICES:                           cl_uint = 0x1163;
pub static CL_PROGRAM_SOURCE:                            cl_uint = 0x1164;
pub static CL_PROGRAM_BINARY_SIZES:                      cl_uint = 0x1165;
pub static CL_PROGRAM_BINARIES:                          cl_uint = 0x1166;

/* cl_program_build_info */
pub static CL_PROGRAM_BUILD_STATUS:                      cl_uint = 0x1181;
pub static CL_PROGRAM_BUILD_OPTIONS:                     cl_uint = 0x1182;
pub static CL_PROGRAM_BUILD_LOG:                         cl_uint = 0x1183;

/* cl_build_status */
pub static CL_BUILD_SUCCESS:                             cl_uint = 0;
pub static CL_BUILD_NONE:                                cl_uint = (-1isize) as cl_uint;
pub static CL_BUILD_ERROR:                               cl_uint = -2isize as cl_uint;
pub static CL_BUILD_IN_PROGRESS:                         cl_uint = -3isize as cl_uint;

/* cl_kernel_info */
pub static CL_KERNEL_FUNCTION_NAME:                      cl_uint = 0x1190;
pub static CL_KERNEL_NUM_ARGS:                           cl_uint = 0x1191;
pub static CL_KERNEL_REFERENCE_COUNT:                    cl_uint = 0x1192;
pub static CL_KERNEL_CONTEXT:                            cl_uint = 0x1193;
pub static CL_KERNEL_PROGRAM:                            cl_uint = 0x1194;

/* cl_kernel_work_group_info */
pub static CL_KERNEL_WORK_GROUP_SIZE:                    cl_uint = 0x11B0;
pub static CL_KERNEL_COMPILE_WORK_GROUP_SIZE:            cl_uint = 0x11B1;
pub static CL_KERNEL_LOCAL_MEM_SIZE:                     cl_uint = 0x11B2;
pub static CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE: cl_uint = 0x11B3;
pub static CL_KERNEL_PRIVATE_MEM_SIZE:                   cl_uint = 0x11B4;

/* cl_event_info  */
pub static CL_EVENT_COMMAND_QUEUE:                       cl_uint = 0x11D0;
pub static CL_EVENT_COMMAND_TYPE:                        cl_uint = 0x11D1;
pub static CL_EVENT_REFERENCE_COUNT:                     cl_uint = 0x11D2;
pub static CL_EVENT_COMMAND_EXECUTION_STATUS:            cl_uint = 0x11D3;
pub static CL_EVENT_CONTEXT:                             cl_uint = 0x11D4;

/* cl_command_type */
pub static CL_COMMAND_NDRANGE_KERNEL:                    cl_uint = 0x11F0;
pub static CL_COMMAND_TASK:                              cl_uint = 0x11F1;
pub static CL_COMMAND_NATIVE_KERNEL:                     cl_uint = 0x11F2;
pub static CL_COMMAND_READ_BUFFER:                       cl_uint = 0x11F3;
pub static CL_COMMAND_WRITE_BUFFER:                      cl_uint = 0x11F4;
pub static CL_COMMAND_COPY_BUFFER:                       cl_uint = 0x11F5;
pub static CL_COMMAND_READ_IMAGE:                        cl_uint = 0x11F6;
pub static CL_COMMAND_WRITE_IMAGE:                       cl_uint = 0x11F7;
pub static CL_COMMAND_COPY_IMAGE:                        cl_uint = 0x11F8;
pub static CL_COMMAND_COPY_IMAGE_TO_BUFFER:              cl_uint = 0x11F9;
pub static CL_COMMAND_COPY_BUFFER_TO_IMAGE:              cl_uint = 0x11FA;
pub static CL_COMMAND_MAP_BUFFER:                        cl_uint = 0x11FB;
pub static CL_COMMAND_MAP_IMAGE:                         cl_uint = 0x11FC;
pub static CL_COMMAND_UNMAP_MEM_OBJECT:                  cl_uint = 0x11FD;
pub static CL_COMMAND_MARKER:                            cl_uint = 0x11FE;
pub static CL_COMMAND_ACQUIRE_GL_OBJECTS:                cl_uint = 0x11FF;
pub static CL_COMMAND_RELEASE_GL_OBJECTS:                cl_uint = 0x1200;
pub static CL_COMMAND_READ_BUFFER_RECT:                  cl_uint = 0x1201;
pub static CL_COMMAND_WRITE_BUFFER_RECT:                 cl_uint = 0x1202;
pub static CL_COMMAND_COPY_BUFFER_RECT:                  cl_uint = 0x1203;
pub static CL_COMMAND_USER:                              cl_uint = 0x1204;

/* command execution status */
pub static CL_COMPLETE:                                  cl_uint = 0x0;
pub static CL_RUNNING:                                   cl_uint = 0x1;
pub static CL_SUBMITTED:                                 cl_uint = 0x2;
pub static CL_QUEUED:                                    cl_uint = 0x3;

/* cl_buffer_create_type  */
pub static CL_BUFFER_CREATE_TYPE_REGION:                 cl_uint = 0x1220;

/* cl_profiling_info  */
pub static CL_PROFILING_COMMAND_QUEUED:                  cl_uint = 0x1280;
pub static CL_PROFILING_COMMAND_SUBMIT:                  cl_uint = 0x1281;
pub static CL_PROFILING_COMMAND_START:                   cl_uint = 0x1282;
pub static CL_PROFILING_COMMAND_END:                     cl_uint = 0x1283;


pub mod ll {
  use cl::*;
  use libc;


  extern
  {
    /* Platform APIs */
    pub fn clGetPlatformIDs(num_entries:   cl_uint,
                            platforms:     *mut cl_platform_id,
                            num_platforms: *mut cl_uint) -> cl_int;
    pub fn clGetPlatformInfo(platform: cl_platform_id,
                             param_name: cl_platform_info,
                             param_value_size: libc::size_t,
                             param_value: *mut libc::c_void,
                             param_value_size_ret: *mut libc::size_t) -> cl_int;

    /* Device APIs */
    pub fn clGetDeviceIDs(platform: cl_platform_id,
                      device_type: cl_device_type,
                      num_entries: cl_uint,
                      devices: *mut cl_device_id,
                      num_devices: *mut cl_uint) -> cl_int;
    pub fn clGetDeviceInfo(device: cl_device_id,
                       param_name: cl_device_info,
                       param_value_size: libc::size_t,
                       param_value: *mut libc::c_void,
                       param_value_size_ret: *mut libc::size_t) -> cl_int;

    /* Context APIs */
    pub fn clCreateContext(properties: *const cl_context_properties,
                       num_devices: cl_uint,
                       devices: *const cl_device_id,
                       pfn_notify: extern fn (*const libc::c_char, *const libc::c_void, libc::size_t, *mut libc::c_void),
                       user_data: *mut libc::c_void,
                       errcode_ret: *mut cl_int) -> cl_context;
    pub fn clCreateContextFromType(properties: *mut cl_context_properties,
                               device_type: cl_device_type,
                               pfn_notify: extern fn (*mut libc::c_char, *mut libc::c_void, libc::size_t, *mut libc::c_void),
                               user_data: *mut libc::c_void,
                               errcode_ret: *mut cl_int) -> cl_context;
    pub fn clRetainContext(context: cl_context) -> cl_int;
    pub fn clReleaseContext(context: cl_context) -> cl_int;
    pub fn clGetContextInfo(context: cl_context,
                        param_name: cl_context_info,
                        param_value_size: libc::size_t,
                        param_value: *mut libc::c_void,
                        param_value_size_ret: *mut libc::size_t) -> cl_int;

    /* Command Queue APIs */
    pub fn clCreateCommandQueue(context: cl_context,
                            device: cl_device_id,
                            properties: cl_command_queue_properties,
                            errcode_ret: *mut cl_int) -> cl_command_queue;
    pub fn clRetainCommandQueue(command_queue: cl_command_queue) -> cl_int;
    pub fn clReleaseCommandQueue(command_queue: cl_command_queue) -> cl_int;
    pub fn clGetCommandQueueInfo(command_queue: cl_command_queue,
                             param_name: cl_command_queue_info,
                             param_value_size: libc::size_t,
                             param_value: *mut libc::c_void,
                             param_value_size_ret: *mut libc::size_t) -> cl_int;

    /* Memory Object APIs */
    pub fn clCreateBuffer(context: cl_context,
                      flags: cl_mem_flags,
                      size: libc::size_t,
                      host_ptr: *mut libc::c_void,
                      errcode_ret: *mut cl_int) -> cl_mem;
    pub fn clCreateSubBuffer(buffer: cl_mem,
                        flags: cl_mem_flags,
                        buffer_create_type: cl_buffer_create_type,
                        buffer_create_info: *mut libc::c_void,
                        errcode_ret: *mut cl_int) -> cl_mem;
    pub fn clCreateImage2D(context: cl_context,
                       flags: cl_mem_flags,
                       image_format: *mut cl_image_format,
                       image_width: libc::size_t,
                       image_height: libc::size_t,
                       image_row_pitch: libc::size_t,
                       host_ptr: *mut libc::c_void,
                       errcode_ret: *mut cl_int) -> cl_mem;
    pub fn clCreateImage3D(context: cl_context,
                       flags: cl_mem_flags,
                       image_format: *mut cl_image_format,
                       image_width: libc::size_t,
                       image_height: libc::size_t,
                       image_depth: libc::size_t,
                       image_row_pitch: libc::size_t,
                       image_depth: libc::size_t,
                       image_row_pitch: libc::size_t,
                       image_slice_pitch: libc::size_t,
                       host_ptr: *mut libc::c_void,
                       errcode_ret: *mut cl_int) -> cl_mem;
    pub fn clRetainMemObject(memobj: cl_mem) -> cl_int;
    pub fn clReleaseMemObject(memobj: cl_mem) -> cl_int;
    pub fn clGetSupportedImageFormats(context: cl_context,
                                  flags: cl_mem_flags,
                                  image_type: cl_mem_object_type,
                                  num_entries: cl_uint,
                                  image_formats: *mut cl_image_format,
                                  num_image_formats: *mut cl_uint) -> cl_int;
    pub fn clGetMemObjectInfo(memobj: cl_mem,
                          param_name: cl_mem_info,
                          param_value_size: libc::size_t,
                          param_value: *mut libc::c_void,
                          param_value_size_ret: *mut libc::size_t) -> cl_int;
    pub fn clGetImageInfo(image: cl_mem,
                      param_name: cl_image_info,
                      param_value_size: libc::size_t,
                      param_value: *mut libc::c_void,
                      param_value_size_ret: *mut libc::size_t) -> cl_int;
    pub fn clSetMemObjectDestructorCallback(memobj: cl_mem,
                                        pfn_notify: extern fn (cl_mem, *mut libc::c_void),
                                        user_data: *mut libc::c_void) -> cl_int;

    /*mut * Sampler APIs */
    pub fn clCreateSampler(context: cl_context,
                       normalize_coords: cl_bool,
                       addressing_mode: cl_addressing_mode,
                       filter_mode: cl_filter_mode,
                       errcode_ret: *mut cl_int) -> cl_sampler;
    pub fn clRetainSampler(sampler: cl_sampler) -> cl_int;
    pub fn clReleaseSampler(sampler: cl_sampler) ->cl_int;
    pub fn clGetSamplerInfo(sampler: cl_sampler,
                        param_name: cl_sampler_info,
                        param_value_size: libc::size_t,
                        param_value: *mut libc::c_void,
                        param_value_size_ret: *mut libc::size_t) -> cl_int;

    /* Program Object APIs */
    pub fn clCreateProgramWithSource(context: cl_context,
                                 count: cl_uint,
                                 strings: *const *const libc::c_char,
                                 lengths: *const libc::size_t,
                                 errcode_ret: *mut cl_int) -> cl_program;
    pub fn clCreateProgramWithBinary(context: cl_context,
                                 num_devices: cl_uint,
                                 device_list: *const cl_device_id,
                                 lengths: *const libc::size_t,
                                 binaries: *const *const libc::c_uchar,
                                 binary_status: *mut cl_int,
                                 errcode_ret: *mut cl_int) -> cl_program;
    pub fn clRetainProgram(program: cl_program) -> cl_int;
    pub fn clReleaseProgram(program: cl_program) -> cl_int;
    pub fn clBuildProgram(program: cl_program,
                      num_devices: cl_uint,
                      device_list: *const cl_device_id,
                      options: *const libc::c_char,
                      pfn_notify: extern fn (cl_program, *mut libc::c_void),
                      user_data: *mut libc::c_void) -> cl_int;
    pub fn clUnloadCompiler() -> cl_int;
    pub fn clGetProgramInfo(program: cl_program,
                        param_name: cl_program_info,
                        param_value_size: libc::size_t,
                        param_value: *mut libc::c_void,
                        param_value_size_ret: *mut libc::size_t) -> cl_int;
    pub fn clGetProgramBuildInfo(program: cl_program,
                             device: cl_device_id,
                             param_name: cl_program_info,
                             param_value_size: libc::size_t,
                             param_value: *mut libc::c_void,
                             param_value_size_ret: *mut libc::size_t) -> cl_int;

    /* Kernel Object APIs */
    pub fn clCreateKernel(program: cl_program,
                      kernel_name: *const libc::c_char,
                      errcode_ret: *mut cl_int) -> cl_kernel;
    pub fn clCreateKernelsInProgram(program: cl_program,
                                num_kernels: cl_uint,
                                kernels: *mut cl_kernel,
                                num_kernels_ret: *mut cl_uint) -> cl_int;
    pub fn clRetainKernel(kernel: cl_kernel) -> cl_int;
    pub fn clReleaseKernel(kernel: cl_kernel) -> cl_int;
    pub fn clSetKernelArg(kernel: cl_kernel,
                      arg_index: cl_uint,
                      arg_size: libc::size_t,
                      arg_value: *const libc::c_void) -> cl_int;
    pub fn clGetKernelInfo(kernel: cl_kernel,
                       param_name: cl_kernel_info,
                       param_value_size: libc::size_t,
                       param_value: *mut libc::c_void,
                       param_value_size_ret: *mut libc::size_t) -> cl_int;
    pub fn clGetKernelWorkGroupInfo(kernel: cl_kernel,
                                device: cl_device_id,
                                param_name: cl_kernel_work_group_info,
                                param_value_size: libc::size_t,
                                param_value: *mut libc::c_void,
                                param_value_size_ret: *mut libc::size_t) -> cl_int;

    /* Event Object APIs */
    pub fn clWaitForEvents(num_events: cl_uint,
                       event_list: *const cl_event) -> cl_int;
    pub fn clGetEventInfo(event: cl_event,
                      param_name: cl_event_info,
                      param_value_size: libc::size_t,
                      param_value: *mut libc::c_void,
                      param_value_size_ret: *mut libc::size_t) -> cl_int;
    pub fn clCreateUserEvent(context: cl_context,
                         errcode_ret: *mut cl_int) -> cl_event;
    pub fn clRetainEvent(event: cl_event) -> cl_int;
    pub fn clReleaseEvent(event: cl_event) -> cl_int;
    pub fn clSetUserEventStatus(event: cl_event,
                            execution_status: cl_int) -> cl_int;
    pub fn clSetEventCallback(event: cl_event,
                          command_exec_callback_type: cl_int,
                          pfn_notify: extern fn (cl_event, cl_int, *mut libc::c_void),
                          user_data: *mut libc::c_void) -> cl_int;

    /* Profiling APIs */
    pub fn clGetEventProfilingInfo(event: cl_event,
                               param_name: cl_profiling_info,
                               param_value_size: libc::size_t,
                               param_value: *mut libc::c_void,
                               param_value_size_ret: *mut libc::size_t) -> cl_int;

    /* Flush and Finish APIs */
    pub fn clFlush(command_queue: cl_command_queue) -> cl_int;
    pub fn clFinish(command_queue: cl_command_queue) -> cl_int;

    /* Enqueued Commands APIs */
    pub fn clEnqueueReadBuffer(command_queue: cl_command_queue,
                           buffer: cl_mem,
                           blocking_read: cl_bool,
                           offset: libc::size_t,
                           cb: libc::size_t,
                           ptr: *mut libc::c_void,
                           num_events_in_wait_list: cl_uint,
                           event_wait_list: *const cl_event,
                           event: *mut cl_event) -> cl_int;
    pub fn clEnqueueReadBufferRect(command_queue: cl_command_queue,
                               buffer: cl_mem,
                               blocking_read: cl_bool,
                               buffer_origin: *mut libc::size_t,
                               host_origin: *mut libc::size_t,
                               region: *mut libc::size_t,
                               buffer_row_pitch: libc::size_t,
                               buffer_slice_pitch: libc::size_t,
                               host_row_pitch: libc::size_t,
                               host_slice_pitch: libc::size_t,
                               ptr: *mut libc::c_void,
                               num_events_in_wait_list: cl_uint,
                               event_wait_list: *const cl_event,
                               event: *mut cl_event) -> cl_int;
    pub fn clEnqueueWriteBuffer(command_queue: cl_command_queue,
                            buffer: cl_mem,
                            blocking_write: cl_bool,
                            offset: libc::size_t,
                            cb: libc::size_t,
                            ptr: *const libc::c_void,
                            num_events_in_wait_list: cl_uint,
                            event_wait_list: *const cl_event,
                            event: *mut cl_event) -> cl_int;
    pub fn clEnqueueWriteBufferRect(command_queue: cl_command_queue,
                                blocking_write: cl_bool,
                                buffer_origin: *mut libc::size_t,
                                host_origin: *mut libc::size_t,
                                region: *mut libc::size_t,
                                buffer_row_pitch: libc::size_t,
                                buffer_slice_pitch: libc::size_t,
                                host_row_pitch: libc::size_t,
                                host_slice_pitch: libc::size_t,
                                ptr: *mut libc::c_void,
                                num_events_in_wait_list: cl_uint,
                                event_wait_list: *const cl_event,
                                event: *mut cl_event) -> cl_int;
    pub fn clEnqueueCopyBuffer(command_queue: cl_command_queue,
                           src_buffer: cl_mem,
                           dst_buffer: cl_mem,
                           src_offset: libc::size_t,
                           dst_offset: libc::size_t,
                           cb: libc::size_t,
                           num_events_in_wait_list: cl_uint,
                           event_wait_list: *const cl_event,
                           event: *mut cl_event) -> cl_int;
    pub fn clEnqueueCopyBufferRect(command_queue: cl_command_queue,
                               src_buffer: cl_mem,
                               dst_buffer: cl_mem,
                               src_origin: *mut libc::size_t,
                               dst_origin: *mut libc::size_t,
                               region: *mut libc::size_t,
                               src_row_pitch: libc::size_t,
                               src_slice_pitch: libc::size_t,
                               dst_row_pitch: libc::size_t,
                               dst_slice_pitch: libc::size_t,
                               num_events_in_wait_list: cl_uint,
                               event_wait_list: *const cl_event,
                               event: *mut cl_event) -> cl_int;
    pub fn clEnqueueReadImage(command_queue: cl_command_queue,
                          image: cl_mem,
                          blocking_read: cl_bool,
                          origin: *mut libc::size_t,
                          region: *mut libc::size_t,
                          row_pitch: libc::size_t,
                          slice_pitch: libc::size_t,
                          ptr: *mut libc::c_void,
                          num_events_in_wait_list: cl_uint,
                          event_wait_list: *const cl_event,
                          event: *mut cl_event) -> cl_int;
    pub fn clEnqueueWriteImage(command_queue: cl_command_queue,
                           image: cl_mem,
                           blocking_write: cl_bool,
                           origin: *mut libc::size_t,
                           region: *mut libc::size_t,
                           input_row_pitch: libc::size_t,
                           input_slice_pitch: libc::size_t,
                           ptr: *mut libc::c_void,
                           num_events_in_wait_list: cl_uint,
                           event_wait_list: *const cl_event,
                           event: *mut cl_event) -> cl_int;
    pub fn clEnqueueCopyImage(command_queue: cl_command_queue,
                          src_image: cl_mem,
                          dst_image: cl_mem,
                          src_origin: *mut libc::size_t,
                          dst_origin: *mut libc::size_t,
                          region: *mut libc::size_t,
                          num_events_in_wait_list: cl_uint,
                          event_wait_list: *const cl_event,
                          event: *mut cl_event) -> cl_int;
    pub fn clEnqueueCopyImageToBuffer(command_queue: cl_command_queue,
                                  src_image: cl_mem,
                                  dst_buffer: cl_mem,
                                  src_origin: *mut libc::size_t,
                                  region: *mut libc::size_t,
                                  dst_offset: libc::size_t,
                                  num_events_in_wait_list: cl_uint,
                                  event_wait_list: *const cl_event,
                                  event: *mut cl_event) -> cl_int;
    pub fn clEnqueueCopyBufferToImage(command_queue: cl_command_queue,
                                  src_buffer: cl_mem,
                                  dst_image: cl_mem,
                                  src_offset: libc::size_t,
                                  dst_origin: *mut libc::size_t,
                                  region: *mut libc::size_t,
                                  num_events_in_wait_list: cl_uint,
                                  event_wait_list: *const cl_event,
                                  event: *mut cl_event) -> cl_int;
    pub fn clEnqueueMapBuffer(command_queue: cl_command_queue,
                          buffer: cl_mem,
                          blocking_map: cl_bool,
                          map_flags: cl_map_flags,
                          offset: libc::size_t,
                          cb: libc::size_t,
                          num_events_in_wait_list: cl_uint,
                          event_wait_list: *const cl_event,
                          event: *mut cl_event,
                          errorcode_ret: *mut cl_int);
    pub fn clEnqueueMapImage(command_queue: cl_command_queue,
                         image: cl_mem,
                         blocking_map: cl_bool,
                         map_flags: cl_map_flags,
                         origin: *mut libc::size_t,
                         region: *mut libc::size_t,
                         image_row_pitch: libc::size_t,
                         image_slice_pitch: libc::size_t,
                         num_events_in_wait_list: cl_uint,
                         event_wait_list: *const cl_event,
                         event: *mut cl_event,
                         errorcode_ret: *mut cl_int);
    pub fn clEnqueueUnmapMemObject(command_queue: cl_command_queue,
                               memobj: cl_mem,
                               mapped_ptr: *mut libc::c_void,
                               num_events_in_wait_list: cl_uint,
                               event_wait_list: *const cl_event,
                               event: *mut cl_event) -> cl_int;
    pub fn clEnqueueNDRangeKernel(command_queue: cl_command_queue,
                              kernel: cl_kernel,
                              work_dim: cl_uint,
                              global_work_offset: *const libc::size_t,
                              global_work_size: *const libc::size_t,
                              local_work_size: *const libc::size_t,
                              num_events_in_wait_list: cl_uint,
                              event_wait_list: *const cl_event,
                              event: *mut cl_event) -> cl_int;
    pub fn clEnqueueTask(command_queue: cl_command_queue,
                     kernel: cl_kernel,
                     num_events_in_wait_list: cl_uint,
                     event_wait_list: *const cl_event,
                     event: *mut cl_event) -> cl_int;
    pub fn clEnqueueNativeKernel(command_queue: cl_command_queue,
                             user_func: extern fn (*mut libc::c_void),
                             args: *mut libc::c_void,
                             cb_args: libc::size_t,
                             num_mem_objects: cl_uint,
                             mem_list: *const cl_mem,
                             args_mem_loc: *const *const libc::c_void,
                             num_events_in_wait_list: cl_uint,
                             event_wait_list: *const cl_event,
                             event: *mut cl_event) -> cl_int;
    pub fn clEnqueueMarker(command_queue: cl_command_queue,
                       event: *mut cl_event) -> cl_int;
    pub fn clEnqueueWaitForEvents(command_queue: cl_command_queue,
                              num_events: cl_uint,
                              event_list: *mut cl_event) -> cl_int;
    pub fn clEnqueueBarrier(command_queue: cl_command_queue) -> cl_int;

    /* Extension function access
     *
     * Returns the extension function address for the given function name,
     * or NULL if a valid function can not be found. The client must
     * check to make sure the address is not NULL, before using or
     * or calling the returned function address.
     */
    pub fn clGetExtensionFunctionAddress(func_name: *const libc::c_char) -> *mut libc::c_void;
  }
}


================================================
FILE: src/error.rs
================================================
//! Error handling utilities.

use cl::{CLStatus, cl_int};
use cl::CLStatus::CL_SUCCESS;

fn error_str(status_code: cl_int) -> String {
    match status_code {
    0 => CLStatus::CL_SUCCESS.to_string(),
    -1 => CLStatus::CL_DEVICE_NOT_FOUND.to_string(),
    -2 => CLStatus::CL_DEVICE_NOT_AVAILABLE.to_string(),
    -3 => CLStatus::CL_COMPILER_NOT_AVAILABLE.to_string(),
    -4 => CLStatus::CL_MEM_OBJECT_ALLOCATION_FAILURE.to_string(),
    -5 => CLStatus::CL_OUT_OF_RESOURCES.to_string(),
    -6 => CLStatus::CL_OUT_OF_HOST_MEMORY.to_string(),
    -7 => CLStatus::CL_PROFILING_INFO_NOT_AVAILABLE.to_string(),
    -8 => CLStatus::CL_MEM_COPY_OVERLAP.to_string(),
    -9 => CLStatus::CL_IMAGE_FORMAT_MISMATCH.to_string(),
    -10 => CLStatus::CL_IMAGE_FORMAT_NOT_SUPPORTED.to_string(),
    -11 => CLStatus::CL_BUILD_PROGRAM_FAILURE.to_string(),
    -12 => CLStatus::CL_MAP_FAILURE.to_string(),
    -13 => CLStatus::CL_MISALIGNED_SUB_BUFFER_OFFSET.to_string(),
    -14 => CLStatus::CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST.to_string(),
    -30 => CLStatus::CL_INVALID_VALUE.to_string(),
    -31 => CLStatus::CL_INVALID_DEVICE_TYPE.to_string(),
    -32 => CLStatus::CL_INVALID_PLATFORM.to_string(),
    -33 => CLStatus::CL_INVALID_DEVICE.to_string(),
    -34 => CLStatus::CL_INVALID_CONTEXT.to_string(),
    -35 => CLStatus::CL_INVALID_QUEUE_PROPERTIES.to_string(),
    -36 => CLStatus::CL_INVALID_COMMAND_QUEUE.to_string(),
    -37 => CLStatus::CL_INVALID_HOST_PTR.to_string(),
    -38 => CLStatus::CL_INVALID_MEM_OBJECT.to_string(),
    -39 => CLStatus::CL_INVALID_IMAGE_FORMAT_DESCRIPTOR.to_string(),
    -40 => CLStatus::CL_INVALID_IMAGE_SIZE.to_string(),
    -41 => CLStatus::CL_INVALID_SAMPLER.to_string(),
    -42 => CLStatus::CL_INVALID_BINARY.to_string(),
    -43 => CLStatus::CL_INVALID_BUILD_OPTIONS.to_string(),
    -44 => CLStatus::CL_INVALID_PROGRAM.to_string(),
    -45 => CLStatus::CL_INVALID_PROGRAM_EXECUTABLE.to_string(),
    -46 => CLStatus::CL_INVALID_KERNEL_NAME.to_string(),
    -47 => CLStatus::CL_INVALID_KERNEL_DEFINITION.to_string(),
    -48 => CLStatus::CL_INVALID_KERNEL.to_string(),
    -49 => CLStatus::CL_INVALID_ARG_INDEX.to_string(),
    -50 => CLStatus::CL_INVALID_ARG_VALUE.to_string(),
    -51 => CLStatus::CL_INVALID_ARG_SIZE.to_string(),
    -52 => CLStatus::CL_INVALID_KERNEL_ARGS.to_string(),
    -53 => CLStatus::CL_INVALID_WORK_DIMENSION.to_string(),
    -54 => CLStatus::CL_INVALID_WORK_GROUP_SIZE.to_string(),
    -55 => CLStatus::CL_INVALID_WORK_ITEM_SIZE.to_string(),
    -56 => CLStatus::CL_INVALID_GLOBAL_OFFSET.to_string(),
    -57 => CLStatus::CL_INVALID_EVENT_WAIT_LIST.to_string(),
    -58 => CLStatus::CL_INVALID_EVENT.to_string(),
    -59 => CLStatus::CL_INVALID_OPERATION.to_string(),
    -60 => CLStatus::CL_INVALID_GL_OBJECT.to_string(),
    -61 => CLStatus::CL_INVALID_BUFFER_SIZE.to_string(),
    -62 => CLStatus::CL_INVALID_MIP_LEVEL.to_string(),
    -63 => CLStatus::CL_INVALID_GLOBAL_WORK_SIZE.to_string(),
    -64 => CLStatus::CL_INVALID_PROPERTY.to_string(),
    -1001 => CLStatus::CL_PLATFORM_NOT_FOUND_KHR.to_string(),
        _ => format!("Unknown Error: {}", status_code)
    }
}

pub fn check(status: cl_int, message: &str) {
    if status != CL_SUCCESS as cl_int {
        panic!("{} ({})", message, error_str(status))
    }
}


================================================
FILE: src/ext.rs
================================================
#![allow(unused,
         unused_attributes,
         non_camel_case_types,
         non_snake_case)]

/// All of the extensions defined for OpenCL 1.1, from
/// [`cl_ext.h`](https://www.khronos.org/registry/cl/api/1.1/cl_ext.h).

// Macro to define a struct-style extension pointer loader.
// Defines a (`Copy`, `Sync`) `struct Functions` that has extension function pointers as members (and methods,
// for convenience).
// Call `$ext::load()` to get an Option<$ext::Functions, String>.  (It's safe to call extension function pointers in other threads, right?)
macro_rules! cl_extension_loader {
    (
        $ext_name:expr;
        $(extern fn $function:ident ($($arg:ident : $arg_type:ty),*) -> $ret:ty),*
    ) => (
        // Define struct Functions
        ext_struct_def!{ $($function, ($($arg, $arg_type),*) $ret)* }
        impl Functions {
            // Make function pointers available as methods so they don't have to be called as (struct.member)(arg)
            $( #[inline(always)] unsafe fn $function (&self, $($arg:$arg_type),*) -> $ret { (self.$function)($($arg),*) } )*
        }

        pub fn load(platform: cl_platform_id) -> Result<Functions, String> {
            use hl;
            use std::mem;
            use std::ptr;
            use std::ffi::CString;
            use cl::ll::clGetExtensionFunctionAddress;

            // Read in the available extensions
            // We have to do this, since loading function pointers for an
            // unavailable extension can return non-NULL.
            // TODO read in extensions lazily and store them in a global HashSet?
            let available = unsafe {
                let hl_platform = hl::Platform::from_platform_id(platform);
                let available = hl_platform.extensions().contains($ext_name);
                mem::forget(hl_platform);
                available
            };
            if !available {
                let platform_name;
                unsafe {
                    let hl_platform = hl::Platform::from_platform_id(platform);
                    platform_name = hl_platform.name();
                    mem::forget(hl_platform);
                }
                return Err(format!("extension {} unavailable for platform {}", $ext_name, platform_name));
            }
            // Return a struct with all functions loaded
            Ok(ext_struct_literal!($ext_name, platform, $($function),*))
        }
    )
}
// We only need these helper macros so we can special-case for unit structs
// (Since writing `struct name {}` is a failing error for some reason)
// Whatever functions we're calling aren't necessarily thread-safe, but since this is a low-level
// interface we'll let the callers worry about that
macro_rules! ext_struct_def {
    () => (#[derive(Copy, Clone)] pub struct Functions;);
    ($($function:ident, ($($arg:ident, $arg_type:ty),+) $ret:ty)+) =>
    (
        #[derive(Copy, Clone)]
        pub struct Functions {
            $(pub $function: (extern fn ($($arg : $arg_type),+) -> $ret)),+
        }
    );
}
// (So is writing `name {}` as a literal)
macro_rules! ext_struct_literal {
    ($ext_name:expr, $plat:ident,) => (Functions);
    ($ext_name:expr, $plat:ident, $($function:ident),+) =>
    (
        Functions {
            $($function: {
                let mut fn_name
                        = CString::new(stringify!($function)).unwrap();
                // TODO use clGetExtensionFunctionAddressForPlatform() when it's available; more
                // reliable.
                let fn_ptr = unsafe { clGetExtensionFunctionAddress(fn_name.as_ptr()) };
                if fn_ptr == ptr::null_mut() {
                    let platform_name;

                    unsafe {
                        let hl_platform = hl::Platform::from_platform_id($plat);
                        platform_name = hl_platform.name();
                        mem::forget(hl_platform);
                    }

                    return Err(format!("extension {} apparently available for platform with id {}, but couldn't load function {}",
                                       $ext_name,
                                       platform_name,
                                       stringify!($function)));
                }
                unsafe {
                    // Cast from *mut libc::void to the function pointer type we want
                    mem::transmute(fn_ptr)
                }
            }),+
        }
    );
}

pub mod cl_khr_fp64 {
    use cl::*;
    static CL_DEVICE_DOUBLE_FP_CONFIG: cl_uint = 0x1032;
    cl_extension_loader! {
        "cl_khr_fp64";
    }
}

pub mod cl_khr_fp16 {
    use cl::*;
    pub static CL_DEVICE_HALF_FP_CONFIG: cl_uint = 0x1033;
    cl_extension_loader! {
        "cl_khr_pf16";
    }
}

pub mod cl_APPLE_SetMemObjectDestructor {
    use libc;
    use cl::*;
    cl_extension_loader! {
        "cl_APPLE_SetMemObjectDestructor";
        extern fn clSetMemObjectDestructorAPPLE(memobj: cl_mem,
                                                pfn_notify: (extern fn(memobj: cl_mem,
                                                                       user_data: *mut libc::c_void)),
                                                user_data: *mut libc::c_void) -> () // Note: returning () is necessary to satisfy macros
    }
}

pub mod cl_APPLE_ContextLoggingFunctions {
    use libc;
    use cl::*;
    cl_extension_loader! {
        "cl_APPLE_ContextLoggingFunctions";
        extern fn clLogMessagesToSystemLogAPPLE(errstr: *const libc::c_char,
                                                private_info: *const libc::c_void,
                                                cb: libc::size_t,
                                                user_data: *mut libc::c_void) -> (),
        extern fn clLogMessagesToStdoutAPPLE(errstr: *const libc::c_char,
                                             private_info: *const libc::c_void,
                                             cb: libc::size_t,
                                             user_data: *mut libc::c_void) -> (),
        extern fn clLogMessagesToStderrAPPLE(errstr: *const libc::c_char,
                                             private_info: *const libc::c_void,
                                             cb: libc::size_t,
                                             user_data: *mut libc::c_void) -> ()
    }
}

pub mod cl_khr_icd {
    use libc;
    use cl::*;
    pub static CL_PLATFORM_ICD_SUFFIX:      cl_uint = 0x0920;
    // Note: this is an error code, but we can't extend CLStatus with it... hmm.
    pub static CL_PLATFORM_NOT_FOUND_KHR:   cl_int  = -1001;
    cl_extension_loader! {
        "cl_khr_icd";
        extern fn clIcdGetPlatformIDsKHR(num_entries: cl_uint,
                                         platform: *mut cl_platform_id,
                                         num_platforms: *mut cl_uint) -> cl_int
    }
}

pub mod cl_nv_device_attribute_query {
    use cl::*;
    pub static CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV:   cl_uint = 0x4000;
    pub static CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV:   cl_uint = 0x4001;
    pub static CL_DEVICE_REGISTERS_PER_BLOCK_NV:        cl_uint = 0x4002;
    pub static CL_DEVICE_WARP_SIZE_NV:                  cl_uint = 0x4003;
    pub static CL_DEVICE_GPU_OVERLAP_NV:                cl_uint = 0x4004;
    pub static CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV:        cl_uint = 0x4005;
    pub static CL_DEVICE_INTEGRATED_MEMORY_NV:          cl_uint = 0x4006;
    cl_extension_loader! {
        "cl_nv_device_attribute_query";
    }
}

pub mod cl_amd_device_attribute_query {
    use cl::*;
    pub static CL_DEVICE_PROFILING_TIMER_OFFSET_AMD:    cl_uint = 0x4036;
    cl_extension_loader! {
        "cl_amd_device_attribute_query";
    }
}

pub mod cl_arm_printf {
    use cl::*;
    pub static CL_PRINTF_CALLBACK_ARM:      cl_uint = 0x40B0;
    pub static CL_PRINTF_BUFFERSIZE_ARM:    cl_uint = 0x40B1;
    cl_extension_loader! {
        "cl_arm_printf";
    }
}

pub mod cl_ext_device_fission {
    use cl::*;
    pub type cl_device_partition_property_ext = cl_ulong;
    pub static CL_DEVICE_PARTITION_EQUALLY_EXT: cl_device_partition_property_ext            = 0x4050;
    pub static CL_DEVICE_PARTITION_BY_COUNTS_EXT: cl_device_partition_property_ext          = 0x4051;
    pub static CL_DEVICE_PARTITION_BY_NAMES_EXT: cl_device_partition_property_ext           = 0x4052;
    pub static CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN_EXT: cl_device_partition_property_ext = 0x4053;
    pub static CL_DEVICE_PARENT_DEVICE_EXT: cl_device_info                                  = 0x4054;
    pub static CL_DEVICE_PARTITION_TYPES_EXT: cl_device_info                                = 0x4055;
    pub static CL_DEVICE_AFFINITY_DOMAINS_EXT: cl_device_info                               = 0x4056;
    pub static CL_DEVICE_REFERENCE_COUNT_EXT: cl_device_info                                = 0x4057;
    pub static CL_DEVICE_PARTITION_STYLE_EXT: cl_device_info                                = 0x4058;
    pub static CL_DEVICE_PARTITION_FAILED_EXT: cl_int                                       = -1057;
    pub static CL_INVALID_PARTITION_COUNT_EXT: cl_int                                       = -1058;
    pub static CL_INVALID_PARTITION_NAME_EXT: cl_int                                        = -1059;
    pub static CL_AFFINITY_DOMAIN_L1_CACHE_EXT: cl_uint                                     = 0x1;
    pub static CL_AFFINITY_DOMAIN_L2_CACHE_EXT: cl_uint                                     = 0x2;
    pub static CL_AFFINITY_DOMAIN_L3_CACHE_EXT: cl_uint                                     = 0x3;
    pub static CL_AFFINITY_DOMAIN_L4_CACHE_EXT: cl_uint                                     = 0x4;
    pub static CL_AFFINITY_DOMAIN_NUMA_EXT: cl_uint                                         = 0x10;
    pub static CL_AFFINITY_DOMAIN_NEXT_FISSIONABLE_EXT: cl_uint                             = 0x100;
    pub static CL_PROPERTIES_LIST_END_EXT: cl_device_partition_property_ext                 = 0;
    pub static CL_PARTITION_BY_COUNTS_LIST_END_EXT: cl_device_partition_property_ext        = 0;
    pub static CL_PARTITION_BY_NAMES_LIST_END_EXT: cl_device_partition_property_ext         = std::u64::MAX;
    cl_extension_loader! {
        "cl_ext_device_fission";
        extern fn clReleaseDeviceEXT(device: cl_device_id) -> cl_int,
        extern fn clRetainDeviceEXT(device: cl_device_id) -> cl_int,
        extern fn clCreateSubDevicesExt(in_device: cl_device_id,
                                        properties: *const cl_device_partition_property_ext,
                                        num_entries: cl_uint,
                                        out_devices: *mut cl_device_id,
                                        num_devices: *mut cl_uint) -> cl_int
    }
}

pub mod cl_qcom_ext_host_ptr {
    use libc;
    use cl::*;
    pub type cl_image_pitch_info_qcom = cl_uint;
    pub struct cl_mem_ext_host_ptr {
        pub allocation_type: cl_uint,
        pub host_cache_policy: cl_uint
    }
    pub static CL_MEM_EXT_HOST_PTR_QCOM:                cl_uint = (1 << 29);
    pub static CL_DEVICE_EXT_MEM_PADDING_IN_BYTES_QCOM: cl_uint = 0x40A0;
    pub static CL_DEVICE_PAGE_SIZE_QCOM:                cl_uint = 0x40A1;
    pub static CL_IMAGE_ROW_ALIGNMENT_QCOM:             cl_uint = 0x40A2;
    pub static CL_IMAGE_SLICE_ALIGNMENT_QCOM:           cl_uint = 0x40A3;
    pub static CL_MEM_HOST_UNCACHED_QCOM:               cl_uint = 0x40A4;
    pub static CL_MEM_HOST_WRITEBACK_QCOM:              cl_uint = 0x40A5;
    pub static CL_MEM_HOST_WRITETHROUGH_QCOM:           cl_uint = 0x40A6;
    pub static CL_MEM_HOST_WRITE_COMBINING_QCOM:        cl_uint = 0x40A7;
    cl_extension_loader! {
        "cl_qcom_ext_host_ptr";
        extern fn clGetDeviceImageInfoQCOM(device: cl_device_id,
                                           image_width: libc::size_t,
                                           image_height: libc::size_t,
                                           image_format: *const cl_image_format,
                                           param_name: cl_image_pitch_info_qcom,
                                           param_value_size: libc::size_t,
                                           param_value: *mut libc::c_void,
                                           param_value_size_ret: *mut libc::size_t) -> ()
    }
}

// This extension depends on the previous one. Should we try to express that?
pub mod cl_qcom_ion_host_ptr {
    use libc;
    use cl::*;
    use super::cl_qcom_ext_host_ptr;
    struct cl_mem_ion_host_ptr {
        pub ext_host_ptr: cl_qcom_ext_host_ptr::cl_mem_ext_host_ptr,
        pub ion_filedesc: libc::c_int,
        pub ion_hostptr: *mut libc::c_void
    }
    pub static CL_MEM_ION_HOST_PTR_QCOM: cl_uint = 0x40A8;

    cl_extension_loader! {
        "cl_qcom_ion_host_ptr";
    }
}


================================================
FILE: src/hl.rs
================================================
//! A higher level API.

use libc;
use std::ffi::CString;
use std::iter::repeat;
use std::marker::PhantomData;
use std::mem;
use std::ptr;
use std::string::String;
use std::vec::Vec;

use cl;
use cl::*;
use cl::ll::*;
use cl::CLStatus::CL_SUCCESS;
use error::check;
use mem::{Put, Get, Write, Read, Buffer, CLBuffer};

#[derive(Copy, Clone)]
pub enum DeviceType {
      CPU, GPU
}

fn convert_device_type(device: DeviceType) -> cl_device_type {
    match device {
        DeviceType::CPU => CL_DEVICE_TYPE_CPU,
        DeviceType::GPU => CL_DEVICE_TYPE_GPU | CL_DEVICE_TYPE_ACCELERATOR
    }
}

pub struct Platform {
    id: cl_platform_id
}

impl Platform {
    fn get_devices_internal(&self, dtype: cl_device_type) -> Vec<Device>
    {
        unsafe
        {
            let mut num_devices = 0;

            info!("Looking for devices matching {}", dtype);

            clGetDeviceIDs(self.id, dtype, 0, ptr::null_mut(),
                           (&mut num_devices));

            let mut ids: Vec<cl_device_id> = repeat(0 as cl_device_id)
                .take(num_devices as usize).collect();
            clGetDeviceIDs(self.id, dtype, ids.len() as cl_uint,
                           ids.as_mut_ptr(), (&mut num_devices));
            ids.iter().map(|id| { Device {id: *id }}).collect()
        }
    }

    pub fn get_devices(&self) -> Vec<Device>
    {
        self.get_devices_internal(CL_DEVICE_TYPE_ALL)
    }

    pub fn get_devices_by_types(&self, types: &[DeviceType]) -> Vec<Device>
    {
        let mut dtype = 0;
        for &t in types.iter() {
          dtype |= convert_device_type(t);
        }

        self.get_devices_internal(dtype)
    }

    fn profile_info(&self, name: cl_platform_info) -> String
    {
        unsafe {
            let mut size = 0 as libc::size_t;

            let status = clGetPlatformInfo(self.id,
                              name,
                              0,
                              ptr::null_mut(),
                              &mut size);
            check(status, "Could not determine platform info string length");

            let mut buf : Vec<u8>
                = repeat(0u8).take(size as usize).collect();

            let status = clGetPlatformInfo(self.id,
                              name,
                              size,
                              buf.as_mut_ptr() as *mut libc::c_void,
                              ptr::null_mut());
            check(status, "Could not get platform info string");

            String::from_utf8_unchecked(buf)
        }
    }

    pub fn get_id(&self) -> cl_platform_id {
        self.id
    }

    pub fn name(&self) -> String
    {
        self.profile_info(CL_PLATFORM_NAME)
    }

    pub fn version(&self) -> String
    {
        self.profile_info(CL_PLATFORM_VERSION)
    }

    pub fn profile(&self) -> String
    {
        self.profile_info(CL_PLATFORM_PROFILE)
    }

    pub fn vendor(&self) -> String
    {
        self.profile_info(CL_PLATFORM_VENDOR)
    }

    pub fn extensions(&self) -> String
    {
        self.profile_info(CL_PLATFORM_EXTENSIONS)
    }

    pub unsafe fn from_platform_id(id: cl_platform_id) -> Platform {
        Platform { id: id }
    }
}

// This mutex is used to work around weak OpenCL implementations.
// On some implementations concurrent calls to clGetPlatformIDs
// will cause the implantation to return invalid status.
static mut platforms_mutex: std::sync::StaticMutex = std::sync::MUTEX_INIT;

pub fn get_platforms() -> Vec<Platform>
{
    let mut num_platforms = 0 as cl_uint;

    unsafe
    {
        let guard = platforms_mutex.lock();
        let status = clGetPlatformIDs(0,
                                          ptr::null_mut(),
                                          (&mut num_platforms));
        // unlock this before the check in case the check fails
        check(status, "could not get platform count.");

        let mut ids: Vec<cl_device_id> = repeat(0 as cl_device_id)
            .take(num_platforms as usize).collect();

        let status = clGetPlatformIDs(num_platforms,
                                      ids.as_mut_ptr(),
                                      (&mut num_platforms));
        check(status, "could not get platforms.");

        let _ = guard;

        ids.iter().map(|id| { Platform { id: *id } }).collect()
    }
}

pub fn create_context_with_properties(dev: &[Device], prop: &[cl_context_properties]) -> Context
{
    unsafe
    {
        // TODO: Support for multiple devices
        let mut errcode = 0;
        let dev: Vec<cl_device_id> = dev.iter().map(|dev| dev.id).collect();

        // TODO: Proper error messages
        let ctx = clCreateContext(&prop[0],
                                  dev.len() as u32,
                                  &dev[0],
                                  mem::transmute(ptr::null::<fn()>()),
                                  ptr::null_mut(),
                                  &mut errcode);

        check(errcode, "Failed to create opencl context!");

        Context { ctx: ctx }
    }
}

#[derive(Copy, Clone)]
pub struct Device {
    id: cl_device_id
}

unsafe impl Sync for Device {}
unsafe impl Send for Device {}

impl Device {
    fn profile_info(&self, name: cl_device_info) -> String
    {
        unsafe {
            let mut size = 0 as libc::size_t;

            let status = clGetDeviceInfo(
                self.id,
                name,
                0,
                ptr::null_mut(),
                &mut size);
            check(status, "Could not determine device info string length");

            let mut buf : Vec<u8>
                = repeat(0u8).take(size as usize).collect();

            let status = clGetDeviceInfo(self.id,
                                         name,
                                         size,
                                         buf.as_mut_ptr() as *mut libc::c_void,
                                         ptr::null_mut());
            check(status, "Could not get device info string");

            String::from_utf8_unchecked(buf)
        }
    }

    pub fn name(&self) -> String
    {
        self.profile_info(CL_DEVICE_NAME)
    }
    pub fn vendor(&self) -> String
    {
        self.profile_info(CL_DEVICE_VENDOR)
    }
    pub fn profile(&self) -> String
    {
        self.profile_info(CL_DEVICE_PROFILE)
    }
    pub fn device_type(&self) -> String
    {
        self.profile_info(CL_DEVICE_TYPE)
    }

    pub fn compute_units(&self) -> usize {
		unsafe {
			let mut ct: usize = 0;
            let status = clGetDeviceInfo(
                self.id,
                CL_DEVICE_MAX_COMPUTE_UNITS,
                8,
                (&mut ct as *mut usize) as *mut libc::c_void,
                ptr::null_mut());
            check(status, "Could not get number of device compute units.");
			return ct;
		}
	}


    pub fn create_context(&self) -> Context
    {
        unsafe
        {
            // TODO: Support for multiple devices
            let mut errcode = 0;

            // TODO: Proper error messages
            let ctx = clCreateContext(ptr::null(),
                                      1,
                                      &self.id,
                                      mem::transmute(ptr::null::<fn()>()),
                                      ptr::null_mut(),
                                      (&mut errcode));

            check(errcode, "Failed to create opencl context!");

            Context { ctx: ctx }
        }
    }
}

pub struct Context {
    pub ctx: cl_context,
}

unsafe impl Sync for Context {}
unsafe impl Send for Context {}

impl Context {
    pub fn create_buffer<T>(&self, size: usize, flags: cl_mem_flags) -> CLBuffer<T>
    {
        unsafe {
            let mut status = 0;
            let buf = clCreateBuffer(self.ctx,
                                     flags,
                                     (size*mem::size_of::<T>()) as libc::size_t ,
                                     ptr::null_mut(),
                                     (&mut status));
            check(status, "Could not allocate buffer");
            CLBuffer {
                cl_buffer: buf,
                phantom: PhantomData,
            }
        }
    }


    pub fn create_buffer_from<T, U, IN: Put<T, U>>(&self, create: IN, flags: cl_mem_flags) -> U
    {
        create.put(|p, len| {
            let mut status = 0;
            let buf = unsafe {
                clCreateBuffer(self.ctx,
                               flags | CL_MEM_COPY_HOST_PTR,
                               len,
                               mem::transmute(p),
                               (&mut status))
            };
            check(status, "Could not allocate buffer");
            buf
        })
    }

    pub fn create_command_queue(&self, device: &Device) -> CommandQueue
    {
        unsafe
        {
            let mut errcode = 0;

            let cqueue = clCreateCommandQueue(self.ctx,
                                              device.id,
                                              CL_QUEUE_PROFILING_ENABLE,
                                              (&mut errcode));

            check(errcode, "Failed to create command queue!");

            CommandQueue {
                cqueue: cqueue
            }
        }
    }

    pub fn create_program_from_source(&self, src: &str) -> Program
    {
        unsafe
        {
            let src = CString::new(src).unwrap();

            let mut status = CL_SUCCESS as cl_int;
            let program = clCreateProgramWithSource(
                self.ctx,
                1,
                &src.as_ptr(),
                ptr::null(),
                (&mut status));
            check(status, "Could not create program");

            Program { prg: program }
        }
    }

    pub fn create_program_from_binary(&self, bin: &str, device: &Device) -> Program {
        let src = CString::new(bin).unwrap();
        let mut status = CL_SUCCESS as cl_int;
        let len = bin.len() as libc::size_t;
        let program = unsafe {
            clCreateProgramWithBinary(
                self.ctx,
                1,
                &device.id,
                (&len),
                (src.as_ptr() as *const *const i8) as *const *const libc::c_uchar,
                ptr::null_mut(),
                (&mut status))
        };
        check(status, "Could not create program");

        Program {prg: program}
    }
}

impl Drop for Context
{
    fn drop(&mut self) {
        unsafe {
            clReleaseContext(self.ctx);
        }
    }
}

impl<'r, T> KernelArg for &'r (Buffer<T> + 'r) {
    fn get_value(&self) -> (libc::size_t, *const libc::c_void)
    {
        unsafe {
            (mem::size_of::<cl_mem>() as libc::size_t,
             self.id_ptr() as *const libc::c_void)
        }
    }
}

impl<'r, T> KernelArg for Box<Buffer<T> + 'r> {
    fn get_value(&self) -> (libc::size_t, *const libc::c_void)
    {
        unsafe {
            (mem::size_of::<cl_mem>() as libc::size_t,
             self.id_ptr() as *const libc::c_void)
        }
    }
}


pub struct CommandQueue {
    pub cqueue: cl_command_queue
}

unsafe impl Sync for CommandQueue {}
unsafe impl Send for CommandQueue {}

impl CommandQueue
{
    //synchronous
    pub fn enqueue_kernel<I: KernelIndex, E: EventList>(&self, k: &Kernel, global: I, local: Option<I>, wait_on: E)
        -> Event
    {
        unsafe
        {
            wait_on.as_event_list(|event_list, event_list_length| {
                let mut e: cl_event = ptr::null_mut();
                let mut status = clEnqueueNDRangeKernel(
                    self.cqueue,
                    k.kernel,
                    KernelIndex::num_dimensions(None::<I>),
                    ptr::null(),
                    global.get_ptr(),
                    match local {
                        Some(ref l) => l.get_ptr() as *const libc::size_t,
                        None => ptr::null()
                    },
                    event_list_length,
                    event_list,
                    (&mut e));
                check(status, "Error enqueuing kernel.");
                status = clFinish(self.cqueue);
                check(status, "Error finishing kernel.");
                Event { event: e }
            })
        }
    }

    //asynchronous
    pub fn enqueue_async_kernel<I: KernelIndex, E: EventList>(&self, k: &Kernel, global: I, local: Option<I>, wait_on: E)
        -> Event
    {
        unsafe
        {
            wait_on.as_event_list(|event_list, event_list_length| {
                let mut e: cl_event = ptr::null_mut();
                let status = clEnqueueNDRangeKernel(
                    self.cqueue,
                    k.kernel,
                    KernelIndex::num_dimensions(None::<I>),
                    ptr::null(),
                    global.get_ptr(),
                    match local {
                        Some(ref l) => l.get_ptr() as *const libc::size_t,
                        None => ptr::null()
                    },
                    event_list_length,
                    event_list,
                    (&mut e));
                check(status, "Error enqueuing kernel.");
                Event { event: e }
            })
        }
    }

    pub fn get<T, U, B: Buffer<T>, G: Get<B, U>, E: EventList>(&self, buf: &B, event: E) -> G
    {
        event.as_event_list(|event_list, event_list_length| {
            Get::get(buf, |offset, ptr, len| {
                unsafe {
                    let err = clEnqueueReadBuffer(self.cqueue,
                                                  buf.id(),
                                                  CL_TRUE,
                                                  offset as libc::size_t,
                                                  len,
                                                  ptr,
                                                  event_list_length,
                                                  event_list,
                                                  ptr::null_mut());

                    check(err, "Failed to read buffer");
                }
            })
        })
    }

    pub fn write<U: Write, T, E: EventList, B: Buffer<T>>(&self, mem: &B, write: &U, event: E)
    {
        unsafe {
            event.as_event_list(|event_list, event_list_length| {
                write.write(|offset, p, len| {
                    let err = clEnqueueWriteBuffer(self.cqueue,
                                                   mem.id(),
                                                   CL_TRUE,
                                                   offset as libc::size_t,
                                                   len as libc::size_t,
                                                   p as *const libc::c_void,
                                                   event_list_length,
                                                   event_list,
                                                   ptr::null_mut());

                    check(err, "Failed to write buffer");
                })
            })
        }
    }

    pub fn write_async<U: Write, T, E: EventList, B: Buffer<T>>(&self, mem: &B, write: &U, event: E) -> Event
    {
        let mut out_event = None;
        unsafe {
            event.as_event_list(|evt, evt_len| {
                write.write(|offset, p, len| {
                    let mut e: cl_event = ptr::null_mut();
                    let err = clEnqueueWriteBuffer(self.cqueue,
                                                   mem.id(),
                                                   CL_FALSE,
                                                   offset as libc::size_t,
                                                   len as libc::size_t,
                                                   p as *const libc::c_void,
                                                   evt_len,
                                                   evt,
                                                   &mut e);
                    out_event = Some(e);
                    check(err, "Failed to write buffer");
                })
            })
        }
        Event { event: out_event.unwrap() }
    }

    pub fn read<T, U: Read, E: EventList, B: Buffer<T>>(&self, mem: &B, read: &mut U, event: E)
    {
        event.as_event_list(|event_list, event_list_length| {
                read.read(|offset, p, len| {
                        unsafe {
                            let err = clEnqueueReadBuffer(self.cqueue,
                                                          mem.id(),
                                                          CL_TRUE,
                                                          offset as libc::size_t,
                                                          len as libc::size_t,
                                                          p as *mut libc::c_void,
                                                          event_list_length,
                                                          event_list,
                                                          ptr::null_mut());

                            check(err, "Failed to read buffer");
                        }
                    })
            })
    }
}

impl Drop for CommandQueue
{
    fn drop(&mut self) {
        unsafe {
            clReleaseCommandQueue(self.cqueue);
        }
    }
}


/// Represents an OpenCL program, which is a collection of kernels.
///
/// Create these using
/// [`Context::create_program_from_source`](struct.Context.html#method.create_program_from_source)
/// or
/// [`Context::create_program_from_binary`](struct.Context.html#method.create_program_from_binary).
pub struct Program
{
    prg: cl_program,
}

impl Drop for Program
{
    fn drop(&mut self) {
        unsafe {
            clReleaseProgram(self.prg);
        }
    }
}

impl Program
{
    /// Build the program for a given device.
    ///
    /// Both Ok and Err returns include the build log.
    pub fn build(&self, device: &Device) -> Result<String, String>
    {
        unsafe
        {
            let ret = clBuildProgram(self.prg, 1, &device.id,
                                     ptr::null(),
                                     mem::transmute(ptr::null::<fn()>()),
                                     ptr::null_mut());
            // Get the build log.
            let mut size = 0 as libc::size_t;
            let status = clGetProgramBuildInfo(
                self.prg,
                device.id,
                CL_PROGRAM_BUILD_LOG,
                0,
                ptr::null_mut(),
                (&mut size));
            check(status, "Could not get build log");

            let mut buf : Vec<u8> = repeat(0u8).take(size as usize).collect();
            let status = clGetProgramBuildInfo(
                self.prg,
                device.id,
                CL_PROGRAM_BUILD_LOG,
                buf.len() as libc::size_t,
                buf.as_mut_ptr() as *mut libc::c_void,
                ptr::null_mut());
            check(status, "Could not get build log");

            let log = String::from_utf8_lossy(&buf[..]);
            if ret == CL_SUCCESS as cl_int {
                Ok(log.into_owned())
            } else {
                Err(log.into_owned())
            }
        }
    }

    pub fn create_kernel(&self, name: &str) -> Kernel {
        create_kernel(self, name)
    }
}

pub struct Kernel {
    kernel: cl_kernel,
}

impl Drop for Kernel
{
    fn drop(&mut self) {
        unsafe {
            clReleaseKernel(self.kernel);
        }
    }
}

impl Kernel {
    pub fn set_arg<T: KernelArg>(&self, i: usize, x: &T)
    {
        set_kernel_arg(self, i as cl::cl_uint, x)
    }
}

pub fn create_kernel(program: &Program, kernel: & str) -> Kernel
{
    unsafe {
        let mut errcode = 0;
        let str = CString::new(kernel).unwrap();
        let kernel = clCreateKernel(program.prg,
                                    str.as_ptr(),
                                    (&mut errcode));

        check(errcode, "Failed to create kernel!");

        Kernel { kernel: kernel }
    }
}

pub trait KernelArg {
  fn get_value(&self) -> (libc::size_t, *const libc::c_void);
}

macro_rules! scalar_kernel_arg (
    ($t:ty) => (impl KernelArg for $t {
        fn get_value(&self) -> (libc::size_t, *const libc::c_void) {
            (mem::size_of::<$t>() as libc::size_t,
             (self as *const $t) as *const libc::c_void)
        }
    })
);

scalar_kernel_arg!(isize);
scalar_kernel_arg!(usize);
scalar_kernel_arg!(u32);
scalar_kernel_arg!(u64);
scalar_kernel_arg!(i32);
scalar_kernel_arg!(i64);
scalar_kernel_arg!(f32);
scalar_kernel_arg!(f64);
scalar_kernel_arg!([f32; 2]);
scalar_kernel_arg!([f64; 2]);

impl KernelArg for [f32; 3] {
    fn get_value(&self) -> (libc::size_t, *const libc::c_void) {
        (4 * mem::size_of::<f32>() as libc::size_t,
          (self as *const f32) as *const libc::c_void)
    }
}

impl KernelArg for [f64; 3] {
    fn get_value(&self) -> (libc::size_t, *const libc::c_void) {
        (4 * mem::size_of::<f64>() as libc::size_t,
          (self as *const f64) as *const libc::c_void)
    }
}

pub fn set_kernel_arg<T: KernelArg>(kernel: & Kernel,
                                    position: cl_uint,
                                    arg: &T)
{
    unsafe
    {
        let (size, p) = arg.get_value();
        let ret = clSetKernelArg(kernel.kernel, position,
                                 size,
                                 p);

        check(ret, "Failed to set kernel arg!");
    }
}


pub struct Event
{
    pub event: cl_event,
}

impl Event {
    fn get_time(&self, param: cl_uint) -> u64
    {
        unsafe {
            let mut time: cl_ulong = 0;
            let ret = clGetEventProfilingInfo(self.event,
                                    param,
                                    mem::size_of::<cl_ulong>() as libc::size_t,
                                    (&mut time as *mut u64) as *mut libc::c_void,
                                    ptr::null_mut());

            check(ret, "Failed to get profiling info");
            time as u64
        }
    }

    pub fn queue_time(&self) -> u64
    {
        self.get_time(CL_PROFILING_COMMAND_QUEUED)
    }

    pub fn submit_time(&self) -> u64
    {
        self.get_time(CL_PROFILING_COMMAND_SUBMIT)
    }

    pub fn start_time(&self) -> u64
    {
        self.get_time(CL_PROFILING_COMMAND_START)
    }

    pub fn end_time(&self) -> u64
    {
        self.get_time(CL_PROFILING_COMMAND_END)
    }
}

impl Drop for Event
{
    fn drop(&mut self) {
        unsafe {
            clReleaseEvent(self.event);
        }
    }
}

pub trait EventList {
    fn as_event_list<T, F: FnOnce(*const cl_event, cl_uint) -> T>(&self, F) -> T;

    fn wait(&self) {
        self.as_event_list(|p, len| {
            unsafe {
                let status = clWaitForEvents(len, p);
                check(status, "Error waiting for event(s)");
            }
        })
    }
}

impl<'r> EventList for &'r Event {
    fn as_event_list<T, F>(&self, f: F) -> T
        where F: FnOnce(*const cl_event, cl_uint) -> T
    {
        f(&self.event, 1 as cl_uint)
    }
}

impl EventList for Event {
    fn as_event_list<T, F>(&self, f: F) -> T
        where F: FnOnce(*const cl_event, cl_uint) -> T
    {
        f(&self.event, 1 as cl_uint)
    }
}

impl<T: EventList> EventList for Option<T> {
    fn as_event_list<T2, F>(&self, f: F) -> T2
        where F: FnOnce(*const cl_event, cl_uint) -> T2
    {
        match *self {
            None => f(ptr::null(), 0),
            Some(ref s) => s.as_event_list(f)
        }
    }
}

impl<'r> EventList for &'r [Event] {
    fn as_event_list<T, F>(&self, f: F) -> T
        where F: FnOnce(*const cl_event, cl_uint) -> T
    {
        let mut vec: Vec<cl_event> = Vec::with_capacity(self.len());
        for item in self.iter(){
            vec.push(item.event);
        }

        f(vec.as_ptr(), vec.len() as cl_uint)
    }
}

/* this seems VERY hackey */
impl EventList for () {
    fn as_event_list<T, F>(&self, f: F) -> T
        where F: FnOnce(*const cl_event, cl_uint) -> T
    {
        f(ptr::null(), 0)
    }
}


pub trait KernelIndex
{
    fn num_dimensions(dummy_self: Option<Self>) -> cl_uint where Self: Sized;
    fn get_ptr(&self) -> *const libc::size_t;
}

impl KernelIndex for isize
{
    fn num_dimensions(_: Option<isize>) -> cl_uint { 1 }

    fn get_ptr(&self) -> *const libc::size_t
    {
        (self as *const isize) as *const libc::size_t
    }
}

impl KernelIndex for (isize, isize) {
    fn num_dimensions(_: Option<(isize, isize)>) -> cl_uint { 2 }

    fn get_ptr(&self) -> *const libc::size_t {
        (self as *const (isize, isize)) as *const libc::size_t
    }
}

impl KernelIndex for (isize, isize, isize)
{
    fn num_dimensions(_: Option<(isize, isize, isize)>) -> cl_uint { 3 }

    fn get_ptr(&self) -> *const libc::size_t {
        (self as *const (isize, isize, isize)) as *const libc::size_t
    }
}

impl KernelIndex for usize
{
    fn num_dimensions(_: Option<usize>) -> cl_uint { 1 }

    fn get_ptr(&self) -> *const libc::size_t {
        (self as *const usize) as *const libc::size_t
    }
}

impl KernelIndex for (usize, usize)
{
    fn num_dimensions(_: Option<(usize, usize)>) -> cl_uint { 2 }

    fn get_ptr(&self) -> *const libc::size_t {
        (self as *const (usize, usize)) as *const libc::size_t
    }
}

impl KernelIndex for (usize, usize, usize)
{
    fn num_dimensions(_: Option<(usize, usize, usize)>) -> cl_uint { 3 }

    fn get_ptr(&self) -> *const libc::size_t {
        (self as *const (usize, usize, usize)) as *const libc::size_t
    }
}


================================================
FILE: src/lib.rs
================================================
#![allow(improper_ctypes)]
#![allow(missing_copy_implementations)]
#![allow(non_upper_case_globals)]

#![feature(static_mutex)]

//! OpenCL bindings for Rust.

extern crate libc;
#[macro_use]
extern crate log;

#[link(name = "OpenCL", kind = "framework")]
#[cfg(target_os = "macos")]
extern { }

#[link(name = "OpenCL")]
#[cfg(target_os = "linux")]
extern { }

/// Low-level OpenCL bindings. These should primarily be used by the
/// higher level features in this library.
pub mod cl;
/// OpenCL extensions
pub mod ext;
pub mod error;
pub mod hl;
pub mod util;
pub mod mem;
pub mod array;


================================================
FILE: src/mem.rs
================================================
//! High level buffer management.

use libc::{size_t, c_void};
use std::marker::{PhantomData};
use std::mem;
use std::ptr;
use std::vec::Vec;

use cl::*;
use cl::ll::*;

use hl::KernelArg;
use error::check;

pub trait Buffer<T> {
    unsafe fn id_ptr(&self) -> *const cl_mem;

    fn id(&self) -> cl_mem {
        unsafe {
            *self.id_ptr()
        }
    }

    fn byte_len(&self) -> size_t
    {
        unsafe {
            let mut size : size_t = 0;
            let err = clGetMemObjectInfo(self.id(),
                                         CL_MEM_SIZE,
                                         mem::size_of::<size_t>() as size_t,
                                         (&mut size as *mut size_t) as *mut c_void,
                                         ptr::null_mut());

            check(err, "Failed to read memory size");
            size
        }
    }

    fn len(&self) -> usize { self.byte_len() as usize / mem::size_of::<T>() }
}

pub struct CLBuffer<T> {
    pub cl_buffer: cl_mem,
    pub phantom: PhantomData<T>,
}

impl<T> Drop for CLBuffer<T> {
    fn drop(&mut self) {
        unsafe {
            clReleaseMemObject(self.cl_buffer);
        }
    }
}

impl<T> Buffer<T> for CLBuffer<T> {
    unsafe fn id_ptr(&self) -> *const cl_mem
    {
        &self.cl_buffer as *const cl_mem
    }
}

impl<T> KernelArg for CLBuffer<T> {
    fn get_value(&self) -> (size_t, *const c_void)
    {
        unsafe {
            (mem::size_of::<cl_mem>() as size_t,
             self.id_ptr() as *const c_void)
        }
    }
}

/* memory life cycle
 * | Trait  | Exists in rust | Exists in OpenCL | Direction      |
 * | Put    | X              |                  | rust -> opencl |
 * | Get    |                | X                | opencl -> rust |
 * | Write  | X              | X                | rust -> opencl |
 * | Read   | X              | X                | opencl -> rust |
 *mut */

pub trait Put<T, B> {
    fn put<F>(&self, F) -> B
        where F: FnOnce(*const c_void, size_t) -> cl_mem;
}

pub trait Get<B, T> {
    fn get<F: FnOnce(size_t, *mut c_void, size_t)>(mem: &B, F) -> Self;
}

pub trait Write {
    fn write<F: FnOnce(size_t, *const c_void, size_t)>(&self, F);
}

pub trait Read {
    fn read<F: FnOnce(size_t, *mut c_void, size_t)>(&mut self, F);
}

impl<'r, T> Put<T, CLBuffer<T>> for &'r [T]
{
    fn put<F>(&self, f: F) -> CLBuffer<T>
        where F: FnOnce(*const c_void, size_t) -> cl_mem
    {
        CLBuffer {
            cl_buffer: f(self.as_ptr() as *const c_void,
                         (self.len() * mem::size_of::<T>()) as size_t),
            phantom: PhantomData,
        }
    }
}

impl<'r, T> Put<T, CLBuffer<T>> for &'r Vec<T>
{
    fn put<F>(&self, f: F) -> CLBuffer<T>
        where F: FnOnce(*const c_void, size_t) -> cl_mem
    {
        CLBuffer {
            cl_buffer: f(self.as_ptr() as *const c_void, (self.len() * mem::size_of::<T>()) as size_t),
            phantom: PhantomData,
        }
    }
}

impl<T> Put<T, CLBuffer<T>> for Vec<T>
{
    fn put<F>(&self, f: F) -> CLBuffer<T>
        where F: FnOnce(*const c_void, size_t) -> cl_mem
    {
        CLBuffer {
            cl_buffer: f(self.as_ptr() as *const c_void, (self.len() * mem::size_of::<T>()) as size_t),
            phantom: PhantomData,
        }
    }
}

impl<T> Get<CLBuffer<T>, T> for Vec<T>
{
    fn get<F>(mem: &CLBuffer<T>, f: F) -> Vec<T>
        where F: FnOnce(size_t, *mut c_void, size_t)
    {
        let mut v: Vec<T> = Vec::with_capacity(mem.len());
        unsafe {
            v.set_len(mem.len());
        }
        f(0, v.as_ptr() as *mut c_void, (v.len() * mem::size_of::<T>()) as size_t);
        v
    }
}

impl<'r, T> Write for &'r [T]
{
    fn write<F>(&self, f: F)
        where F: FnOnce(size_t, *const c_void, size_t)
    {
        f(0, self.as_ptr() as *const c_void, (self.len() * mem::size_of::<T>()) as size_t)
    }
}

impl<'r, T> Read for &'r mut [T]
{
    fn read<F>(&mut self, f: F)
        where F: FnOnce(size_t, *mut c_void, size_t)
    {
        let p = (*self).as_mut_ptr();
        let len = self.len();
        f(0, p as *mut c_void, (len * mem::size_of::<T>()) as size_t)
    }
}

macro_rules! get_arg (
    ($t:ty) => (impl Get<CLBuffer<$t>, $t> for $t
        {
            fn get<F>(_: &CLBuffer<$t>, f: F) -> $t
                where F: FnOnce(size_t, *mut c_void, size_t)
            {
                let mut v: $t = 0 as $t;
                f(0, (&mut v as *mut $t) as *mut c_void, mem::size_of::<$t>() as size_t);
                v as $t
            }
        })
);

get_arg!(isize);
get_arg!(usize);
get_arg!(u32);
get_arg!(u64);
get_arg!(i32);
get_arg!(i64);
get_arg!(f32);
get_arg!(f64);

macro_rules! put_arg (
    ($t:ty) => (impl Put<$t, CLBuffer<$t>> for $t
        {
            fn put<F>(&self, f: F) -> CLBuffer<$t>
                where F: FnOnce(*const c_void, size_t) -> cl_mem
            {
                CLBuffer {
                    cl_buffer: f((self as *const $t) as *const c_void, mem::size_of::<$t>() as size_t),
                    phantom: PhantomData,
                }
            }
        }
    )
);

put_arg!(isize);
put_arg!(usize);
put_arg!(u32);
put_arg!(u64);
put_arg!(i32);
put_arg!(i64);
put_arg!(f32);
put_arg!(f64);

macro_rules! read_arg (
    ($t:ty) => (impl Read for $t
        {
            fn read<F>(&mut self, f: F)
                where F: FnOnce(size_t, *mut c_void, size_t)
            {
                f(0, (self as *mut $t) as *mut c_void, mem::size_of::<$t>() as size_t)
            }
        }
    )
);

read_arg!(isize);
read_arg!(usize);
read_arg!(u32);
read_arg!(u64);
read_arg!(i32);
read_arg!(i64);
read_arg!(f32);
read_arg!(f64);

macro_rules! write_arg (
    ($t:ty) => (impl Write for $t
        {
            fn write<F>(&self, f: F) 
                where F: FnOnce(size_t, *const c_void, size_t)
            {
                f(0, (self as *const $t) as *const c_void, mem::size_of::<$t>() as size_t)
            }
        }
    )
);

write_arg!(isize);
write_arg!(usize);
write_arg!(u32);
write_arg!(u64);
write_arg!(i32);
write_arg!(i64);
write_arg!(f32);
write_arg!(f64);


================================================
FILE: src/util.rs
================================================
//! Utility functions

use hl::*;

pub fn create_compute_context() -> Result<(Device, Context, CommandQueue), &'static str>
{
    let platforms = get_platforms();
    if platforms.len() == 0 {
        return Err("No platform found");
    }

    let mut devices = platforms[0].get_devices();
    if devices.len() == 0 {
        Err("No device found")
    } else {
        let device = devices.remove(0);
        let context = device.create_context();
        let queue = context.create_command_queue(&device);
        Ok((device, context, queue))
    }
}

#[derive(Copy, Clone)]
pub enum PreferedType {
    Any,

    CPUPrefered,
    GPUPrefered,

    CPUOnly,
    GPUOnly,
}

pub fn create_compute_context_prefer(cltype: PreferedType) -> Result<(Device, Context, CommandQueue), &'static str>
{
    let platforms = get_platforms();
    for platform in platforms.iter() {
        let types = match cltype {
            PreferedType::Any => vec![DeviceType::CPU, DeviceType::GPU],
            PreferedType::CPUPrefered | PreferedType::CPUOnly => vec![DeviceType::CPU],
            PreferedType::GPUPrefered | PreferedType::GPUOnly => vec![DeviceType::GPU]
        };

        let mut devices = platform.get_devices_by_types(&types[..]);
        if devices.len() > 0 {
            let device = devices.remove(0);
            let context = device.create_context();
            let queue = context.create_command_queue(&device);
            return Ok((device, context, queue))
        }
    }


    match cltype {
        PreferedType::Any |
        PreferedType::CPUPrefered |
        PreferedType::GPUPrefered => create_compute_context(),
        _ => Err("Could not find valid implementation")
    }
}


================================================
FILE: tests/test.rs
================================================
#![feature(slice_bytes)]

#[macro_use]
extern crate log;

extern crate opencl;

use opencl::hl::*;

macro_rules! expect (
    ($test: expr, $expected: expr) => ({
            let test     = $test;
            let expected = $expected;
            if test != expected {
                panic!(format!("Test failure in {}:", // " expected {}, got {}",
                              stringify!($test)/*,
                              expected, test*/))
            }
        }
    )
);

pub fn test_all_platforms_devices<F>(test: &mut F)
    where F: FnMut(&Device, &Context, &CommandQueue)
{
    let platforms = get_platforms();
    for p in platforms.iter() {
        let devices = p.get_devices();
        for d in devices.iter() {
            let context = d.create_context();
            let queue = context.create_command_queue(d);
            test(d, &context, &queue);
        }
    }
}

mod mem {
    use std::slice;
    use opencl::mem::{Read, Write};

    fn read_write<W: Write, R: Read>(src: &W, dst: &mut R)
    {
        // find the max size of the input buffer
        let mut max = 0;
        src.write(|off, _, len| {
            if max < off + len {
                max = off + len;
            }
        });
        let max = max as usize;

        let mut buffer: Vec<u8> = Vec::new();
        unsafe {
            buffer.reserve(max);
            buffer.set_len(max);
        }

        // copy from input into buffer
        src.write(|off, ptr, len| {
            let off = off as usize;
            let len = len as usize;
            assert!(buffer.len() >= (off + len) as usize);
            let target = &mut buffer[off .. off + len];
            unsafe {
                let ptr = ptr as *const u8;
                let src = slice::from_raw_parts(ptr, len);
                slice::bytes::copy_memory(src, target);
            }
        });

        // copy from buffer into output
        dst.read(|off, ptr, len| {
            let off = off as usize;
            let len = len as usize;
            assert!(buffer.len() >= (off + len) as usize);
            let src = &buffer[off .. off + len];
            unsafe {
                let ptr = ptr as *mut u8;
                let mut dst = slice::from_raw_parts_mut(ptr, len);
                slice::bytes::copy_memory(src, dst);
            }
        })
    }

    #[test]
    fn read_write_slice()
    {
        let input: &[isize] = &[0, 1, 2, 3, 4, 5, 6, 7];
        let mut output: &mut [isize] = &mut [0, 0, 0, 0, 0, 0, 0, 0];
        read_write(&input, &mut output);
        expect!(input, output);
    }

    #[test]
    fn read_write_int()
    {
        let input: isize      = 3141;
        let mut output: isize = 0;
        read_write(&input, &mut output);
        expect!(input, output);
    }

    #[test]
    fn read_write_uint()
    {
        let input : usize = 3141;
        let mut output : usize = 0;
        read_write(&input, &mut output);
        expect!(input, output);
    }

    #[test]
    fn read_write_f32()
    {
        let input : f32 = 3141.;
        let mut output : f32 = 0.;
        read_write(&input, &mut output);
        expect!(input, output);
    }

    #[test]
    fn read_write_f64()
    {
        let input : f64 = 3141.;
        let mut output : f64 = 0.;
        read_write(&input, &mut output);
        expect!(input, output);
    }
}

#[cfg(test)]
mod hl {
    use opencl::cl::*;
    use opencl::hl::*;
    use opencl::mem::*;
    use opencl::util;

    #[test]
    fn program_build() {
        let src = "__kernel void test(__global int *i) { \
                   *i += 1; \
                   }";
        ::test_all_platforms_devices(&mut |device, ctx, _| {
            let prog = ctx.create_program_from_source(src);
            prog.build(device).unwrap();
        })
    }

    #[test]
    fn simple_kernel() {
        let src = "__kernel void test(__global int *i) { \
                   *i += 1; \
                   }";
        ::test_all_platforms_devices(&mut |device, ctx, queue| {
            let prog = ctx.create_program_from_source(src);
            prog.build(device).unwrap();

            let k = prog.create_kernel("test");
            let v = ctx.create_buffer_from(vec![1isize], CL_MEM_READ_WRITE);

            k.set_arg(0, &v);

            queue.enqueue_async_kernel(&k, 1isize, None, ()).wait();

            let v: Vec<isize> = queue.get(&v, ());

            expect!(v[0], 2);
        })
    }

    #[test]
    fn add_k() {
        let src = "__kernel void test(__global int *i, long int k) { \
                   *i += k; \
                   }";

        ::test_all_platforms_devices(&mut |device, ctx, queue| {
            let prog = ctx.create_program_from_source(src);
            prog.build(device).unwrap();

            let k = prog.create_kernel("test");

            let v = ctx.create_buffer_from(vec![1isize], CL_MEM_READ_WRITE);

            k.set_arg(0, &v);
            k.set_arg(1, &42isize);

            queue.enqueue_async_kernel(&k, 1isize, None, ()).wait();

            let v: Vec<isize> = queue.get(&v, ());

            expect!(v[0], 43);
        })
    }

    #[test]
    fn simple_kernel_index() {
        let src = "__kernel void test(__global int *i) { \
                   *i += 1; \
                   }";

        ::test_all_platforms_devices(&mut |device, ctx, queue| {
            let prog = ctx.create_program_from_source(src);
            prog.build(device).unwrap();

            let k = prog.create_kernel("test");

            let v = ctx.create_buffer_from(vec![1isize], CL_MEM_READ_WRITE);

            k.set_arg(0, &v);

            queue.enqueue_async_kernel(&k, 1isize, None, ()).wait();

            let v: Vec<isize> = queue.get(&v, ());

            expect!(v[0], 2);
        })
    }

    #[test]
    fn chain_kernel_event() {
        let src = "__kernel void test(__global int *i) { \
                   *i += 1; \
                   }";

        ::test_all_platforms_devices(&mut |device, ctx, queue| {
            let prog = ctx.create_program_from_source(src);
            prog.build(device).unwrap();

            let k = prog.create_kernel("test");
            let v = ctx.create_buffer_from(vec![1isize], CL_MEM_READ_WRITE);

            k.set_arg(0, &v);

            let mut e : Option<Event> = None;
            for _ in 0isize .. 8 {
                e = Some(queue.enqueue_async_kernel(&k, 1isize, None, e));
            }
            e.wait();

            let v: Vec<isize> = queue.get(&v, ());

            expect!(v[0], 9);
        })
    }

    #[test]
    fn chain_kernel_event_list() {
        let src = "__kernel void inc(__global int *i) { \
                   *i += 1; \
                   } \
                   __kernel void add(__global int *a, __global int *b, __global int *c) { \
                   *c = *a + *b; \
                   }";

        ::test_all_platforms_devices(&mut |device, ctx, queue| {
            let prog = ctx.create_program_from_source(src);
            prog.build(device).unwrap();

            let k_inc_a = prog.create_kernel("inc");
            let k_inc_b = prog.create_kernel("inc");
            let k_add = prog.create_kernel("add");

            let a = ctx.create_buffer_from(vec![1isize], CL_MEM_READ_WRITE);
            let b = ctx.create_buffer_from(vec![1isize], CL_MEM_READ_WRITE);
            let c = ctx.create_buffer_from(vec![1isize], CL_MEM_READ_WRITE);

            k_inc_a.set_arg(0, &a);
            k_inc_b.set_arg(0, &b);

            let event_list = [
                queue.enqueue_async_kernel(&k_inc_a, 1isize, None, ()),
                queue.enqueue_async_kernel(&k_inc_b, 1isize, None, ()),
            ];

            k_add.set_arg(0, &a);
            k_add.set_arg(1, &b);
            k_add.set_arg(2, &c);

            let event = queue.enqueue_async_kernel(&k_add, 1isize, None, &event_list[..]);

            let v: Vec<isize> = queue.get(&c, event);

            expect!(v[0], 4);
        })
    }

    #[test]
    fn kernel_2d()
    {
        let src = "__kernel void test(__global long int *N) { \
                   int i = get_global_id(0); \
                   int j = get_global_id(1); \
                   int s = get_global_size(0); \
                   N[i * s + j] = i * j;
}";
        ::test_all_platforms_devices(&mut |device, ctx, queue| {
            let prog = ctx.create_program_from_source(src);

            match prog.build(device) {
                Ok(_) => (),
                Err(build_log) => {
                    println!("Error building program:\n");
                    println!("{}", build_log);
                    panic!("");
                }
            }

            let k = prog.create_kernel("test");

            let v = ctx.create_buffer_from(&[1isize, 2, 3, 4, 5, 6, 7, 8, 9][..], CL_MEM_READ_ONLY);

            k.set_arg(0, &v);

            queue.enqueue_async_kernel(&k, (3isize, 3isize), None, ()).wait();

            let v: Vec<isize> = queue.get(&v, ());

            expect!(v, vec!(0, 0, 0, 0, 1, 2, 0, 2, 4));
        })
    }

    #[test]
    fn memory_read_write()
    {
        ::test_all_platforms_devices(&mut |_, ctx, queue| {
            let buffer: CLBuffer<isize> = ctx.create_buffer(8, CL_MEM_READ_ONLY);

            let input = [0isize, 1, 2, 3, 4, 5, 6, 7];
            let mut output = [0isize, 0, 0, 0, 0, 0, 0, 0];

            queue.write(&buffer, &&input[..], ());
            queue.read(&buffer, &mut &mut output[..], ());

            expect!(input, output);
        })
    }

    #[test]
    fn memory_read_vec()
    {
        ::test_all_platforms_devices(&mut |_, ctx, queue| {
            let input = [0isize, 1, 2, 3, 4, 5, 6, 7];
            let buffer = ctx.create_buffer_from(&input[..], CL_MEM_READ_WRITE);
            let output: Vec<isize> = queue.get(&buffer, ());
            expect!(&input[..], &output[..]);
        })
    }


    #[test]
    fn memory_read_owned()
    {
        ::test_all_platforms_devices(&mut |_, ctx, queue| {
            let input = vec!(0isize, 1, 2, 3, 4, 5, 6, 7);
            let buffer = ctx.create_buffer_from(&input, CL_MEM_READ_WRITE);
            let output: Vec<isize> = queue.get(&buffer, ());
            expect!(input, output);
        })
    }

    #[test]
    fn memory_read_owned_clone()
    {
        ::test_all_platforms_devices(&mut |_, ctx, queue| {
            let input = vec!(0isize, 1, 2, 3, 4, 5, 6, 7);
            let buffer = ctx.create_buffer_from(input.clone(), CL_MEM_READ_WRITE);
            let output: Vec<isize> = queue.get(&buffer, ());
            expect!(input, output);
        })
    }

    #[test]
    fn event_get_times() {
        let src = "__kernel void test(__global int *i) { \
                   *i += 1; \
                   }";

        let (device, ctx, queue) = util::create_compute_context().unwrap();
        let prog = ctx.create_program_from_source(src);
        prog.build(&device).unwrap();

        let k = prog.create_kernel("test");
        let v = ctx.create_buffer_from(vec![1isize], CL_MEM_READ_WRITE);

        k.set_arg(0, &v);

        let e = queue.enqueue_async_kernel(&k, 1isize, None, ());
        e.wait();

        // the that are returned are not useful for unit test, this test
        // is mostly testing that opencl returns no error
        e.queue_time();
        e.submit_time();
        e.start_time();
        e.end_time();
    }
}


#[cfg(test)]
mod array {
    use opencl::array::*;
    use opencl::cl::CL_MEM_READ_WRITE;

    #[test]
    fn put_get_2d()
    {
        ::test_all_platforms_devices(&mut |_, ctx, queue| {
            let arr_in = Array2D::new(8, 8, |x, y| {(x+y) as isize});
            let arr_cl = ctx.create_buffer_from(&arr_in, CL_MEM_READ_WRITE);
            let arr_out: Array2D<isize> = queue.get(&arr_cl, ());

            for x in 0usize.. 8usize {
                for y in 0usize..8usize {
                    expect!(arr_in.get(x, y), arr_out.get(x, y));
                }
            }
        })
    }


    #[test]
    fn read_write_2d()
    {
        ::test_all_platforms_devices(&mut |_, ctx, queue| {
            let added = Array2D::new(8, 8, |x, y| {(x+y) as isize});
            let zero = Array2D::new(8, 8, |_, _| {(0) as isize});
            let mut out = Array2D::new(8, 8, |_, _| {(0) as isize});

            /* both are zeroed */
            let a_cl = ctx.create_buffer_from(&zero, CL_MEM_READ_WRITE);

            queue.write(&a_cl, &added, ());
            queue.read(&a_cl, &mut out, ());

            for x in 0usize .. 8usize {
                for y in 0usize .. 8usize {
                    expect!(added.get(x, y), out.get(x, y));
                }
            }
        })
    }


    #[test]
    fn kernel_2d()
    {
        ::test_all_platforms_devices(&mut |device, ctx, queue| {
            let mut a = Array2D::new(8, 8, |_, _| {(0) as i32});
            let b = Array2D::new(8, 8, |x, y| {(x*y) as i32});
            let a_cl = ctx.create_buffer_from(&a, CL_MEM_READ_WRITE);

            let src =  "__kernel void test(__global int *a) { \
                            int x = get_global_id(0); \
                            int y = get_global_id(1); \
                            int size_x = get_global_size(0); \
                            a[size_x*y + x] = x*y; \
                        }";
            let prog = ctx.create_program_from_source(src);
            match prog.build(device) {
                Ok(_) => (),
                Err(build_log) => {
                    println!("Error building program:\n");
                    println!("{}", build_log);
                    panic!("");
                }
            }
            let k = prog.create_kernel("test");

            k.set_arg(0, &a_cl);
            let event = queue.enqueue_async_kernel(&k, (8isize, 8isize), None, ());
            queue.read(&a_cl, &mut a, &event);

            for x in 0usize .. 8usize {
                for y in 0usize .. 8usize {
                    expect!(a.get(x, y), b.get(x, y));
                }
            }
        })
    }

    #[test]
    fn put_get_3d()
    {
        ::test_all_platforms_devices(&mut |_, ctx, queue| {
            let arr_in = Array3D::new(8, 8, 8, |x, y, z| {(x+y+z) as isize});
            let arr_cl = ctx.create_buffer_from(&arr_in, CL_MEM_READ_WRITE);
            let arr_out: Array3D<isize> = queue.get(&arr_cl, ());

            for x in 0usize .. 8usize {
                for y in 0usize .. 8usize {
                    for z in 0usize .. 8usize {
                        expect!(arr_in.get(x, y, z), arr_out.get(x, y, z));
                    }
                }
            }
        })
    }


    #[test]
    fn read_write_3d()
    {
        ::test_all_platforms_devices(&mut |_, ctx, queue| {
            let added = Array3D::new(8, 8, 8, |x, y, z| {(x+y+z) as isize});
            let zero = Array3D::new(8, 8, 8, |_, _, _| {(0) as isize});
            let mut out = Array3D::new(8, 8, 8, |_, _, _| {(0) as isize});

            /* both are zeroed */
            let a_cl = ctx.create_buffer_from(&zero, CL_MEM_READ_WRITE);

            queue.write(&a_cl, &added, ());
            queue.read(&a_cl, &mut out, ());

            for x in 0usize .. 8usize {
                for y in 0usize .. 8usize {
                    for z in 0usize .. 8usize {
                        expect!(added.get(x, y, z), out.get(x, y, z));
                    }
                }
            }
        })
    }


    #[test]
    fn kernel_3d()
    {
        ::test_all_platforms_devices(&mut |device, ctx, queue| {
            let mut a = Array3D::new(8, 8, 8, |_, _, _| {(0) as i32});
            let b = Array3D::new(8, 8, 8, |x, y, z| {(x*y*z) as i32});
            let a_cl = ctx.create_buffer_from(&a, CL_MEM_READ_WRITE);

            let src =  "__kernel void test(__global int *a) { \
                            int x = get_global_id(0); \
                            int y = get_global_id(1); \
                            int z = get_global_id(2); \
                            int size_x = get_global_size(0); \
                            int size_y = get_global_size(1); \
                            a[size_x*size_y*z + size_x*y + x] = x*y*z; \
                        }";
            let prog = ctx.create_program_from_source(src);
            match prog.build(device) {
                Ok(_) => (),
                Err(build_log) => {
                    println!("Error building program:\n");
                    println!("{}", build_log);
                    panic!("");
                }
            }
            let k = prog.create_kernel("test");

            k.set_arg(0, &a_cl);
            let event = queue.enqueue_async_kernel(&k, (8isize, 8isize, 8isize), None, ());
            queue.read(&a_cl, &mut a, &event);

            for x in 0usize .. 8usize {
                for y in 0usize .. 8usize {
                    for z in 0usize .. 8usize {
                        expect!(a.get(x, y, z), b.get(x, y, z));
                    }
                }
            }
        })
    }
}

#[cfg(test)]
mod ext {
    use opencl::ext;
    use opencl::hl::*;

    #[test]
    fn try_load_all_extensions() {
        let platforms = get_platforms();

        for platform in platforms.into_iter() {
            let platform_id = platform.get_id();

            macro_rules! check_ext {
                ($ext:ident) => {
                    match ext::$ext::load(platform_id) {
                        Ok(_) => {
                            info!("Extension {} loaded successfully.",
                                  stringify!($ext))
                        }
                        Err(_) => {
                            info!("Error loading extension {}.",
                                  stringify!($ext))
                        }
                    }
                }
            }

            check_ext!(cl_khr_fp64);
            check_ext!(cl_khr_fp16);
            check_ext!(cl_APPLE_SetMemObjectDestructor);
            check_ext!(cl_APPLE_ContextLoggingFunctions);
            check_ext!(cl_khr_icd);
            check_ext!(cl_nv_device_attribute_query);
            check_ext!(cl_amd_device_attribute_query);
            check_ext!(cl_arm_printf);
            check_ext!(cl_ext_device_fission);
            check_ext!(cl_qcom_ext_host_ptr);
            check_ext!(cl_qcom_ion_host_ptr);
        }
    }
}

#[cfg(test)]
mod cl {
    use opencl::cl::CLStatus::*;

    #[test]
    fn clstatus_str() {
        let x = CL_SUCCESS;
        expect!(format!("{}", x), "CL_SUCCESS");

        let y = CL_DEVICE_NOT_FOUND;
        expect!(y.to_string(), "CL_DEVICE_NOT_FOUND");
    }
}
Download .txt
gitextract_m_jlpnxy/

├── .gitignore
├── .travis.yml
├── COPYRIGHT
├── Cargo.toml
├── LICENSE-APACHE
├── LICENSE-MIT
├── Makefile
├── examples/
│   ├── demo/
│   │   ├── demo.ocl
│   │   └── main.rs
│   └── platform/
│       └── main.rs
├── src/
│   ├── OpenCL/
│   │   └── error.rs
│   ├── array.rs
│   ├── cl.rs
│   ├── error.rs
│   ├── ext.rs
│   ├── hl.rs
│   ├── lib.rs
│   ├── mem.rs
│   └── util.rs
└── tests/
    └── test.rs
Download .txt
SYMBOL INDEX (306 symbols across 11 files)

FILE: examples/demo/main.rs
  function main (line 6) | fn main()
  function string_from_slice (line 44) | fn string_from_slice<T: fmt::Display>(slice: &[T]) -> String {

FILE: examples/platform/main.rs
  function main (line 5) | fn main() {

FILE: src/OpenCL/error.rs
  method fmt (line 7) | fn fmt(&self, f: &mut Formatter) -> Result {
  function try_convert (line 22) | pub fn try_convert(status: cl_int) -> Option<CLStatus> {
  function convert (line 76) | pub fn convert(status: cl_int) -> CLStatus {
  function error_str (line 83) | fn error_str(status: cl_int) -> ~str {
  function check (line 90) | pub fn check(status: cl_int, message: &str) {

FILE: src/array.rs
  type Array3D (line 13) | pub struct Array3D<T> {
  type Array3DCL (line 20) | pub struct Array3DCL<T> {
  function new (line 29) | pub fn new<F>(width: usize, height: usize, depth: usize,
  function set (line 51) | pub fn set(&mut self, x: usize, y: usize, z: usize, val: T)
  function get (line 56) | pub fn get(&self, x: usize, y: usize, z: usize) -> T
  method drop (line 63) | fn drop(&mut self) {
  function put (line 72) | fn put<F>(&self, f: F)
  function get (line 93) | fn get<F>(arr: &Array3DCL<T>, f: F)
  method write (line 116) | fn write<F>(&self, f: F)
  method read (line 126) | fn read<F>(&mut self, f: F)
  function id_ptr (line 136) | unsafe fn id_ptr(&self) -> *const cl_mem {
  function len (line 140) | fn len(&self) -> usize {
  method get_value (line 146) | fn get_value(&self) -> (size_t, *const c_void)
  type Array2D (line 153) | pub struct Array2D<T> {
  type Array2DCL (line 159) | pub struct Array2DCL<T> {
  function new (line 167) | pub fn new<F>(width: usize, height: usize, val: F) -> Array2D<T>
  function set (line 183) | pub fn set(&mut self, x: usize, y: usize, val: T) {
  function get (line 187) | pub fn get(&self, x: usize, y: usize) -> T {
  method drop (line 193) | fn drop(&mut self) {
  function put (line 202) | fn put<F>(&self, f: F) -> Array2DCL<T>
  function get (line 221) | fn get<F>(arr: &Array2DCL<T>, f: F)
  method write (line 243) | fn write<F>(&self, f: F)
  method read (line 253) | fn read<F>(&mut self, f: F)
  function id_ptr (line 263) | unsafe fn id_ptr(&self) -> *const cl_mem {
  function len (line 267) | fn len(&self) -> usize {
  method get_value (line 273) | fn get_value(&self) -> (size_t, *const c_void)

FILE: src/cl.rs
  type cl_platform_id (line 9) | pub type cl_platform_id     = *mut libc::c_void;
  type cl_device_id (line 10) | pub type cl_device_id       = *mut libc::c_void;
  type cl_context (line 11) | pub type cl_context         = *mut libc::c_void;
  type cl_command_queue (line 12) | pub type cl_command_queue   = *mut libc::c_void;
  type cl_mem (line 13) | pub type cl_mem             = *mut libc::c_void;
  type cl_program (line 14) | pub type cl_program         = *mut libc::c_void;
  type cl_kernel (line 15) | pub type cl_kernel          = *mut libc::c_void;
  type cl_event (line 16) | pub type cl_event           = *mut libc::c_void;
  type cl_sampler (line 17) | pub type cl_sampler         = *mut libc::c_void;
  type cl_char (line 20) | pub type cl_char    = i8;
  type cl_uchar (line 21) | pub type cl_uchar   = u8;
  type cl_short (line 22) | pub type cl_short   = i16;
  type cl_ushort (line 23) | pub type cl_ushort  = u16;
  type cl_int (line 24) | pub type cl_int     = i32;
  type cl_uint (line 25) | pub type cl_uint    = u32;
  type cl_long (line 26) | pub type cl_long    = i64;
  type cl_ulong (line 27) | pub type cl_ulong   = u64;
  type cl_half (line 29) | pub type cl_half    = u16;
  type cl_float (line 30) | pub type cl_float   = f32;
  type cl_double (line 31) | pub type cl_double  = f64;
  type cl_bool (line 33) | pub type cl_bool                        = cl_uint;
  type cl_bitfield (line 34) | pub type cl_bitfield                    = cl_ulong;
  type cl_device_type (line 35) | pub type cl_device_type                 = cl_bitfield;
  type cl_platform_info (line 36) | pub type cl_platform_info               = cl_uint;
  type cl_device_info (line 37) | pub type cl_device_info                 = cl_uint;
  type cl_device_fp_config (line 38) | pub type cl_device_fp_config            = cl_bitfield;
  type cl_device_mem_cache_type (line 39) | pub type cl_device_mem_cache_type       = cl_uint;
  type cl_device_local_mem_type (line 40) | pub type cl_device_local_mem_type       = cl_uint;
  type cl_device_exec_capabilities (line 41) | pub type cl_device_exec_capabilities    = cl_bitfield;
  type cl_command_queue_properties (line 42) | pub type cl_command_queue_properties    = cl_bitfield;
  type cl_context_properties (line 44) | pub type cl_context_properties          = libc::intptr_t;
  type cl_context_info (line 45) | pub type cl_context_info                = cl_uint;
  type cl_command_queue_info (line 46) | pub type cl_command_queue_info          = cl_uint;
  type cl_channel_order (line 47) | pub type cl_channel_order               = cl_uint;
  type cl_channel_type (line 48) | pub type cl_channel_type                = cl_uint;
  type cl_mem_flags (line 49) | pub type cl_mem_flags                   = cl_bitfield;
  type cl_mem_object_type (line 50) | pub type cl_mem_object_type             = cl_uint;
  type cl_mem_info (line 51) | pub type cl_mem_info                    = cl_uint;
  type cl_image_info (line 52) | pub type cl_image_info                  = cl_uint;
  type cl_buffer_create_type (line 53) | pub type cl_buffer_create_type          = cl_uint;
  type cl_addressing_mode (line 54) | pub type cl_addressing_mode             = cl_uint;
  type cl_filter_mode (line 55) | pub type cl_filter_mode                 = cl_uint;
  type cl_sampler_info (line 56) | pub type cl_sampler_info                = cl_uint;
  type cl_map_flags (line 57) | pub type cl_map_flags                   = cl_bitfield;
  type cl_program_info (line 58) | pub type cl_program_info                = cl_uint;
  type cl_program_build_info (line 59) | pub type cl_program_build_info          = cl_uint;
  type cl_build_status (line 60) | pub type cl_build_status                = cl_int;
  type cl_kernel_info (line 61) | pub type cl_kernel_info                 = cl_uint;
  type cl_kernel_work_group_info (line 62) | pub type cl_kernel_work_group_info      = cl_uint;
  type cl_event_info (line 63) | pub type cl_event_info                  = cl_uint;
  type cl_command_type (line 64) | pub type cl_command_type                = cl_uint;
  type cl_profiling_info (line 65) | pub type cl_profiling_info              = cl_uint;
  type cl_image_format (line 67) | pub struct cl_image_format {
  type cl_buffer_region (line 72) | pub struct cl_buffer_region {
  type CLStatus (line 81) | pub enum CLStatus {
    method fmt (line 136) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  function clGetPlatformIDs (line 443) | pub fn clGetPlatformIDs(num_entries:   cl_uint,
  function clGetPlatformInfo (line 446) | pub fn clGetPlatformInfo(platform: cl_platform_id,
  function clGetDeviceIDs (line 453) | pub fn clGetDeviceIDs(platform: cl_platform_id,
  function clGetDeviceInfo (line 458) | pub fn clGetDeviceInfo(device: cl_device_id,
  function clCreateContext (line 465) | pub fn clCreateContext(properties: *const cl_context_properties,
  function clCreateContextFromType (line 471) | pub fn clCreateContextFromType(properties: *mut cl_context_properties,
  function clRetainContext (line 476) | pub fn clRetainContext(context: cl_context) -> cl_int;
  function clReleaseContext (line 477) | pub fn clReleaseContext(context: cl_context) -> cl_int;
  function clGetContextInfo (line 478) | pub fn clGetContextInfo(context: cl_context,
  function clCreateCommandQueue (line 485) | pub fn clCreateCommandQueue(context: cl_context,
  function clRetainCommandQueue (line 489) | pub fn clRetainCommandQueue(command_queue: cl_command_queue) -> cl_int;
  function clReleaseCommandQueue (line 490) | pub fn clReleaseCommandQueue(command_queue: cl_command_queue) -> cl_int;
  function clGetCommandQueueInfo (line 491) | pub fn clGetCommandQueueInfo(command_queue: cl_command_queue,
  function clCreateBuffer (line 498) | pub fn clCreateBuffer(context: cl_context,
  function clCreateSubBuffer (line 503) | pub fn clCreateSubBuffer(buffer: cl_mem,
  function clCreateImage2D (line 508) | pub fn clCreateImage2D(context: cl_context,
  function clCreateImage3D (line 516) | pub fn clCreateImage3D(context: cl_context,
  function clRetainMemObject (line 528) | pub fn clRetainMemObject(memobj: cl_mem) -> cl_int;
  function clReleaseMemObject (line 529) | pub fn clReleaseMemObject(memobj: cl_mem) -> cl_int;
  function clGetSupportedImageFormats (line 530) | pub fn clGetSupportedImageFormats(context: cl_context,
  function clGetMemObjectInfo (line 536) | pub fn clGetMemObjectInfo(memobj: cl_mem,
  function clGetImageInfo (line 541) | pub fn clGetImageInfo(image: cl_mem,
  function clSetMemObjectDestructorCallback (line 546) | pub fn clSetMemObjectDestructorCallback(memobj: cl_mem,
  function clCreateSampler (line 551) | pub fn clCreateSampler(context: cl_context,
  function clRetainSampler (line 556) | pub fn clRetainSampler(sampler: cl_sampler) -> cl_int;
  function clReleaseSampler (line 557) | pub fn clReleaseSampler(sampler: cl_sampler) ->cl_int;
  function clGetSamplerInfo (line 558) | pub fn clGetSamplerInfo(sampler: cl_sampler,
  function clCreateProgramWithSource (line 565) | pub fn clCreateProgramWithSource(context: cl_context,
  function clCreateProgramWithBinary (line 570) | pub fn clCreateProgramWithBinary(context: cl_context,
  function clRetainProgram (line 577) | pub fn clRetainProgram(program: cl_program) -> cl_int;
  function clReleaseProgram (line 578) | pub fn clReleaseProgram(program: cl_program) -> cl_int;
  function clBuildProgram (line 579) | pub fn clBuildProgram(program: cl_program,
  function clUnloadCompiler (line 585) | pub fn clUnloadCompiler() -> cl_int;
  function clGetProgramInfo (line 586) | pub fn clGetProgramInfo(program: cl_program,
  function clGetProgramBuildInfo (line 591) | pub fn clGetProgramBuildInfo(program: cl_program,
  function clCreateKernel (line 599) | pub fn clCreateKernel(program: cl_program,
  function clCreateKernelsInProgram (line 602) | pub fn clCreateKernelsInProgram(program: cl_program,
  function clRetainKernel (line 606) | pub fn clRetainKernel(kernel: cl_kernel) -> cl_int;
  function clReleaseKernel (line 607) | pub fn clReleaseKernel(kernel: cl_kernel) -> cl_int;
  function clSetKernelArg (line 608) | pub fn clSetKernelArg(kernel: cl_kernel,
  function clGetKernelInfo (line 612) | pub fn clGetKernelInfo(kernel: cl_kernel,
  function clGetKernelWorkGroupInfo (line 617) | pub fn clGetKernelWorkGroupInfo(kernel: cl_kernel,
  function clWaitForEvents (line 625) | pub fn clWaitForEvents(num_events: cl_uint,
  function clGetEventInfo (line 627) | pub fn clGetEventInfo(event: cl_event,
  function clCreateUserEvent (line 632) | pub fn clCreateUserEvent(context: cl_context,
  function clRetainEvent (line 634) | pub fn clRetainEvent(event: cl_event) -> cl_int;
  function clReleaseEvent (line 635) | pub fn clReleaseEvent(event: cl_event) -> cl_int;
  function clSetUserEventStatus (line 636) | pub fn clSetUserEventStatus(event: cl_event,
  function clSetEventCallback (line 638) | pub fn clSetEventCallback(event: cl_event,
  function clGetEventProfilingInfo (line 644) | pub fn clGetEventProfilingInfo(event: cl_event,
  function clFlush (line 651) | pub fn clFlush(command_queue: cl_command_queue) -> cl_int;
  function clFinish (line 652) | pub fn clFinish(command_queue: cl_command_queue) -> cl_int;
  function clEnqueueReadBuffer (line 655) | pub fn clEnqueueReadBuffer(command_queue: cl_command_queue,
  function clEnqueueReadBufferRect (line 664) | pub fn clEnqueueReadBufferRect(command_queue: cl_command_queue,
  function clEnqueueWriteBuffer (line 678) | pub fn clEnqueueWriteBuffer(command_queue: cl_command_queue,
  function clEnqueueWriteBufferRect (line 687) | pub fn clEnqueueWriteBufferRect(command_queue: cl_command_queue,
  function clEnqueueCopyBuffer (line 700) | pub fn clEnqueueCopyBuffer(command_queue: cl_command_queue,
  function clEnqueueCopyBufferRect (line 709) | pub fn clEnqueueCopyBufferRect(command_queue: cl_command_queue,
  function clEnqueueReadImage (line 722) | pub fn clEnqueueReadImage(command_queue: cl_command_queue,
  function clEnqueueWriteImage (line 733) | pub fn clEnqueueWriteImage(command_queue: cl_command_queue,
  function clEnqueueCopyImage (line 744) | pub fn clEnqueueCopyImage(command_queue: cl_command_queue,
  function clEnqueueCopyImageToBuffer (line 753) | pub fn clEnqueueCopyImageToBuffer(command_queue: cl_command_queue,
  function clEnqueueCopyBufferToImage (line 762) | pub fn clEnqueueCopyBufferToImage(command_queue: cl_command_queue,
  function clEnqueueMapBuffer (line 771) | pub fn clEnqueueMapBuffer(command_queue: cl_command_queue,
  function clEnqueueMapImage (line 781) | pub fn clEnqueueMapImage(command_queue: cl_command_queue,
  function clEnqueueUnmapMemObject (line 793) | pub fn clEnqueueUnmapMemObject(command_queue: cl_command_queue,
  function clEnqueueNDRangeKernel (line 799) | pub fn clEnqueueNDRangeKernel(command_queue: cl_command_queue,
  function clEnqueueTask (line 808) | pub fn clEnqueueTask(command_queue: cl_command_queue,
  function clEnqueueNativeKernel (line 813) | pub fn clEnqueueNativeKernel(command_queue: cl_command_queue,
  function clEnqueueMarker (line 823) | pub fn clEnqueueMarker(command_queue: cl_command_queue,
  function clEnqueueWaitForEvents (line 825) | pub fn clEnqueueWaitForEvents(command_queue: cl_command_queue,
  function clEnqueueBarrier (line 828) | pub fn clEnqueueBarrier(command_queue: cl_command_queue) -> cl_int;
  function clGetExtensionFunctionAddress (line 837) | pub fn clGetExtensionFunctionAddress(func_name: *const libc::c_char) -> ...

FILE: src/error.rs
  function error_str (line 6) | fn error_str(status_code: cl_int) -> String {
  function check (line 63) | pub fn check(status: cl_int, message: &str) {

FILE: src/ext.rs
  type cl_device_partition_property_ext (line 200) | pub type cl_device_partition_property_ext = cl_ulong;
  type cl_image_pitch_info_qcom (line 237) | pub type cl_image_pitch_info_qcom = cl_uint;
  type cl_mem_ext_host_ptr (line 238) | pub struct cl_mem_ext_host_ptr {
  type cl_mem_ion_host_ptr (line 269) | struct cl_mem_ion_host_ptr {

FILE: src/hl.rs
  type DeviceType (line 20) | pub enum DeviceType {
  function convert_device_type (line 24) | fn convert_device_type(device: DeviceType) -> cl_device_type {
  type Platform (line 31) | pub struct Platform {
    method get_devices_internal (line 36) | fn get_devices_internal(&self, dtype: cl_device_type) -> Vec<Device>
    method get_devices (line 55) | pub fn get_devices(&self) -> Vec<Device>
    method get_devices_by_types (line 60) | pub fn get_devices_by_types(&self, types: &[DeviceType]) -> Vec<Device>
    method profile_info (line 70) | fn profile_info(&self, name: cl_platform_info) -> String
    method get_id (line 96) | pub fn get_id(&self) -> cl_platform_id {
    method name (line 100) | pub fn name(&self) -> String
    method version (line 105) | pub fn version(&self) -> String
    method profile (line 110) | pub fn profile(&self) -> String
    method vendor (line 115) | pub fn vendor(&self) -> String
    method extensions (line 120) | pub fn extensions(&self) -> String
    method from_platform_id (line 125) | pub unsafe fn from_platform_id(id: cl_platform_id) -> Platform {
  function get_platforms (line 135) | pub fn get_platforms() -> Vec<Platform>
  function create_context_with_properties (line 162) | pub fn create_context_with_properties(dev: &[Device], prop: &[cl_context...
  type Device (line 185) | pub struct Device {
    method profile_info (line 193) | fn profile_info(&self, name: cl_device_info) -> String
    method name (line 220) | pub fn name(&self) -> String
    method vendor (line 224) | pub fn vendor(&self) -> String
    method profile (line 228) | pub fn profile(&self) -> String
    method device_type (line 232) | pub fn device_type(&self) -> String
    method compute_units (line 237) | pub fn compute_units(&self) -> usize {
    method create_context (line 252) | pub fn create_context(&self) -> Context
  type Context (line 274) | pub struct Context {
    method create_buffer (line 282) | pub fn create_buffer<T>(&self, size: usize, flags: cl_mem_flags) -> CL...
    method create_buffer_from (line 300) | pub fn create_buffer_from<T, U, IN: Put<T, U>>(&self, create: IN, flag...
    method create_command_queue (line 316) | pub fn create_command_queue(&self, device: &Device) -> CommandQueue
    method create_program_from_source (line 335) | pub fn create_program_from_source(&self, src: &str) -> Program
    method create_program_from_binary (line 354) | pub fn create_program_from_binary(&self, bin: &str, device: &Device) -...
  method drop (line 376) | fn drop(&mut self) {
  type CommandQueue (line 404) | pub struct CommandQueue {
    method enqueue_kernel (line 414) | pub fn enqueue_kernel<I: KernelIndex, E: EventList>(&self, k: &Kernel,...
    method enqueue_async_kernel (line 443) | pub fn enqueue_async_kernel<I: KernelIndex, E: EventList>(&self, k: &K...
    method get (line 469) | pub fn get<T, U, B: Buffer<T>, G: Get<B, U>, E: EventList>(&self, buf:...
    method write (line 490) | pub fn write<U: Write, T, E: EventList, B: Buffer<T>>(&self, mem: &B, ...
    method write_async (line 511) | pub fn write_async<U: Write, T, E: EventList, B: Buffer<T>>(&self, mem...
    method read (line 535) | pub fn read<T, U: Read, E: EventList, B: Buffer<T>>(&self, mem: &B, re...
  method drop (line 559) | fn drop(&mut self) {
  type Program (line 573) | pub struct Program
    method build (line 592) | pub fn build(&self, device: &Device) -> Result<String, String>
    method create_kernel (line 630) | pub fn create_kernel(&self, name: &str) -> Kernel {
  method drop (line 580) | fn drop(&mut self) {
  type Kernel (line 635) | pub struct Kernel {
    method set_arg (line 649) | pub fn set_arg<T: KernelArg>(&self, i: usize, x: &T)
  method drop (line 641) | fn drop(&mut self) {
  function create_kernel (line 655) | pub fn create_kernel(program: &Program, kernel: & str) -> Kernel
  type KernelArg (line 670) | pub trait KernelArg {
    method get_value (line 384) | fn get_value(&self) -> (libc::size_t, *const libc::c_void)
    method get_value (line 394) | fn get_value(&self) -> (libc::size_t, *const libc::c_void)
    method get_value (line 671) | fn get_value(&self) -> (libc::size_t, *const libc::c_void);
    method get_value (line 695) | fn get_value(&self) -> (libc::size_t, *const libc::c_void) {
    method get_value (line 702) | fn get_value(&self) -> (libc::size_t, *const libc::c_void) {
  function set_kernel_arg (line 708) | pub fn set_kernel_arg<T: KernelArg>(kernel: & Kernel,
  type Event (line 724) | pub struct Event
    method get_time (line 730) | fn get_time(&self, param: cl_uint) -> u64
    method queue_time (line 745) | pub fn queue_time(&self) -> u64
    method submit_time (line 750) | pub fn submit_time(&self) -> u64
    method start_time (line 755) | pub fn start_time(&self) -> u64
    method end_time (line 760) | pub fn end_time(&self) -> u64
  method drop (line 768) | fn drop(&mut self) {
  type EventList (line 775) | pub trait EventList {
    method as_event_list (line 776) | fn as_event_list<T, F: FnOnce(*const cl_event, cl_uint) -> T>(&self, F...
    method wait (line 778) | fn wait(&self) {
    method as_event_list (line 789) | fn as_event_list<T, F>(&self, f: F) -> T
    method as_event_list (line 797) | fn as_event_list<T, F>(&self, f: F) -> T
    method as_event_list (line 805) | fn as_event_list<T2, F>(&self, f: F) -> T2
    method as_event_list (line 816) | fn as_event_list<T, F>(&self, f: F) -> T
    method as_event_list (line 830) | fn as_event_list<T, F>(&self, f: F) -> T
  type KernelIndex (line 838) | pub trait KernelIndex
    method num_dimensions (line 840) | fn num_dimensions(dummy_self: Option<Self>) -> cl_uint where Self: Sized;
    method get_ptr (line 841) | fn get_ptr(&self) -> *const libc::size_t;
    method num_dimensions (line 846) | fn num_dimensions(_: Option<isize>) -> cl_uint { 1 }
    method get_ptr (line 848) | fn get_ptr(&self) -> *const libc::size_t
    method num_dimensions (line 855) | fn num_dimensions(_: Option<(isize, isize)>) -> cl_uint { 2 }
    method get_ptr (line 857) | fn get_ptr(&self) -> *const libc::size_t {
    method num_dimensions (line 864) | fn num_dimensions(_: Option<(isize, isize, isize)>) -> cl_uint { 3 }
    method get_ptr (line 866) | fn get_ptr(&self) -> *const libc::size_t {
    method num_dimensions (line 873) | fn num_dimensions(_: Option<usize>) -> cl_uint { 1 }
    method get_ptr (line 875) | fn get_ptr(&self) -> *const libc::size_t {
    method num_dimensions (line 882) | fn num_dimensions(_: Option<(usize, usize)>) -> cl_uint { 2 }
    method get_ptr (line 884) | fn get_ptr(&self) -> *const libc::size_t {
    method num_dimensions (line 891) | fn num_dimensions(_: Option<(usize, usize, usize)>) -> cl_uint { 3 }
    method get_ptr (line 893) | fn get_ptr(&self) -> *const libc::size_t {

FILE: src/mem.rs
  type Buffer (line 15) | pub trait Buffer<T> {
    method id_ptr (line 16) | unsafe fn id_ptr(&self) -> *const cl_mem;
    method id (line 18) | fn id(&self) -> cl_mem {
    method byte_len (line 24) | fn byte_len(&self) -> size_t
    method len (line 39) | fn len(&self) -> usize { self.byte_len() as usize / mem::size_of::<T>() }
  type CLBuffer (line 42) | pub struct CLBuffer<T> {
  method drop (line 48) | fn drop(&mut self) {
  function id_ptr (line 56) | unsafe fn id_ptr(&self) -> *const cl_mem
  method get_value (line 63) | fn get_value(&self) -> (size_t, *const c_void)
  type Put (line 80) | pub trait Put<T, B> {
    method put (line 81) | fn put<F>(&self, F) -> B
  type Get (line 85) | pub trait Get<B, T> {
    method get (line 86) | fn get<F: FnOnce(size_t, *mut c_void, size_t)>(mem: &B, F) -> Self;
  type Write (line 89) | pub trait Write {
    method write (line 90) | fn write<F: FnOnce(size_t, *const c_void, size_t)>(&self, F);
    method write (line 150) | fn write<F>(&self, f: F)
  type Read (line 93) | pub trait Read {
    method read (line 94) | fn read<F: FnOnce(size_t, *mut c_void, size_t)>(&mut self, F);
    method read (line 159) | fn read<F>(&mut self, f: F)
  function put (line 99) | fn put<F>(&self, f: F) -> CLBuffer<T>
  function put (line 112) | fn put<F>(&self, f: F) -> CLBuffer<T>
  function put (line 124) | fn put<F>(&self, f: F) -> CLBuffer<T>
  function get (line 136) | fn get<F>(mem: &CLBuffer<T>, f: F) -> Vec<T>

FILE: src/util.rs
  function create_compute_context (line 5) | pub fn create_compute_context() -> Result<(Device, Context, CommandQueue...
  type PreferedType (line 24) | pub enum PreferedType {
  function create_compute_context_prefer (line 34) | pub fn create_compute_context_prefer(cltype: PreferedType) -> Result<(De...

FILE: tests/test.rs
  function test_all_platforms_devices (line 23) | pub fn test_all_platforms_devices<F>(test: &mut F)
  function read_write (line 41) | fn read_write<W: Write, R: Read>(src: &W, dst: &mut R)
  function read_write_slice (line 86) | fn read_write_slice()
  function read_write_int (line 95) | fn read_write_int()
  function read_write_uint (line 104) | fn read_write_uint()
  function read_write_f32 (line 113) | fn read_write_f32()
  function read_write_f64 (line 122) | fn read_write_f64()
  function program_build (line 139) | fn program_build() {
  function simple_kernel (line 150) | fn simple_kernel() {
  function add_k (line 172) | fn add_k() {
  function simple_kernel_index (line 197) | fn simple_kernel_index() {
  function chain_kernel_event (line 221) | fn chain_kernel_event() {
  function chain_kernel_event_list (line 248) | fn chain_kernel_event_list() {
  function kernel_2d (line 289) | fn kernel_2d()
  function memory_read_write (line 324) | fn memory_read_write()
  function memory_read_vec (line 340) | fn memory_read_vec()
  function memory_read_owned (line 352) | fn memory_read_owned()
  function memory_read_owned_clone (line 363) | fn memory_read_owned_clone()
  function event_get_times (line 374) | fn event_get_times() {
  function put_get_2d (line 407) | fn put_get_2d()
  function read_write_2d (line 424) | fn read_write_2d()
  function kernel_2d (line 447) | fn kernel_2d()
  function put_get_3d (line 484) | fn put_get_3d()
  function read_write_3d (line 503) | fn read_write_3d()
  function kernel_3d (line 528) | fn kernel_3d()
  function try_load_all_extensions (line 575) | fn try_load_all_extensions() {
  function clstatus_str (line 616) | fn clstatus_str() {
Condensed preview — 20 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (145K chars).
[
  {
    "path": ".gitignore",
    "chars": 77,
    "preview": "*~\n*.so\n*.dylib\n*.dSYM\nopencl-test\ntarget/\n.rust\nbin/\ndoc/\nCargo.lock\nbuild/\n"
  },
  {
    "path": ".travis.yml",
    "chars": 412,
    "preview": "language: rust\nrust: nightly\n\nenv:\n  global:\n    - secure: TUA5IHO5hwaQvgA1gAvslQ4QWhHEym5bFmmm7nAKHVIxRDchpCmjaLPmu3Dir"
  },
  {
    "path": "COPYRIGHT",
    "chars": 450,
    "preview": "rust-opencl - OpenCL Binding and Higher Level Wrapper for Rust.\nCopyright (C) 2013 - The rust-opencl Developers\n\nLicense"
  },
  {
    "path": "Cargo.toml",
    "chars": 807,
    "preview": "[package]\nname = \"opencl\"\nversion = \"0.3.0-dev\"\nauthors = [ \"Colin Sherratt <colin.sherratt@gmail.com>\",\n            \"Er"
  },
  {
    "path": "LICENSE-APACHE",
    "chars": 10847,
    "preview": "                              Apache License\n                        Version 2.0, January 2004\n                     http"
  },
  {
    "path": "LICENSE-MIT",
    "chars": 1071,
    "preview": "MIT License\nhttp://opensource.org/licenses/MIT\n\nPermission is hereby granted, free of charge, to any\nperson obtaining a "
  },
  {
    "path": "Makefile",
    "chars": 895,
    "preview": "\nifndef RUSTC\n\tRUSTC = rustc\nendif\n\nifndef TARGET_DIR\n\tTARGET_DIR = target/\nendif\n\nRUSTC_OPTS = -g -L $(TARGET_DIR) --ou"
  },
  {
    "path": "examples/demo/demo.ocl",
    "chars": 143,
    "preview": "__kernel void vector_add(__global const long *A, __global const long *B, __global long *C) {\n\tint i = get_global_id(0);\n"
  },
  {
    "path": "examples/demo/main.rs",
    "chars": 1624,
    "preview": "extern crate opencl;\n\nuse opencl::mem::CLBuffer;\nuse std::fmt;\n\nfn main()\n{\n    let ker = include_str!(\"demo.ocl\");\n    "
  },
  {
    "path": "examples/platform/main.rs",
    "chars": 740,
    "preview": "extern crate opencl;\n\nuse opencl::hl;\n\nfn main() {\n    for platform in hl::get_platforms().iter() {\n        println!(\"Pl"
  },
  {
    "path": "src/OpenCL/error.rs",
    "chars": 2917,
    "preview": "//! Error handling utilities.\n\nuse CL::*;\nuse std::fmt::{Show, Formatter, Result};\n\nimpl Show for CLStatus {\n    fn fmt("
  },
  {
    "path": "src/array.rs",
    "chars": 6393,
    "preview": "//! Two- and three-dimensional array support.\n\nuse cl::*;\nuse cl::ll::*;\nuse mem::*;\nuse std::marker::PhantomData;\nuse s"
  },
  {
    "path": "src/cl.rs",
    "chars": 44923,
    "preview": "#![allow(non_camel_case_types, dead_code)]\n\nextern crate std;\n\nuse libc;\nuse std::fmt;\n\n/* Opaque types */\npub type cl_p"
  },
  {
    "path": "src/error.rs",
    "chars": 3300,
    "preview": "//! Error handling utilities.\n\nuse cl::{CLStatus, cl_int};\nuse cl::CLStatus::CL_SUCCESS;\n\nfn error_str(status_code: cl_i"
  },
  {
    "path": "src/ext.rs",
    "chars": 12851,
    "preview": "#![allow(unused,\n         unused_attributes,\n         non_camel_case_types,\n         non_snake_case)]\n\n/// All of the ex"
  },
  {
    "path": "src/hl.rs",
    "chars": 25729,
    "preview": "//! A higher level API.\n\nuse libc;\nuse std::ffi::CString;\nuse std::iter::repeat;\nuse std::marker::PhantomData;\nuse std::"
  },
  {
    "path": "src/lib.rs",
    "chars": 589,
    "preview": "#![allow(improper_ctypes)]\n#![allow(missing_copy_implementations)]\n#![allow(non_upper_case_globals)]\n\n#![feature(static_"
  },
  {
    "path": "src/mem.rs",
    "chars": 6133,
    "preview": "//! High level buffer management.\n\nuse libc::{size_t, c_void};\nuse std::marker::{PhantomData};\nuse std::mem;\nuse std::pt"
  },
  {
    "path": "src/util.rs",
    "chars": 1699,
    "preview": "//! Utility functions\n\nuse hl::*;\n\npub fn create_compute_context() -> Result<(Device, Context, CommandQueue), &'static s"
  },
  {
    "path": "tests/test.rs",
    "chars": 18669,
    "preview": "#![feature(slice_bytes)]\n\n#[macro_use]\nextern crate log;\n\nextern crate opencl;\n\nuse opencl::hl::*;\n\nmacro_rules! expect "
  }
]

About this extraction

This page contains the full source code of the luqmana/rust-opencl GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 20 files (137.0 KB), approximately 33.2k tokens, and a symbol index with 306 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!