diff --git a/sycl/include/CL/sycl/backend.hpp b/sycl/include/CL/sycl/backend.hpp index 69ff9e0b87268..1608ed97ed8e4 100644 --- a/sycl/include/CL/sycl/backend.hpp +++ b/sycl/include/CL/sycl/backend.hpp @@ -52,6 +52,14 @@ template class backend_traits { // TODO define errc once SYCL2020-style exceptions are supported. }; +template +using backend_input_t = + typename backend_traits::template input_type; + +template +using backend_return_t = + typename backend_traits::template return_type; + template auto get_native(const SyclObjectT &Obj) -> typename interop::type { diff --git a/sycl/include/CL/sycl/backend_types.hpp b/sycl/include/CL/sycl/backend_types.hpp index b7872208fc4aa..148bccf6e77a6 100644 --- a/sycl/include/CL/sycl/backend_types.hpp +++ b/sycl/include/CL/sycl/backend_types.hpp @@ -26,7 +26,16 @@ enum class backend : char { all = 4 }; -template struct interop; +template struct interop; + +template class backend_traits; + +template +using backend_input_t = + typename backend_traits::template input_type; +template +using backend_return_t = + typename backend_traits::template return_type; inline std::ostream &operator<<(std::ostream &Out, backend be) { switch (be) { diff --git a/sycl/include/CL/sycl/interop_handle.hpp b/sycl/include/CL/sycl/interop_handle.hpp index eb6e7fb81cc77..1a135c6a26455 100644 --- a/sycl/include/CL/sycl/interop_handle.hpp +++ b/sycl/include/CL/sycl/interop_handle.hpp @@ -48,17 +48,21 @@ class interop_handle { /// of the command group requirements (e.g. it is an unregistered placeholder /// accessor), the exception `cl::sycl::invalid_object` is thrown /// asynchronously. - template - typename detail::enable_if_t< - Target == access::target::global_buffer || - Target == access::target::constant_buffer, - typename interop>::type> + backend_return_t> get_native_mem(const accessor &Acc) const { + // TODO: the method is available when the target is target::device. Add it + // to the assert below when target::device enum is created. + static_assert(Target == access::target::global_buffer || + Target == access::target::constant_buffer, + "The method is available only for target::device accessors"); #ifndef __SYCL_DEVICE_ONLY__ + if (Backend != get_backend()) + throw invalid_object_error("Incorrect backend argument was passed", + PI_INVALID_MEM_OBJECT); const auto *AccBase = static_cast(&Acc); - return getMemImpl( + return getMemImpl( detail::getSyclObjImpl(*AccBase).get()); #else (void)Acc; @@ -67,49 +71,49 @@ class interop_handle { #endif } - template - typename detail::enable_if_t< - !(Target == access::target::global_buffer || - Target == access::target::constant_buffer), - typename interop>::type> - get_native_mem(const accessor &) const { - throw invalid_object_error("Getting memory object out of accessor for " - "specified target is not allowed", - PI_INVALID_MEM_OBJECT); - } - - /// Returns an underlying OpenCL queue for the SYCL queue used to submit the - /// command group, or the fallback queue if this command-group is re-trying - /// execution on an OpenCL queue. The OpenCL command queue returned is + /// Returns an underlying native backend object associated with teh queue + /// that the host task was submitted to. If the command group was submitted + /// with a secondary queue and the fall-back was triggered, the queue that + /// is associated with the interop_handle must be the fall-back queue. + /// The native backend object returned must be in a state where it is capable + /// of being used in a way appropriate for the associated SYCL backend. It is /// implementation-defined in cases where the SYCL queue maps to multiple - /// underlying OpenCL objects. It is responsibility of the SYCL runtime to - /// ensure the OpenCL queue returned is in a state that can be used to - /// dispatch work, and that other potential OpenCL command queues associated + /// underlying backend objects. It is responsibility of the SYCL runtime to + /// ensure the backend queue returned is in a state that can be used to + /// dispatch work, and that other potential backend command queues associated /// with the same SYCL command queue are not executing commands while the host /// task is executing. - template - auto get_native_queue() const noexcept -> - typename interop::type { + template + backend_return_t get_native_queue() const { #ifndef __SYCL_DEVICE_ONLY__ - return reinterpret_cast::type>( - getNativeQueue()); + // TODO: replace the exception thrown below with the SYCL-2020 exception + // with the error code 'errc::backend_mismatch' when those new exceptions + // are ready to be used. + if (Backend != get_backend()) + throw invalid_object_error("Incorrect backend argument was passed", + PI_INVALID_MEM_OBJECT); + return reinterpret_cast>(getNativeQueue()); #else // we believe this won't be ever called on device side return 0; #endif } - /// Returns an underlying OpenCL device associated with the SYCL queue used - /// to submit the command group, or the fallback queue if this command-group - /// is re-trying execution on an OpenCL queue. - template - auto get_native_device() const noexcept -> - typename interop::type { + /// Returns the SYCL application interoperability native backend object + /// associated with the device associated with the SYCL queue that the host + /// task was submitted to. The native backend object returned must be in + /// a state where it is capable of being used in a way appropriate for + /// the associated SYCL backend. + template + backend_return_t get_native_device() const { #ifndef __SYCL_DEVICE_ONLY__ - return reinterpret_cast::type>( + // TODO: replace the exception thrown below with the SYCL-2020 exception + // with the error code 'errc::backend_mismatch' when those new exceptions + // are ready to be used. + if (Backend != get_backend()) + throw invalid_object_error("Incorrect backend argument was passed", + PI_INVALID_MEM_OBJECT); + return reinterpret_cast>( getNativeDevice()); #else // we believe this won't be ever called on device side @@ -117,14 +121,21 @@ class interop_handle { #endif } - /// Returns an underlying OpenCL context associated with the SYCL queue used - /// to submit the command group, or the fallback queue if this command-group - /// is re-trying execution on an OpenCL queue. - template - auto get_native_context() const noexcept -> - typename interop::type { + /// Returns the SYCL application interoperability native backend object + /// associated with the context associated with the SYCL queue that the host + /// task was submitted to. The native backend object returned must be in + /// a state where it is capable of being used in a way appropriate for + /// the associated SYCL backend. + template + backend_return_t get_native_context() const { #ifndef __SYCL_DEVICE_ONLY__ - return reinterpret_cast::type>( + // TODO: replace the exception thrown below with the SYCL-2020 exception + // with the error code 'errc::backend_mismatch' when those new exceptions + // are ready to be used. + if (Backend != get_backend()) + throw invalid_object_error("Incorrect backend argument was passed", + PI_INVALID_MEM_OBJECT); + return reinterpret_cast>( getNativeContext()); #else // we believe this won't be ever called on device side @@ -144,11 +155,9 @@ class interop_handle { : MQueue(Queue), MDevice(Device), MContext(Context), MMemObjs(std::move(MemObjs)) {} - template - auto getMemImpl(detail::Requirement *Req) const -> - typename interop>::type { + template + backend_return_t> + getMemImpl(detail::Requirement *Req) const { /* Do not update this cast: a C-style cast is required here. @@ -167,9 +176,7 @@ class interop_handle { https://en.cppreference.com/w/cpp/language/reinterpret_cast https://en.cppreference.com/w/cpp/language/explicit_cast */ - return (typename interop>::type)( - getNativeMem(Req)); + return (backend_return_t>)(getNativeMem(Req)); } __SYCL_EXPORT pi_native_handle getNativeMem(detail::Requirement *Req) const;