Add synchronous and asynchronous events#6
Conversation
There was a problem hiding this comment.
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
Eventwrapper + event info queries + asyncEventFutureimplementation. - Add queue-side synchronization APIs (
wait,barrier(_with_deps)) and USMmemset(_with_deps)that returnEvent. - Introduce
EnqueuedBuffer/BufferFutureso 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.
There was a problem hiding this comment.
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-allocatedsycl::eventwithout deleting it, so this loop leaks every dependency event passed tobarrier(...). There’s no need torelease()here; match thememset(...)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));
| 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]>
This PR adds:
.wait()for Queues and Events.awaitfor EventsBreaking 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:
Asynchronous waiting:
Note:
tokiowas used as a dev dependency for theasync.rsexample but the actual Futures are executor-agnostic.This PR requires the following SYCL extensions for the asynchronous execution implementation:
sycl_ext_intel_queue_immediate_command_listsycl_ext_oneapi_enqueue_barrier