diff --git a/sycl/doc/extensions/proposed/sycl_ext_oneapi_graph.asciidoc b/sycl/doc/extensions/proposed/sycl_ext_oneapi_graph.asciidoc index 35e41c73d5483..62d92486e133c 100644 --- a/sycl/doc/extensions/proposed/sycl_ext_oneapi_graph.asciidoc +++ b/sycl/doc/extensions/proposed/sycl_ext_oneapi_graph.asciidoc @@ -163,9 +163,9 @@ for example: [source, c++] ---- -queue.begin_recording(graph); +graph.begin_recording(queue); graph.add(/*command group*/); // Invalid as graph is being recorded to -queue.end_recording(); +graph.end_recording(); ---- == Specification @@ -321,6 +321,13 @@ public: command_graph(const property_list& propList = {}); command_graph finalize(const context& syclContext) const; + bool begin_recording(queue recordingQueue); + bool begin_recording(const std::vector& recordingQueues); + + bool end_recording(); + bool end_recording(queue recordingQueue); + bool end_recording(const std::vector& recordingQueues); + node add(const property_list& propList = {}); template @@ -344,9 +351,6 @@ public: using namespace ext::oneapi::experimental; class queue { public: - bool begin_recording(command_graph& graph); - bool end_recording(); - /* -- graph convenience shortcuts -- */ event graph(command_graph graph); @@ -681,7 +685,120 @@ Exceptions: |=== -Table 8. Member functions of the `command_graph` class (executable graph update). +Table 8. Member functions of the `command_graph` class for queue recording. +[cols="2a,a"] +|=== +|Member function|Description + +| +[source, c++] +---- +using namespace ext::oneapi::experimental; +bool begin_recording(queue recordingQueue) +---- + +|Synchronously changes the state of `recordingQueue` to the +`queue_state::recording` state. + +Parameters: + +* `recordingQueue` - A `sycl::queue` object to change to the + `queue_state::recording` state and start recording commands to the graph + instance. + +Returns: `true` if `recordingQueue` has its state changed from +`queue_state::executing` to `queue_state::recording`, `false` otherwise. + +Exceptions: + +* Throws synchronously with error code `invalid` if `recordingQueue` is + already recording to a different graph. + +| +[source, c++] +---- +using namespace ext::oneapi::experimental; +bool begin_recording(const std::vector& recordingQueues) +---- + +|Synchronously changes the state of each queue in `recordingQueues` to the +`queue_state::recording` state. + +Parameters: + +* `recordingQueues` - List of `sycl::queue` objects to change to the + `queue_state::recording` state and start recording commands to the graph + instance. + +Returns: `true` if any queue in `recordingQueues` has its state changed from +`queue_state::executing` to `queue_state::recording`, `false` otherwise. + +Exceptions: + +* Throws synchronously with error code `invalid` if the any queue in + `recordingQueues` is already recording to a different graph. + +| +[source, c++] +---- +using namespace ext::oneapi::experimental; +bool end_recording() +---- + +|Synchronously finishes recording on all queues that are recording to the +graph and sets their state to `queue_state::executing`. + +Returns: `true` if any queue recording to the graph has its state changed from +`queue_state::recording` to `queue_state::executing`, `false` otherwise. + +| +[source, c++] +---- +using namespace ext::oneapi::experimental; +bool end_recording(queue recordingQueue) +---- + +|Synchronously changes the state of `recordingQueue` to the +`queue_state::executing` state. + +Parameters: + +* `recordingQueue` - A `sycl::queue` object to change to the executing state. + +Returns: `true` if `recordingQueue` has its state changed from +`queue_state::recording` to `queue_state::executing`, `false` otherwise. + +Exceptions: + +* Throws synchronously with error code `invalid` if `recordingQueue` is + recording to a different graph. + +| +[source, c++] +---- +using namespace ext::oneapi::experimental; +bool end_recording(const std::vector& recordingQueues) +---- + +|Synchronously changes the state of each queue in `recordingQueues` to the +`queue_state::executing` state. + +Parameters: + +* `recordingQueues` - List of `sycl::queue` objects to change to the executing + state. + +Returns: `true` if any queue in `recordingQueues` has its state changed from +`queue_state::recording` to `queue_state::executing`, `false` otherwise. + +Exceptions: + +* Throws synchronously with error code `invalid` if any queue in + `recordingQueues` is recording to a different graph. + +|=== + +Table 9. Member functions of the `command_graph` class (executable graph update). [cols="2a,a"] |=== |Member function|Description @@ -727,8 +844,7 @@ put into a mode where command-groups are recorded to a graph rather than submitted immediately for execution. <> are also added to the -`sycl::queue` class with this extension. Two functions for selecting the state -of the queue, and another function for submitting a graph to the queue. +`sycl::queue` class in this extension as queue shortcuts for `handler::graph()`. ==== Queue State @@ -756,7 +872,7 @@ The state of a queue can be queried with `queue::get_info` using template parameter `info::queue::state`. The following entry is added to the {queue-info-table}[queue info table] to define this query: -Table 9. Queue info query +Table 10. Queue info query [cols="2a,a,a"] |=== | Queue Descriptors | Return Type | Description @@ -799,46 +915,11 @@ property and this graph extension. ==== New Queue Member Functions -Table 8. Additional member functions of the `sycl::queue` class. +Table 11. Additional member functions of the `sycl::queue` class. [cols="2a,a"] |=== |Member function|Description -| -[source, c++] ----- -using namespace ext::oneapi::experimental; -bool queue::begin_recording(command_graph& graph) ----- - -|Synchronously changes the state of the queue to the `queue_state::recording` -state. - -Parameters: - -* `graph` - Graph object to start recording commands to. - -Returns: `true` if the queue was previously in the `queue_state::executing` -state, `false` otherwise. - -Exceptions: - -* Throws synchronously with error code `invalid` if the queue is already - recording to a different graph. - -| -[source, c++] ----- -using namespace ext::oneapi::experimental; -bool queue::end_recording() ----- - -|Synchronously changes the state of the queue to the `queue_state::executing` -state. - -Returns: `true` if the queue was previously in the `queue_state::recording` -state, `false` otherwise. - | [source,c++] ---- @@ -874,7 +955,7 @@ containing `handler::depends_on(depEvents)` and `handler::graph(graph)`. ==== New Handler Member Functions -Table 10. Additional member functions of the `sycl::handler` class. +Table 12. Additional member functions of the `sycl::handler` class. [cols="2a,a"] |=== |Member function|Description @@ -912,25 +993,38 @@ The returned value from the `info::queue::state` should be considered immediately stale in multi-threaded usage, as another thread could have preemptively changed the state of the queue. +=== Exception Safety + +In addition to the destruction semantics provided by the SYCL +{crs}[common reference semantics], when a modifiable `command_graph` is +destroyed recording is ended on any queues that are recording to that +graph, equivalent to `this->end_recording()`. + +As a result users don't need to manually wrap queue recording code in a +`try` / `catch` block to reset the state of recording queues on an exception +back to the executing state. Instead, an uncaught exception destroying the +modifiable graph will perform this action, useful in RAII pattern usage. + === Error Handling Errors are reported through exceptions, as usual in the SYCL API. For new APIs, submitting a graph for execution can generate unspecified asynchronous errors, while `command_graph::finalize()` may throw unspecified synchronous exceptions. -Synchronous exception errors codes are defined for both -`queue::begin_recording()` and `command_graph::update()`. +Synchronous exception errors codes are defined for all of +`command_graph::begin_recording()`, `command_graph::end_recording()` and +`command_graph::update()`. When a queue is in recording mode asynchronous exceptions will not be -generated, as no device execution is occuring. Synchronous errors specified as +generated, as no device execution is occurring. Synchronous errors specified as being thrown in the default queue executing state, will still be thrown when a queue is in the recording state. -The `queue::begin_recording` and `queue::end_recording` entry-points return a -`bool` value informing the user whether a state change occurred. False is -returned rather than throwing an exception when state isn't changed. This design -is because the queue is already in the state the user desires, so if the -function threw an exception in this case, the application would likely swallow -it and then proceed. +The `command_graph::begin_recording` and `command_graph::end_recording` +entry-points return a `bool` value informing the user whether a related queue +state change occurred. False is returned rather than throwing an exception when +no queue state is changed. This design is because the queues are already in +the state the user desires, so if the function threw an exception in this case, +the application would likely swallow it and then proceed. While a queue is in the recording state, methods performed on that queue which are not command submissions behave as normal. This includes waits, throws, and @@ -1092,7 +1186,7 @@ submitted in its entirety for execution via // `q` will be put in the recording state where commands are recorded to // `graph` rather than submitted for execution immediately. - q.begin_recording(graph); + graph.begin_recording(q); // Record commands to `graph` with the following topology. // @@ -1135,9 +1229,9 @@ submitted in its entirety for execution via }); }); - // queue will be returned to the executing state where commands are + // queue `q` will be returned to the executing state where commands are // submitted immediately for extension. - q.end_recording(); + graph.end_recording(); } // Finalize the modifiable graph to create an executable graph that can be @@ -1188,4 +1282,5 @@ this feature in the extension. |4|2022-08-10|Pablo Reble|Adding USM shortcuts |5|2022-10-21|Ewan Crawford|Merge in Codeplay vendor extension |6|2022-11-14|Ewan Crawford|Change graph execution to be a function on the handler +|7|2022-12-15|Ewan Crawford|Change record & replay relationship between graph and queue. |========================================