Skip to content

Commit d82bb30

Browse files
committed
Address editorial feedback from Gordon
1 parent 4e93de3 commit d82bb30

File tree

3 files changed

+102
-39
lines changed

3 files changed

+102
-39
lines changed

sycl/doc/extensions/experimental/sycl_ext_codeplay_enqueue_native_command.asciidoc

Lines changed: 51 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -177,15 +177,15 @@ dependencies are satisfied.
177177
The SYCL command described above completes once all of the native asynchronous
178178
tasks it contains have completed.
179179

180-
The call to `interopCallable` is done by the host thread, users should
181-
therefore not perform blocking or synchronization tasks inside
182-
`interopCallable`, as it will defer the host thread returning to SYCL user
183-
code.
184-
185180
The call to `interopCallable` must not add tasks to backend objects that underly
186181
any other queue, aside from the queue that is associated with this handler,
187182
otherwise, the behavior is undefined.
188183

184+
[_Note:_ The function object `interopCallable` is invoked to enqueue commands to a
185+
native queue or graph and therefore, APIs which block or synchronize could
186+
prolong or interfere with other commands being enqueued to the backend.
187+
_{endnote}_]
188+
189189
=== SYCL-Graph Interaction
190190

191191
This section defines the interaction with the
@@ -202,6 +202,8 @@ that they respect the graph node edges.
202202
==== Interop Handle Class Modifications
203203

204204
```c++
205+
// Alias is for editorial brevity in the ext_codeplay_get_native_graph
206+
// definition, and is non-normative.
205207
using graph = ext::oneapi::experimental::command_graph<
206208
ext::oneapi::experimental::graph_state::executable>;
207209

@@ -213,28 +215,6 @@ class interop_handle {
213215
};
214216
```
215217

216-
Table {counter: tableNumber}. Native types for
217-
`template <backend Backend, class T> backend_return_t<Backend, T>` where `T` is
218-
instantiated as `command_graph<graph_state::executable>`.
219-
220-
[cols="2a,a"]
221-
|===
222-
|Backend|Native graph type
223-
224-
| `backend::opencl`
225-
| `cl_command_buffer_khr`
226-
227-
| `backend::ext_oneapi_level_zero`
228-
| `ze_command_list_handle_t`
229-
230-
| `backend::ext_oneapi_cuda`
231-
| `CUGraph`
232-
233-
| `backend::ext_oneapi_hip`
234-
| `hipGraph_t`
235-
236-
|===
237-
238218
==== New Interop Handle Member Functions
239219

