Asynchronous error handler

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.

See also

SYCL Specification Section 4.13.1.1

Error handling rules

Exceptions

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