Expand description
§oneAPI-rs
oneAPI-rs is a set of (mostly) safe Rust bindings for SYCL - an open, royalty-free, cross-platform abstraction layer that enables code for heterogeneous and offload processors to be written using modern ISO C++, and provides APIs and abstractions to find devices (CPUs, GPUs, FPGAs …) on which code can be executed, and to manage data resources and code execution on those devices.
§System dependencies
Make sure to install the Intel oneAPI toolkit.
Then source the setvars.sh file:
source <oneapi_install_directory>/setvars.sh§Getting started
§Building the crate
Before building this crate you need to source the setvars.sh file. You can then build it as
usual with cargo:
cargo build --releaseYou must also source setvars.sh before running any SYCL program.
§Hello world
- Create a
Queue. It’s the main entry point to the SYCL API.
let mut queue = Queue::new();- Create an USM buffer for your data.
let mut device_buffer = queue.alloc_device::<f64>(1024).wait();- Build a SYCL kernel.
let kernel = queue
.get_context()
.create_kernel_bundle_from_source(IOTA_SRC)
.build()
.get_kernel("iota");- Launch your kernel.
unsafe {
queue.launch(
NdRange::new([1024], [16]),
&kernel,
(3.14, &mut device_buffer),
)
}
.wait();- Copy your data to the host.
let mut host_buffer = queue.alloc_host::<f64>(1024).wait();
queue.copy(&device_buffer, &mut host_buffer).wait();You can access your host data just like a normal Rust slice.
for e in host_buffer.iter() {
print!("{e} ");
}
println!();§Safety model
- USM allocations are represented by a zero-cost
Buffertype managed through RAII.- Note: Unlike SYCL buffers, oneAPI-rs buffers do not rely on accessors.
- Buffers are zero-initialized by default.
- Buffers can only store types that implement [
bytemuck::Pod]. - Kernel launch is inherently unsafe.
§Asynchronous programming model
Each queue operation returns an Event. You can synchronously
.wait() for it, or asynchronously .await it.
You can also synchronously call Queue::wait() to wait for a
Queue directly. To do the same asynchronously you have to .await an
event returned by Queue::barrier().