Skip to content

Commit 66c8ace

Browse files
committed
[SYCL][Doc] Add spec to record an event
Add a proposed extension specification which allows an application to reuse the same event object in multiple command submissions, rather than creating a new event for each submission.
1 parent 753ab35 commit 66c8ace

File tree

1 file changed

+213
-0
lines changed

1 file changed

+213
-0
lines changed
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
= sycl_ext_oneapi_record_event
2+
3+
:source-highlighter: coderay
4+
:coderay-linenums-mode: table
5+
6+
// This section needs to be after the document title.
7+
:doctype: book
8+
:toc2:
9+
:toc: left
10+
:encoding: utf-8
11+
:lang: en
12+
:dpcpp: pass:[DPC++]
13+
:endnote: —{nbsp}end{nbsp}note
14+
15+
// Set the default source code type in this document to C++,
16+
// for syntax highlighting purposes. This is needed because
17+
// docbook uses c++ and html5 uses cpp.
18+
:language: {basebackend@docbook:c++:cpp}
19+
20+
21+
== Notice
22+
23+
[%hardbreaks]
24+
Copyright (C) 2025 Intel Corporation. All rights reserved.
25+
26+
Khronos(R) is a registered trademark and SYCL(TM) and SPIR(TM) are trademarks
27+
of The Khronos Group Inc. OpenCL(TM) is a trademark of Apple Inc. used by
28+
permission by Khronos.
29+
30+
31+
== Contact
32+
33+
To report problems with this extension, please open a new issue at:
34+
35+
https://github.com/intel/llvm/issues
36+
37+
38+
== Dependencies
39+
40+
This extension is written against the SYCL 2020 revision 10 specification.
41+
All references below to the "core SYCL specification" or to section numbers in
42+
the SYCL specification refer to that revision.
43+
44+
This extension also depends on the following other SYCL extensions:
45+
46+
* link:../experimental/sycl_ext_oneapi_enqueue_functions.asciidoc[
47+
sycl_ext_oneapi_enqueue_functions]
48+
49+
50+
== Status
51+
52+
This is a proposed extension specification, intended to gather community
53+
feedback.
54+
Interfaces defined in this specification may not be implemented yet or may be in
55+
a preliminary state.
56+
The specification itself may also change in incompatible ways before it is
57+
finalized.
58+
*Shipping software products should not rely on APIs defined in this
59+
specification.*
60+
61+
62+
== Overview
63+
64+
This extension adds the ability to reuse the same `event` object in multiple
65+
command submissions, rather than creating a new event for each submission.
66+
This pattern may perform better on some implementations because fewer event
67+
objects need to be created and destroyed.
68+
The pattern may also be more familiar to users porting CUDA code to SYCL.
69+
70+
71+
== Specification
72+
73+
=== Feature test macro
74+
75+
This extension provides a feature-test macro as described in the core SYCL
76+
specification. An implementation supporting this extension must predefine the
77+
macro `SYCL_EXT_ONEAPI_RECORD_EVENT` to one of the values defined in the table
78+
below. Applications can test for the existence of this macro to determine if
79+
the implementation supports this feature, or applications can test the macro's
80+
value to determine which of the extension's features the implementation
81+
supports.
82+
83+
[%header,cols="1,5"]
84+
|===
85+
|Value
86+
|Description
87+
88+
|1
89+
|The APIs of this experimental extension are not versioned, so the
90+
feature-test macro always has this value.
91+
|===
92+
93+
=== New kernel launch property
94+
95+
This extension adds a new kernel launch property:
96+
97+
[source,c++]
98+
----
99+
namespace sycl::ext::oneapi::experimental {
100+
101+
struct record_event {
102+
record_event(event* evt); (1)
103+
};
104+
using record_event_key = record_event;
105+
106+
} // namespace sycl::ext::oneapi::experimental
107+
----
108+
109+
This property may be passed as a launch property to the following command
110+
submission functions from
111+
link:../experimental/sycl_ext_oneapi_enqueue_functions.asciidoc[
112+
sycl_ext_oneapi_enqueue_functions]:
113+
114+
* The `submit` overload that takes parameters of type `queue` and `Properties`.
115+
* The `single_task` overloads that take parameters of type `queue` and
116+
`Properties`.
117+
* The `parallel_for` overloads that take parameters of type `queue` and
118+
`launch_config`.
119+
* The `nd_launch` overloads that take parameters of type `queue` and
120+
`launch_config`.
121+
* The `memcpy` overload that takes parameters of type `queue` and `Properties`.
122+
* The `copy` overload that takes parameters of type `queue` and `Properties`.
123+
* The `memset` overload that takes parameters of type `queue` and `Properties`.
124+
* The `fill` overload that takes parameters of type `queue` and `Properties`.
125+
* The `prefetch` overload that takes parameters of type `queue` and
126+
`Properties`.
127+
* The `mem_advise` overload that takes parameters of type `queue` and
128+
`Properties`.
129+
* The `barrier` overload that takes parameters of type `queue` and `Properties`.
130+
* The `partial_barrier` overload that takes parameters of type `queue` and
131+
`Properties`.
132+
* The `execute_graph` overload that takes parameters of type `queue` and
133+
`Properties`.
134+
135+
_Effects (1)_: Constructs a `record_event` property with a pointer to an `event`
136+
object.
137+
When `evt` is not null, the following happens.
138+
The status of the event is disassociated with any previously submitted command,
139+
and its status is reset to `info::event_command_status::submitted`.
140+
For the `submit` function, this happens when the command group function returns
141+
back to `submit`.
142+
The event is then associated with the newly submitted command.
143+
Assuming the event remains associated with this command, the event's status
144+
changes according to the execution status of that command.
145+
When `evt` is null, the property has no effect on the command submission.
146+
147+
_Remarks:_
148+
149+
* If a recorded event is used as a command dependency for some other command
150+
_C2_ (e.g. via `handler::depends_on`), the dependency is captured at the point
151+
when _C2_ is submitted.
152+
The dependency does _not_ change if the event is subsequently overwritten via
153+
`record_event`.
154+
155+
* If another host thread is blocked in a call to `event::wait` when that same
156+
event is associated with a new command via `record_event`, it is unspecified
157+
whether the call to `event:wait` unblocks.
158+
159+
160+
== Example
161+
162+
[source,c++]
163+
----
164+
#include <sycl/sycl.hpp>
165+
namespace syclex = sycl::ext::oneapi::experimental;
166+
167+
int main() {
168+
sycl::queue q1;
169+
sycl::queue q2;
170+
sycl::event e;
171+
sycl::range r{GLOBAL};
172+
173+
// Launch a command and record an event which tracks its completion.
174+
syclex::launch_config cfg{r, syclex::record_event{&e}};
175+
syclex::parallel_for(q1, cfg, [=](sycl::item<> it) { /* ... */ });
176+
177+
// Launch another command which depends on that event and also
178+
// record completion of this new command using the same event.
179+
syclex::submit(q2, syclex::record_event{&e}, [&](sycl::handler cgh) {
180+
cgh.depends_on(e);
181+
syclex::parallel_for(cgh, r, [=](sycl::item<> it) { /* ... */ });
182+
});
183+
184+
// Wait for both commands to complete.
185+
e.wait();
186+
}
187+
----
188+
189+
190+
== Implementation notes
191+
192+
It is expected that the implementation will often be able to reuse the
193+
underlying backend event object when a SYCL event is passed to `record_event`.
194+
However, there will still be cases when the implementation needs to release the
195+
underlying backend event and create a new one.
196+
For example, this will happen when the existing backend event is from a
197+
different backend or from a different context than the command being submitted.
198+
In these cases, we expect that the implementation will release the backend event
199+
and associate the SYCL event with a new backend event.
200+
201+
202+
== Issues
203+
204+
* Is it possible to implement the behavior specified above regarding
205+
`event::wait` and `record_event`?
206+
What if the implementation needs to release the backend event when another
207+
host thread is blocked in a call to `event:wait`?
208+
Can we guarantee that the call to `event::wait` either remains blocked or
209+
becomes unblocked?
210+
(Either is fine.)
211+
Or, is it possible that this will lead to a crash?
212+
If a crash is possible, we need to weaken the specification to say this
213+
condition is UB.

0 commit comments

Comments
 (0)