Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions sycl/include/sycl/detail/is_device_copyable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,20 +93,25 @@ namespace detail {
template <typename T, typename> struct CheckFieldsAreDeviceCopyable;
template <typename T, typename> struct CheckBasesAreDeviceCopyable;

template <typename T>
inline constexpr bool is_deprecated_device_copyable_v =
is_device_copyable_v<T> || (std::is_trivially_copy_constructible_v<T> &&
std::is_trivially_destructible_v<T>);

template <typename T, unsigned... FieldIds>
struct CheckFieldsAreDeviceCopyable<T, std::index_sequence<FieldIds...>> {
static_assert(
((is_device_copyable_v<decltype(__builtin_field_type(T, FieldIds))> &&
...)),
"The specified type is not device copyable");
static_assert(((is_deprecated_device_copyable_v<
decltype(__builtin_field_type(T, FieldIds))> &&
...)),
"The specified type is not device copyable");
};

template <typename T, unsigned... BaseIds>
struct CheckBasesAreDeviceCopyable<T, std::index_sequence<BaseIds...>> {
static_assert(
((is_device_copyable_v<decltype(__builtin_base_type(T, BaseIds))> &&
...)),
"The specified type is not device copyable");
static_assert(((is_deprecated_device_copyable_v<
decltype(__builtin_base_type(T, BaseIds))> &&
...)),
"The specified type is not device copyable");
};

// All the captures of a lambda or functor of type FuncT passed to a kernel
Expand Down
10 changes: 10 additions & 0 deletions sycl/test/basic_tests/is_device_copyable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ struct BCopyable {
BCopyable(const BCopyable &x) : i(x.i) {}
};

// Not trivially copyable, but trivially copy constructible/destructible.
// Such types are passed to kernels to stay compatible with deprecated
// sycl 1.2.1 rules.
struct C : A {
const A C2;
C() : A{0}, C2{2} {}
};

// Not copyable type, but it will be declared as device copyable.
struct DCopyable {
int i;
Expand Down Expand Up @@ -59,6 +67,7 @@ void test() {
A IamGood;
IamGood.i = 0;
BCopyable IamBadButCopyable(1);
C IamAlsoGood;
DCopyable IamAlsoBadButCopyable{0};
marray<int, 5> MarrayForCopyableIsCopyable(0);
range<2> Range{1,2};
Expand All @@ -69,6 +78,7 @@ void test() {
int A = IamGood.i;
int B = IamBadButCopyable.i;
int C = IamAlsoBadButCopyable.i;
int D = IamAlsoGood.i;
int E = MarrayForCopyableIsCopyable[0];
int F = Range[1];
int G = Id[2];
Expand Down
6 changes: 3 additions & 3 deletions sycl/test/basic_tests/is_device_copyable_neg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,18 @@ void test() {
B IamAlsoBad{0};
marray<B, 2> MarrayForNotCopyable;
queue Q;
// expected-error@*:* {{static assertion failed due to requirement 'is_device_copyable_v<A>': The specified type is not device copyable}}
// expected-error@*:* {{static assertion failed due to requirement 'is_deprecated_device_copyable_v<A>': The specified type is not device copyable}}
Q.single_task<class TestA>([=] {
int A = IamBad.i;
int B = IamAlsoBad.i;
int MB = MarrayForNotCopyable[0].i;
});

FunctorA FA;
// expected-error@*:* {{static assertion failed due to requirement 'is_device_copyable_v<C>': The specified type is not device copyable}}
// expected-error@*:* {{static assertion failed due to requirement 'is_deprecated_device_copyable_v<C>': The specified type is not device copyable}}
Q.single_task<class TestB>(FA);

FunctorB FB;
// expected-error@*:* {{static assertion failed due to requirement 'is_device_copyable_v<D>': The specified type is not device copyable}}
// expected-error@*:* {{static assertion failed due to requirement 'is_deprecated_device_copyable_v<D>': The specified type is not device copyable}}
Q.single_task<class TestC>(FB);
}
Loading