Asynchronous error handler#
namespace sycl {
using async_handler = std::function<void(sycl::exception_list)>;
} // namespace sycl
The sycl::queue and sycl::context classes can optionally take
an asynchronous handler object sycl::async_handler
on construction,
which is a callable such as a function class or lambda, with
an sycl::exception_list
as a parameter. Invocation of an
sycl::async_handler
may be triggered by the queue member functions
sycl::queue::wait_and_throw()
or sycl::queue::throw_asynchronous()
,
by the sycl::event
member function sycl::event::wait_and_throw()
,
or automatically on destruction of a sycl::queue or sycl::context that
contains unconsumed asynchronous errors. When invoked, an
sycl::async_handler
is called and receives an sycl::exception_list
argument containing a list of exception objects representing any unconsumed
asynchronous errors associated with the sycl::queue or sycl::context.
When an asynchronous error instance has been passed to an
sycl::async_handler
, then that instance of the error
has been consumed for handling and is not reported on any
subsequent invocations of the sycl::async_handler
.
The sycl::async_handler
may be a named function object type, a
lambda function or a std::function
. The sycl::exception_list
object
passed to the sycl::async_handler
is constructed by the SYCL runtime.
Behavior without an sycl::async_handler
#
If an asynchronous error occurs in a sycl::queue or sycl::context that
has no user-supplied asynchronous error handler object sycl::async_handler
,
then an implementation-defined default sycl::async_handler
is called to
handle the error in the same situations that a user-supplied
sycl::async_handler
would be, as defined in section above.
The default sycl::async_handler
must in some way report all errors
passed to it, when possible, and must then invoke std::terminate
or equivalent.
Example 1#
Below is example of implementing an sycl::async_handler
as lambda
function and passing it to the sycl::queue.
1#include <sycl/sycl.hpp>
2
3auto async_handler_object = [](sycl::exception_list exceptions) {
4 for (auto e : exceptions) {
5 try {
6 std::rethrow_exception(e);
7 } catch (sycl::exception const &e) {
8 std::cout << "Caught asynchronous SYCL exception:\n"
9 << e.what() << std::endl;
10 }
11 }
12};
13
14class async_error_example {};
15
16int main() {
17 // Create a queue with asynchronous handler
18 sycl::queue myQueue{async_handler_object};
19
20 myQueue.submit([&](sycl::handler &cgh) {
21 // Throw sycl::exception for async_handler_object to catch
22 cgh.host_task([]() {
23 throw sycl::exception(std::error_code{}, "Example exception!");
24 });
25 });
26
27 // Invocation of sycl::async_handler is triggered here
28 myQueue.wait_and_throw();
29}
Output:
Caught asynchronous SYCL exception:
Example exception