Skip to content

Add synchronous and asynchronous events#6

Open
szymon-zadworny wants to merge 28 commits into
oneapi-src:mainfrom
szymon-zadworny:event
Open

Add synchronous and asynchronous events#6
szymon-zadworny wants to merge 28 commits into
oneapi-src:mainfrom
szymon-zadworny:event

Conversation

@szymon-zadworny

@szymon-zadworny szymon-zadworny commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

This PR adds:

  • The Event class bindings
  • Synchronization methods:
    • through synchronous .wait() for Queues and Events
    • through asynchronous Futures and .await for Events
    • through barriers (which return an Event) for Queues
  • memset bindings
  • event dependencies
  • examples showcasing synchronous and asynchronous waiting

Breaking change: queues are now in-order by default.

This PR also finalizes the Buffer safety model - safe Buffers are initialized by default and need to be waited/awaited. You can still create uninitialized Buffers through unsafe uninit methods.

Synchronous waiting:

fn main() {
    let mut queue = Queue::new();
    let mut buffer = queue.alloc_shared::<u32>(10).wait();
}

Asynchronous waiting:

#[tokio::main]
async fn main() {
    let mut queue = Queue::new();
    let mut buffer = queue.alloc_shared::<u32>(10).await;
}

Note: tokio was used as a dev dependency for the async.rs example but the actual Futures are executor-agnostic.

This PR requires the following SYCL extensions for the asynchronous execution implementation:

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces SYCL Event bindings and queue/event synchronization primitives in oneapi-rs, including blocking waits (.wait()), async waits (.await via IntoFuture), barriers returning events, and USM memset plus dependency wiring. It also updates the buffer safety model so “safe” allocations are zero-initialized via an enqueued operation that must be waited/awaited before use.

Changes:

  • Add Event wrapper + event info queries + async EventFuture implementation.
  • Add queue-side synchronization APIs (wait, barrier(_with_deps)) and USM memset(_with_deps) that return Event.
  • Introduce EnqueuedBuffer/BufferFuture so safe host/shared allocations enqueue initialization and require wait/await.

Reviewed changes

Copilot reviewed 20 out of 21 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
oneapi-rs/src/usm.rs Makes USM allocator own a cloned Queue so buffers can outlive the original queue reference.
oneapi-rs/src/queue.rs Adds immediate queue construction, USM memset + deps, barriers + deps, and blocking queue wait; adds zero-initializing alloc APIs returning EnqueuedBuffer.
oneapi-rs/src/lib.rs Exposes new event module publicly.
oneapi-rs/src/info/event-info.rs Adds EventInfo trait + CommandExecutionStatus query binding.
oneapi-rs/src/info.rs Wires info::event module and re-exports EventCommandStatus.
oneapi-rs/src/event.rs Implements Event wrapper, cloning, blocking wait, event info, and async EventFuture/IntoFuture.
oneapi-rs/src/buffer.rs Adds EnqueuedBuffer + BufferFuture so safe allocations are initialized asynchronously and require wait/await.
oneapi-rs/examples/async.rs New example demonstrating async .await on an enqueued allocation.
oneapi-rs/examples/alloc.rs Updates allocation example to use .wait() on safe initialization.
oneapi-rs/Cargo.toml Adds bytemuck + pin-project deps and tokio as a dev-dependency for the async example.
oneapi-rs-sys/src/types-sys.rs Adds opaque Waker wrapper and new Event/EventPtr/EventCommandStatus types for cxx bridging.
oneapi-rs-sys/src/queue.cpp Adds in-order/immediate queue constructors; adds memset, barrier, and wait shims returning Event.
oneapi-rs-sys/src/queue-sys.rs Extends cxx bridge for queue to include immediate queue, cloning, memset/barrier/wait, and EventPtr plumbing.
oneapi-rs-sys/src/lib.rs Exposes new event sys module.
oneapi-rs-sys/src/event.cpp Adds Event wait/clone/info and callback registration using host_task to wake a Rust waker.
oneapi-rs-sys/src/event-sys.rs Adds cxx bridge for Event APIs and Rust-side wake trampoline.
oneapi-rs-sys/include/types.hpp Adds using Event = sycl::event;.
oneapi-rs-sys/include/queue.hpp Declares new queue shims (immediate queue, clone, memset, barrier, wait) returning/using Event.
oneapi-rs-sys/include/event.hpp Declares event shims and EventCommandStatus API surface.
oneapi-rs-sys/build.rs Registers new event bridge + C++ source/header in the build.
Cargo.lock Locks new dependency graph for bytemuck, pin-project, and tokio.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread oneapi-rs/src/event.rs
Comment thread oneapi-rs/src/buffer.rs
Comment thread oneapi-rs-sys/src/queue.cpp Outdated
Comment thread oneapi-rs-sys/src/queue.cpp Outdated
Comment thread oneapi-rs-sys/src/event.cpp
Comment thread oneapi-rs-sys/src/queue.cpp

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 21 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

oneapi-rs-sys/src/queue.cpp:49

  • e.ptr.release() relinquishes ownership of the heap-allocated sycl::event without deleting it, so this loop leaks every dependency event passed to barrier(...). There’s no need to release() here; match the memset(...) implementation and move/copy the event value instead.
std::unique_ptr<Event> barrier(std::unique_ptr<Queue> & queue, rust::Vec<EventPtr> dep_events) {
  std::vector<sycl::event> deps;
  for (auto&& e: dep_events)
    deps.push_back(std::move(*e.ptr.release()));
  return std::make_unique<Event>(queue->ext_oneapi_submit_barrier(deps));

Comment thread oneapi-rs/src/event.rs
Comment thread oneapi-rs/src/event.rs
Comment thread oneapi-rs/src/event.rs
Comment on lines +56 to +60
if self.set_callback == false {
let this = self.project();
*this.set_callback = true;
let waker = Box::new(cx.waker().clone().into());
ffi::register_callback(&mut this.queue.0, &this.event.0, waker);
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants