Skip to content

Commit d08c21a

Browse files
authored
[SYCL] Use SYCL-2020 backend_return_t<> in interop_handle instead of interop<> (#3685)
The corresponding changes in LIT tests: intel/llvm-test-suite#263 This patch also removes the implementation of the method get_native_mem accepting accessor with target not equal to global_buffer/constant_buffer. That method always threw exception, which is wrong as that is the runtime handling of an obvious error, which must be detected earlier - at compile time. The template parameter 'backend Backend = backend::opencl' remains as one having the default value to not break compatibility with older behavior of interop_handle::get_native_mem(), which could be called without explicit specification of the 'backend' template parameter. Signed-off-by: Vyacheslav N Klochkov <[email protected]>
1 parent 50edee4 commit d08c21a

File tree

3 files changed

+79
-55
lines changed

3 files changed

+79
-55
lines changed

sycl/include/CL/sycl/backend.hpp

+8
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,14 @@ template <backend Backend> class backend_traits {
5252
// TODO define errc once SYCL2020-style exceptions are supported.
5353
};
5454

55+
template <backend Backend, typename SyclType>
56+
using backend_input_t =
57+
typename backend_traits<Backend>::template input_type<SyclType>;
58+
59+
template <backend Backend, typename SyclType>
60+
using backend_return_t =
61+
typename backend_traits<Backend>::template return_type<SyclType>;
62+
5563
template <backend BackendName, class SyclObjectT>
5664
auto get_native(const SyclObjectT &Obj) ->
5765
typename interop<BackendName, SyclObjectT>::type {

sycl/include/CL/sycl/backend_types.hpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,16 @@ enum class backend : char {
2626
all = 4
2727
};
2828

29-
template <backend name, typename SYCLObjectT> struct interop;
29+
template <backend Backend, typename SYCLObjectT> struct interop;
30+
31+
template <backend Backend> class backend_traits;
32+
33+
template <backend Backend, typename SYCLObjectT>
34+
using backend_input_t =
35+
typename backend_traits<Backend>::template input_type<SYCLObjectT>;
36+
template <backend Backend, typename SYCLObjectT>
37+
using backend_return_t =
38+
typename backend_traits<Backend>::template return_type<SYCLObjectT>;
3039

3140
inline std::ostream &operator<<(std::ostream &Out, backend be) {
3241
switch (be) {

sycl/include/CL/sycl/interop_handle.hpp

+61-54
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,21 @@ class interop_handle {
4848
/// of the command group requirements (e.g. it is an unregistered placeholder
4949
/// accessor), the exception `cl::sycl::invalid_object` is thrown
5050
/// asynchronously.
51-
template <backend BackendName = backend::opencl, typename DataT, int Dims,
51+
template <backend Backend = backend::opencl, typename DataT, int Dims,
5252
access::mode Mode, access::target Target, access::placeholder IsPlh>
53-
typename detail::enable_if_t<
54-
Target == access::target::global_buffer ||
55-
Target == access::target::constant_buffer,
56-
typename interop<BackendName,
57-
accessor<DataT, Dims, Mode, Target, IsPlh>>::type>
53+
backend_return_t<Backend, buffer<DataT, Dims>>
5854
get_native_mem(const accessor<DataT, Dims, Mode, Target, IsPlh> &Acc) const {
55+
// TODO: the method is available when the target is target::device. Add it
56+
// to the assert below when target::device enum is created.
57+
static_assert(Target == access::target::global_buffer ||
58+
Target == access::target::constant_buffer,
59+
"The method is available only for target::device accessors");
5960
#ifndef __SYCL_DEVICE_ONLY__
61+
if (Backend != get_backend())
62+
throw invalid_object_error("Incorrect backend argument was passed",
63+
PI_INVALID_MEM_OBJECT);
6064
const auto *AccBase = static_cast<const detail::AccessorBaseHost *>(&Acc);
61-
return getMemImpl<BackendName, DataT, Dims, Mode, Target, IsPlh>(
65+
return getMemImpl<Backend, DataT, Dims>(
6266
detail::getSyclObjImpl(*AccBase).get());
6367
#else
6468
(void)Acc;
@@ -67,64 +71,71 @@ class interop_handle {
6771
#endif
6872
}
6973

70-
template <backend BackendName = backend::opencl, typename DataT, int Dims,
71-
access::mode Mode, access::target Target, access::placeholder IsPlh>
72-
typename detail::enable_if_t<
73-
!(Target == access::target::global_buffer ||
74-
Target == access::target::constant_buffer),
75-
typename interop<BackendName,
76-
accessor<DataT, Dims, Mode,
77-
access::target::global_buffer, IsPlh>>::type>
78-
get_native_mem(const accessor<DataT, Dims, Mode, Target, IsPlh> &) const {
79-
throw invalid_object_error("Getting memory object out of accessor for "
80-
"specified target is not allowed",
81-
PI_INVALID_MEM_OBJECT);
82-
}
83-
84-
/// Returns an underlying OpenCL queue for the SYCL queue used to submit the
85-
/// command group, or the fallback queue if this command-group is re-trying
86-
/// execution on an OpenCL queue. The OpenCL command queue returned is
74+
/// Returns an underlying native backend object associated with teh queue
75+
/// that the host task was submitted to. If the command group was submitted
76+
/// with a secondary queue and the fall-back was triggered, the queue that
77+
/// is associated with the interop_handle must be the fall-back queue.
78+
/// The native backend object returned must be in a state where it is capable
79+
/// of being used in a way appropriate for the associated SYCL backend. It is
8780
/// implementation-defined in cases where the SYCL queue maps to multiple
88-
/// underlying OpenCL objects. It is responsibility of the SYCL runtime to
89-
/// ensure the OpenCL queue returned is in a state that can be used to
90-
/// dispatch work, and that other potential OpenCL command queues associated
81+
/// underlying backend objects. It is responsibility of the SYCL runtime to
82+
/// ensure the backend queue returned is in a state that can be used to
83+
/// dispatch work, and that other potential backend command queues associated
9184
/// with the same SYCL command queue are not executing commands while the host
9285
/// task is executing.
93-
template <backend BackendName = backend::opencl>
94-
auto get_native_queue() const noexcept ->
95-
typename interop<BackendName, queue>::type {
86+
template <backend Backend = backend::opencl>
87+
backend_return_t<Backend, queue> get_native_queue() const {
9688
#ifndef __SYCL_DEVICE_ONLY__
97-
return reinterpret_cast<typename interop<BackendName, queue>::type>(
98-
getNativeQueue());
89+
// TODO: replace the exception thrown below with the SYCL-2020 exception
90+
// with the error code 'errc::backend_mismatch' when those new exceptions
91+
// are ready to be used.
92+
if (Backend != get_backend())
93+
throw invalid_object_error("Incorrect backend argument was passed",
94+
PI_INVALID_MEM_OBJECT);
95+
return reinterpret_cast<backend_return_t<Backend, queue>>(getNativeQueue());
9996
#else
10097
// we believe this won't be ever called on device side
10198
return 0;
10299
#endif
103100
}
104101

105-
/// Returns an underlying OpenCL device associated with the SYCL queue used
106-
/// to submit the command group, or the fallback queue if this command-group
107-
/// is re-trying execution on an OpenCL queue.
108-
template <backend BackendName = backend::opencl>
109-
auto get_native_device() const noexcept ->
110-
typename interop<BackendName, device>::type {
102+
/// Returns the SYCL application interoperability native backend object
103+
/// associated with the device associated with the SYCL queue that the host
104+
/// task was submitted to. The native backend object returned must be in
105+
/// a state where it is capable of being used in a way appropriate for
106+
/// the associated SYCL backend.
107+
template <backend Backend = backend::opencl>
108+
backend_return_t<Backend, device> get_native_device() const {
111109
#ifndef __SYCL_DEVICE_ONLY__
112-
return reinterpret_cast<typename interop<BackendName, device>::type>(
110+
// TODO: replace the exception thrown below with the SYCL-2020 exception
111+
// with the error code 'errc::backend_mismatch' when those new exceptions
112+
// are ready to be used.
113+
if (Backend != get_backend())
114+
throw invalid_object_error("Incorrect backend argument was passed",
115+
PI_INVALID_MEM_OBJECT);
116+
return reinterpret_cast<backend_return_t<Backend, device>>(
113117
getNativeDevice());
114118
#else
115119
// we believe this won't be ever called on device side
116120
return 0;
117121
#endif
118122
}
119123

120-
/// Returns an underlying OpenCL context associated with the SYCL queue used
121-
/// to submit the command group, or the fallback queue if this command-group
122-
/// is re-trying execution on an OpenCL queue.
123-
template <backend BackendName = backend::opencl>
124-
auto get_native_context() const noexcept ->
125-
typename interop<BackendName, context>::type {
124+
/// Returns the SYCL application interoperability native backend object
125+
/// associated with the context associated with the SYCL queue that the host
126+
/// task was submitted to. The native backend object returned must be in
127+
/// a state where it is capable of being used in a way appropriate for
128+
/// the associated SYCL backend.
129+
template <backend Backend = backend::opencl>
130+
backend_return_t<Backend, context> get_native_context() const {
126131
#ifndef __SYCL_DEVICE_ONLY__
127-
return reinterpret_cast<typename interop<BackendName, context>::type>(
132+
// TODO: replace the exception thrown below with the SYCL-2020 exception
133+
// with the error code 'errc::backend_mismatch' when those new exceptions
134+
// are ready to be used.
135+
if (Backend != get_backend())
136+
throw invalid_object_error("Incorrect backend argument was passed",
137+
PI_INVALID_MEM_OBJECT);
138+
return reinterpret_cast<backend_return_t<Backend, context>>(
128139
getNativeContext());
129140
#else
130141
// we believe this won't be ever called on device side
@@ -144,11 +155,9 @@ class interop_handle {
144155
: MQueue(Queue), MDevice(Device), MContext(Context),
145156
MMemObjs(std::move(MemObjs)) {}
146157

147-
template <backend BackendName, typename DataT, int Dims, access::mode Mode,
148-
access::target Target, access::placeholder IsPlh>
149-
auto getMemImpl(detail::Requirement *Req) const ->
150-
typename interop<BackendName,
151-
accessor<DataT, Dims, Mode, Target, IsPlh>>::type {
158+
template <backend Backend, typename DataT, int Dims>
159+
backend_return_t<Backend, buffer<DataT, Dims>>
160+
getMemImpl(detail::Requirement *Req) const {
152161
/*
153162
Do not update this cast: a C-style cast is required here.
154163
@@ -167,9 +176,7 @@ class interop_handle {
167176
https://en.cppreference.com/w/cpp/language/reinterpret_cast
168177
https://en.cppreference.com/w/cpp/language/explicit_cast
169178
*/
170-
return (typename interop<BackendName,
171-
accessor<DataT, Dims, Mode, Target, IsPlh>>::type)(
172-
getNativeMem(Req));
179+
return (backend_return_t<Backend, buffer<DataT, Dims>>)(getNativeMem(Req));
173180
}
174181

175182
__SYCL_EXPORT pi_native_handle getNativeMem(detail::Requirement *Req) const;

0 commit comments

Comments
 (0)