240220
Table {counter: tableNumber}. Additional member functions of the `sycl::interop_handle` class.
@@ -248,11 +228,16 @@ Table {counter: tableNumber}. Additional member functions of the `sycl::interop_
248228
bool interop_handle::ext_codeplay_has_graph() const;
249229
----
250230

251-
| Query if the `interop_handle` object has a native graph object available.
252-
Note that host-task nodes in a `command_graph` will return `false` for this,
253-
as host-task commands are executed by the SYCL runtime rather than the
254-
backend device, so there is no native graph object associated with the
255-
command.
231+
|
232+
_Returns_: True if the `interop_handle object` was constructed and passed to
233+
an enqueue native command function object by `ext_codeplay_enqueue_native_command`,
234+
that was invoked when adding a graph node, either explicitly or implicitly
235+
via graph record.
236+
237+
[_Note:_ that host-task nodes in a `command_graph` will return `false` from this
238+
query, as the host-task callable is invoked during graph execution rather than
239+
graph finalization.
240+
_{endnote}_]
256241

257242
|
258243
[source,c++]
@@ -262,12 +247,42 @@ backend_return_t<Backend, graph>
262247
interop_handle::ext_codeplay_get_native_graph() const;
263248
----
264249

265-
| Return the native graph object associated with the `interop_handle`.
250+
|
251+
_Returns_: The native graph object associated with the `interop_handle`.
252+
253+
_Throws_: An exception with the `errc::invalid` error code if
254+
`ext_codeplay_has_graph()` returns `false`.
255+
256+
|===
257+
258+
== Implementation Notes
259+
260+
When `interop_handle::get_native_queue()` is invoked in a native command
261+
function object on graph finalize, the queue that is returned to the user is an
262+
internal queue created by the SYCL runtime, as there is no user provided queue
263+
at the point of graph finalization. This queue has the same device and context
264+
as the graph was created with. The only valid usage of this queue is to perform
265+
stream capture to a graph for backend APIs that provide this functionality.
266+
267+
Table {counter: tableNumber}. Native types for
268+
`template <backend Backend, class T> backend_return_t<Backend, T>` where `T` is
269+
instantiated as `command_graph<graph_state::executable>`.
270+
271+
[cols="2a,a"]
272+
|===
273+
|Backend|Native Graph Type
274+
275+
| `backend::opencl`
276+
| `cl_command_buffer_khr`
277+
278+
| `backend::ext_oneapi_level_zero`
279+
| `ze_command_list_handle_t`
266280

267-
Exceptions:
281+
| `backend::ext_oneapi_cuda`
282+
| `CUGraph`
268283

269-
* Throws with error code `invalid` if `ext_codeplay_has_graph()` returns
270-
`false`.
284+
| `backend::ext_oneapi_hip`
285+
| `hipGraph_t`
271286

272287
|===
273288

sycl/doc/syclgraph/SYCLGraphUsageGuide.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,57 @@ In this case it may be necessary to first manually trigger the warmup by calling
171171
`Graph.begin_recording(Queue)` to prevent the warmup from being captured in a
172172
graph when recording.
173173
174+
#### ext_codeplay_enqueue_native_command
175+
176+
The SYCL-Graph extension is compatible with the
177+
[ext_codeplay_enqueue_native_command](../extensions/experimental/sycl_ext_codeplay_enqueue_native_command.asciidoc)
178+
extension that can be used to capture asynchronous library commands as graph
179+
nodes. However, existing `ext_codeplay_enqueue_native_command` user code will
180+
need modifications to work correctly for submission to a sycl queue that can be
181+
in either the executable or recording state.
182+
183+
Using the CUDA backend as an example, existing code which uses a
184+
native-command to invoke a library call:
185+
186+
```c++
187+
q.submit([&](sycl::handler &CGH) {
188+
CGH.ext_codeplay_enqueue_native_command([=](sycl::interop_handle IH) {
189+
auto NativeStream = IH.get_native_queue<cuda>();
190+
myNativeLibraryCall(NativeStream);
191+
});
192+
});
193+
```
194+
195+
Can be ported as below to work with SYCL-Graph, where the queue may be in
196+
a recording state. If the code is not ported but the queue is in a recording
197+
state, then asynchronous work in `myNativeLibraryCall` will be scheduled
198+
immediately as part of graph finalize, rather than being added to the graph as
199+
a node, which is unlikely to be the desired user behavior.
200+
201+
```c++
202+
q.submit([&](sycl::handler &CGH) {
203+
CGH.ext_codeplay_enqueue_native_command([=](sycl::interop_handle IH) {
204+
auto NativeStream = h.get_native_queue<cuda>();
205+
if (IH.ext_codeplay_has_graph()) {
206+
auto NativeGraph =
207+
IH.ext_codeplay_get_native_graph<sycl::backend::ext_oneapi_cuda>();
208+
209+
// Start capture stream calls into graph
210+
cuStreamBeginCaptureToGraph(NativeStream, NativeGraph, nullptr,
211+
nullptr, 0,
212+
CU_STREAM_CAPTURE_MODE_GLOBAL);
213+
214+
myNativeLibraryCall(NativeStream);
215+
216+
// Stop capturing stream calls into graph
217+
cuStreamEndCapture(NativeStream, &NativeGraph);
218+
} else {
219+
myNativeLibraryCall(NativeStream);
220+
}
221+
});
222+
});
223+
```
224+
174225
## Code Examples
175226

176227
The examples below demonstrate intended usage of the extension, but may not be

sycl/include/sycl/interop_handle.hpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,6 @@ class interop_handle {
144144
template <backend Backend = backend::opencl>
145145
backend_return_t<Backend, graph> ext_codeplay_get_native_graph() const {
146146
#ifndef __SYCL_DEVICE_ONLY__
147-
// TODO: replace the exception thrown below with the SYCL 2020 exception
148-
// with the error code 'errc::backend_mismatch' when those new exceptions
149-
// are ready to be used.
150147
if (Backend != get_backend())
151148
throw exception(make_error_code(errc::invalid),
152149
"Incorrect backend argument was passed");

0 commit comments

Comments
 (0)