Crate sycl_rs

Crate sycl_rs 

Source
Expand description

§SYCL-rs

SYCL-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

This project was tested on oneAPI Toolkit 2026.1 and requires the Unified Runtime over Level Zero driver version 1.14.37020 or newer. For more detailed information check out the required extensions section.

§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 --release

You must also source setvars.sh before running any SYCL program.

§Hello world


fn main() -> sycl_rs::Result<()> {
    // 1. Create a Queue. It's the main entry point to the SYCL API.
    let mut queue = Queue::new();
    let mut device_array = queue.alloc_device::<f32>(1024)?.wait()?;

    // 3. Build a SYCL kernel.
    let kernel = queue
        .get_context()
        .create_kernel_bundle_from_source(IOTA_SRC)?
        .build()?
        .get_kernel("iota")?;

    // 4. Launch your kernel.
    unsafe {
        queue.launch(
            NdRange::new([1024], [16]),
            &kernel,
            (3.14_f32, &mut device_array),
        )
    }?
    .wait()?;

    let mut host_array = queue.alloc_host::<f32>(1024)?.wait()?;

    // 5. Copy your data to the host.
    queue.copy(&device_array, &mut host_array)?.wait()?;

    // You can access your host data just like a normal Rust slice.
    for e in host_array.iter() {
        print!("{e} ");
    }
    println!();

    Ok(())
}

§Safety model

  • USM allocations are represented by a zero-cost UsmBox type managed through RAII.
    • Note: UsmBox arrays do not rely on accessors, unlike SYCL buffers.
  • UsmBoxes are zero-initialized by default.
  • UsmBoxes can only store types that implement [bytemuck::Pod].
  • Kernel launch is inherently unsafe. In particular, the caller must ensure that every argument has the correct representation, layout, and alignment.

§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().

All basic SYCL wrapper types (Queue, Event, Context, Platform, Device) are thread safe as indicated by the provided Send and Sync trait implementations. However - UsmBoxes are not thread-safe. If you need a thread-safe UsmBox you need to wrap it in an Arc<Mutex<T>>.

§Required extensions

This project requires the following SYCL extensions to work:

The following extensions are also required for async support:

Modules§

context
device
event
info
kernel
platform
prelude
queue
range
usm
usmbox

Type Aliases§

Result
SyclError