Skip to content

Commit a6465c9

Browse files
author
Ivan Karachun
authored
[SYCL] Aligned set_arg behaviour with SYCL specification (#2159)
According to SYCL 1.2.1 specification, rev. 7, paragraph 4.8.5: template <typename T> void set_arg(int argIndex, T &&arg) ... The argument can be either a SYCL accessor, a SYCL sampler or a trivially copyable and standard-layout C++ type. Signed-off-by: Ivan Karachun <[email protected]>
1 parent a9c776f commit a6465c9

File tree

2 files changed

+77
-1
lines changed

2 files changed

+77
-1
lines changed

sycl/include/CL/sycl/handler.hpp

+30-1
Original file line numberDiff line numberDiff line change
@@ -796,13 +796,42 @@ class __SYCL_EXPORT handler {
796796
}
797797
}
798798

799+
template <typename T>
800+
using remove_cv_ref_t =
801+
typename std::remove_cv<detail::remove_reference_t<T>>::type;
802+
803+
template <typename U, typename T>
804+
using is_same_type = std::is_same<remove_cv_ref_t<U>, remove_cv_ref_t<T>>;
805+
806+
template <typename T> struct ShouldEnableSetArg {
807+
static constexpr bool value =
808+
std::is_trivially_copyable<T>::value
809+
#if CL_SYCL_LANGUAGE_VERSION && CL_SYCL_LANGUAGE_VERSION <= 121
810+
&& std::is_standard_layout<T>::value
811+
#endif
812+
|| is_same_type<sampler, T>::value // Sampler
813+
|| (!is_same_type<cl_mem, T>::value &&
814+
std::is_pointer<remove_cv_ref_t<T>>::value) // USM
815+
|| is_same_type<cl_mem, T>::value; // Interop
816+
};
817+
799818
/// Sets argument for OpenCL interoperability kernels.
800819
///
801820
/// Registers Arg passed as argument # ArgIndex.
802821
///
803822
/// \param ArgIndex is a positional number of argument to be set.
804823
/// \param Arg is an argument value to be set.
805-
template <typename T> void set_arg(int ArgIndex, T &&Arg) {
824+
template <typename T>
825+
typename std::enable_if<ShouldEnableSetArg<T>::value, void>::type
826+
set_arg(int ArgIndex, T &&Arg) {
827+
setArgHelper(ArgIndex, std::move(Arg));
828+
}
829+
830+
template <typename DataT, int Dims, access::mode AccessMode,
831+
access::target AccessTarget, access::placeholder IsPlaceholder>
832+
void
833+
set_arg(int ArgIndex,
834+
accessor<DataT, Dims, AccessMode, AccessTarget, IsPlaceholder> Arg) {
806835
setArgHelper(ArgIndex, std::move(Arg));
807836
}
808837

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// RUN: %clangxx -fsycl -Xclang -verify %s -I %sycl_include -Xclang -verify-ignore-unexpected=note,warning -fsyntax-only
2+
3+
#include <CL/sycl.hpp>
4+
5+
struct TriviallyCopyable {
6+
int a;
7+
int b;
8+
};
9+
10+
struct NonTriviallyCopyable {
11+
NonTriviallyCopyable() = default;
12+
NonTriviallyCopyable(NonTriviallyCopyable const &) {}
13+
int a;
14+
int b;
15+
};
16+
17+
struct NonStdLayout {
18+
int a;
19+
20+
private:
21+
int b;
22+
};
23+
24+
int main() {
25+
constexpr size_t size = 1;
26+
cl::sycl::buffer<int> buf(size);
27+
cl::sycl::queue q;
28+
q.submit([&](cl::sycl::handler &h) {
29+
auto global_acc = buf.get_access<cl::sycl::access::mode::write>(h);
30+
cl::sycl::sampler samp(cl::sycl::coordinate_normalization_mode::normalized,
31+
cl::sycl::addressing_mode::clamp,
32+
cl::sycl::filtering_mode::nearest);
33+
cl::sycl::accessor<int, 1, cl::sycl::access::mode::read_write,
34+
cl::sycl::access::target::local>
35+
local_acc({size}, h);
36+
h.set_arg(0, local_acc);
37+
h.set_arg(1, global_acc);
38+
h.set_arg(2, samp);
39+
h.set_arg(3, TriviallyCopyable{});
40+
h.set_arg( // expected-error {{no matching member function for call to 'set_arg'}}
41+
4, NonTriviallyCopyable{});
42+
#if CL_SYCL_LANGUAGE_VERSION && CL_SYCL_LANGUAGE_VERSION <= 121
43+
h.set_arg( // expected-error {{no matching member function for call to 'set_arg'}}
44+
5, NonStdLayout{});
45+
#endif
46+
});
47+
}

0 commit comments

Comments
 (0)