lattwood / ocl

OpenCL for Rust

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ocl

OpenCL interfaces for Rust. Makes easy to use the most common features of OpenCL. All interfaces are virtually zero-cost and perform on a par with any C++ libraries.

Interfaces are still unstable. Won't eat your laundry but some of the conventions may change (in hopefully obvious ways).

##Goals

To provide a simple and intuitive way to interact with OpenCL devices with:

  • The full functionality of the OpenCL C ABI
  • An absolute minimum of boilerplate
  • Zero performance overhead (or as close as absolutely possible)

##Platforms

Tested so far only on Linux. Please provide feedback about failures and successes on other platforms.

##Installation

Ensure that an OpenCL library is installed for your preferred platform and that clinfo or some other diagnostic command will run.

Add:

[dependencies]
ocl = "0.2"

to your project's Cargo.toml.

##Example From 'examples/basics.rs':

use ocl::{Context, BuildConfig, Envoy, SimpleDims, ProQue};
extern crate ocl;

const PRINT_DEBUG: bool = true;

fn main() {
	// Set our data set size and coefficent to arbitrary values:
	let data_set_size = 900000;
	let coeff = 5432.1;

	// Create a context with the first avaliable platform and default device type:
	let ocl_cxt = Context::new(None, None).unwrap();

	// Create a program/queue with the first available device: 
	let mut ocl_pq = ProQue::new(&ocl_cxt, None);

	// Declare our kernel source code:
	let kernel_src = r#"
		__kernel void multiply_by_scalar(
					__global float const* const src,
					__private float const coeff,
					__global float* const res)
		{
			uint const idx = get_global_id(0);

			res[idx] = src[idx] * coeff;
		}
	"#;

	// Create a basic build configuration using above source: 
	let build_config = BuildConfig::new().kern_embed(kernel_src);

	// Build with our configuration and check for errors:
	ocl_pq.build(build_config).expect("ocl program build");

	// Set up our work dimensions / data set size:
	let dims = SimpleDims::OneDim(data_set_size);

	// Create an envoy (a local array + a remote buffer) as a data source:
	let source_envoy = Envoy::scrambled(&dims, 0.0f32, 20.0f32, &ocl_pq.queue());

	// Create another empty envoy for results:
	let mut result_envoy = Envoy::new(&dims, 0.0f32, &ocl_pq.queue());

	// Create a kernel with three arguments corresponding to those in the kernel:
	let kernel = ocl_pq.create_kernel("multiply_by_scalar", dims.work_size())
		.arg_env(&source_envoy)
		.arg_scl(coeff)
		.arg_env(&mut result_envoy)
	;

	// Enqueue kernel depending on and creating no events:
	kernel.enqueue(None, None);

	// Read results:
	result_envoy.read_wait();

	// Check results and print the first 20:
	for idx in 0..data_set_size {
		// Check:
		assert_eq!(result_envoy[idx], source_envoy[idx] * coeff);

		// Print:
		if PRINT_DEBUG && (idx < 20) { 
			println!("source_envoy[idx]: {}, coeff: {}, result_envoy[idx]: {}",
			source_envoy[idx], coeff, result_envoy[idx]); 
		}
	}
}

##Upcoming Changes

Envoy will be receiving a major rework and a possible rename. Issue #4.

##Help

If troubleshooting your OpenCL drivers: check that /usr/lib/libOpenCL.so.1 exists. Go ahead and link /usr/lib/libOpenCL.so -> libOpenCL.so.1 just in case it's not already (AMD drivers sometimes don't create this link). Intel and AMD also have OpenCL libraries for your CPU if you're having trouble getting your GPU to work (intel: windows, linux).

Please ask questions and provide feedback by opening an issue.

Lots more details and documentation to come.

About

OpenCL for Rust

License:MIT License


Languages

Language:Rust 99.7%Language:C 0.3%