Skip to content

Commit b5b6673

Browse files
author
Pavel Samolysov
authored
[SYCL] Make sycl::marray trivially copyable (#4885)
The sycl::marray class is not trivially copyable but marked as device copyable. It makes problems with any class that contain a member with the sycl::marray type: that class will not be trivially copyable and therefore device copyable regardless the sycl::marray one is. To solve this issue, the sycl::marray class is converted into a trivially copyable one. The constexpr attribute for the copy constructor is saved so the class can still be copied in constant expressions.
1 parent c855fd1 commit b5b6673

File tree

4 files changed

+40
-19
lines changed

4 files changed

+40
-19
lines changed

sycl/include/CL/sycl/marray.hpp

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -66,17 +66,9 @@ template <typename Type, std::size_t NumElements> class marray {
6666
typename = typename std::enable_if<sizeof...(ArgTN) == NumElements>::type>
6767
constexpr marray(const ArgTN &... Args) : MData{Args...} {}
6868

69-
constexpr marray(const marray<Type, NumElements> &Rhs) {
70-
for (std::size_t I = 0; I < NumElements; ++I) {
71-
MData[I] = Rhs.MData[I];
72-
}
73-
}
69+
constexpr marray(const marray<Type, NumElements> &Rhs) = default;
7470

75-
constexpr marray(marray<Type, NumElements> &&Rhs) {
76-
for (std::size_t I = 0; I < NumElements; ++I) {
77-
MData[I] = Rhs.MData[I];
78-
}
79-
}
71+
constexpr marray(marray<Type, NumElements> &&Rhs) = default;
8072

8173
// Available only when: NumElements == 1
8274
template <std::size_t Size = NumElements,
@@ -92,12 +84,7 @@ template <typename Type, std::size_t NumElements> class marray {
9284

9385
const_reference operator[](std::size_t index) const { return MData[index]; }
9486

95-
marray &operator=(const marray<Type, NumElements> &Rhs) {
96-
for (std::size_t I = 0; I < NumElements; ++I) {
97-
MData[I] = Rhs.MData[I];
98-
}
99-
return *this;
100-
}
87+
marray &operator=(const marray<Type, NumElements> &Rhs) = default;
10188

10289
// broadcasting operator
10390
marray &operator=(const Type &Rhs) {

sycl/include/CL/sycl/types.hpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2414,10 +2414,13 @@ struct is_device_copyable<std::tuple<T, Ts...>>
24142414
: detail::bool_constant<is_device_copyable<T>::value &&
24152415
is_device_copyable<std::tuple<Ts...>>::value> {};
24162416

2417-
// marray is device copyable if element type is device copyable
2417+
// marray is device copyable if element type is device copyable and it is also
2418+
// not trivially copyable (if the element type is trivially copyable, the marray
2419+
// is device copyable by default).
24182420
template <typename T, std::size_t N>
2419-
struct is_device_copyable<sycl::marray<T, N>,
2420-
std::enable_if_t<is_device_copyable<T>::value>>
2421+
struct is_device_copyable<
2422+
sycl::marray<T, N>, std::enable_if_t<is_device_copyable<T>::value &&
2423+
!std::is_trivially_copyable<T>::value>>
24212424
: std::true_type {};
24222425

24232426
// vec is device copyable on host, on device vec is trivially copyable

sycl/test/basic_tests/marray/marray.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,5 +94,31 @@ int main() {
9494
b___ = !mint3{0, 1, 2};
9595
assert(b___[0] == true && b___[1] == false && b___[2] == false);
9696

97+
// check copyability
98+
constexpr sycl::marray<double, 5> ma;
99+
constexpr sycl::marray<double, 5> mb(ma);
100+
constexpr sycl::marray<double, 5> mc = ma;
101+
102+
// check trivially copyability
103+
struct Copyable {
104+
int a;
105+
double b;
106+
const char *name;
107+
};
108+
109+
static_assert(std::is_trivially_copyable<sycl::marray<Copyable, 5>>::value,
110+
"sycl::marray<Copyable, 5> is not trivially copyable type");
111+
static_assert(
112+
!std::is_trivially_copyable<sycl::marray<std::string, 5>>::value,
113+
"sycl::marray<std::string, 5> is trivially copyable type");
114+
115+
// check device copyability
116+
static_assert(sycl::is_device_copyable<sycl::marray<std::tuple<>, 5>>::value,
117+
"sycl::marray<std::tuple<>, 5> is not device copyable type");
118+
static_assert(!sycl::is_device_copyable<sycl::marray<std::string, 5>>::value,
119+
"sycl::marray<std::string, 5> is device copyable type");
120+
121+
return 0;
122+
97123
return 0;
98124
}

sycl/test/basic_tests/valid_kernel_args.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ struct SomeStructure {
2323
} v;
2424
};
2525

26+
struct SomeMarrayStructure {
27+
cl::sycl::marray<double, 5> points;
28+
};
29+
2630
#define CHECK_PASSING_TO_KERNEL_BY_VALUE(Type) \
2731
static_assert(std::is_standard_layout<Type>::value, \
2832
"Is not standard layouti type."); \
@@ -34,3 +38,4 @@ CHECK_PASSING_TO_KERNEL_BY_VALUE(int)
3438
CHECK_PASSING_TO_KERNEL_BY_VALUE(cl::sycl::cl_uchar4)
3539
CHECK_PASSING_TO_KERNEL_BY_VALUE(SomeStructure)
3640
#endif
41+
CHECK_PASSING_TO_KERNEL_BY_VALUE(SomeMarrayStructure)

0 commit comments

Comments
 (0)