Skip to content

Commit 5b49cd3

Browse files
authored
[SYCL] Fix long long support in vec::convert on Windows (#3097)
- Keep `long long` and `unsigned long long` in `is_standard_type`. Excluding them resulted in duplicate `convertImpl` definitions on Windows when converting from `long long` or `unsigned long long`: SPIR-V-based and the non-standard type version. - For to-int SPIR-V-based `convertImpl` overload resolution, compare the OpenCL return type with cl_DestType instead of simply DestType ((u)char, (u)short, (u)int, (u)long). When converting to `long long` or `unsigned long long` on Windows, the non-standard type version was used instead of these functions, because `cl_long == long long != long` there.
1 parent 7497774 commit 5b49cd3

File tree

2 files changed

+78
-35
lines changed

2 files changed

+78
-35
lines changed

sycl/include/CL/sycl/types.hpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,8 @@ using is_float_to_float =
242242
std::integral_constant<bool, detail::is_floating_point<T>::value &&
243243
detail::is_floating_point<R>::value>;
244244
template <typename T>
245-
using is_standard_type = std::integral_constant<
246-
bool, detail::is_sgentype<T>::value && !std::is_same<T, long long>::value &&
247-
!std::is_same<T, unsigned long long>::value>;
245+
using is_standard_type =
246+
std::integral_constant<bool, detail::is_sgentype<T>::value>;
248247

249248
template <typename T, typename R, rounding_mode roundingMode, typename OpenCLT,
250249
typename OpenCLR>
@@ -330,7 +329,7 @@ convertImpl(T Value) {
330329
typename OpenCLT, typename OpenCLR> \
331330
detail::enable_if_t<is_sint_to_sint<T, R>::value && \
332331
!std::is_same<OpenCLT, OpenCLR>::value && \
333-
(std::is_same<OpenCLR, DestType>::value || \
332+
(std::is_same<OpenCLR, cl_##DestType>::value || \
334333
(std::is_same<OpenCLR, signed char>::value && \
335334
std::is_same<DestType, char>::value)), \
336335
R> \
@@ -352,7 +351,7 @@ __SYCL_GENERATE_CONVERT_IMPL(long)
352351
typename OpenCLT, typename OpenCLR> \
353352
detail::enable_if_t<is_uint_to_uint<T, R>::value && \
354353
!std::is_same<OpenCLT, OpenCLR>::value && \
355-
std::is_same<OpenCLR, DestType>::value, \
354+
std::is_same<OpenCLR, cl_##DestType>::value, \
356355
R> \
357356
convertImpl(T Value) { \
358357
OpenCLT OpValue = cl::sycl::detail::convertDataToType<T, OpenCLT>(Value); \
@@ -454,7 +453,7 @@ __SYCL_GENERATE_CONVERT_IMPL_FOR_ROUNDING_MODE(rtn, Rtn)
454453
template <typename T, typename R, rounding_mode roundingMode, \
455454
typename OpenCLT, typename OpenCLR> \
456455
detail::enable_if_t<is_float_to_int<T, R>::value && \
457-
(std::is_same<OpenCLR, DestType>::value || \
456+
(std::is_same<OpenCLR, cl_##DestType>::value || \
458457
std::is_same<OpenCLR, signed char>::value && \
459458
std::is_same<DestType, char>::value) && \
460459
RoundingModeCondition<roundingMode>::value, \

sycl/test/basic_tests/vectors/vectors.cpp

Lines changed: 73 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,52 @@
1010

1111
#define SYCL_SIMPLE_SWIZZLES
1212
#include <CL/sycl.hpp>
13-
using namespace cl::sycl;
1413

15-
void check_vectors(int4 a, int4 b, int4 c, int4 gold) {
16-
int4 result = a * (int4)b.y() + c;
14+
void check_vectors(sycl::int4 a, sycl::int4 b, sycl::int4 c, sycl::int4 gold) {
15+
sycl::int4 result = a * (sycl::int4)b.y() + c;
1716
assert((int)result.x() == (int)gold.x());
1817
assert((int)result.y() == (int)gold.y());
19-
assert((int)result.w() == (int)gold.w());
2018
assert((int)result.z() == (int)gold.z());
19+
assert((int)result.w() == (int)gold.w());
20+
}
21+
22+
template <typename From, typename To> void check_convert() {
23+
sycl::vec<From, 4> vec{1, 2, 3, 4};
24+
sycl::vec<To, 4> result = vec.template convert<To>();
25+
assert((int)result.x() == (int)vec.x());
26+
assert((int)result.y() == (int)vec.y());
27+
assert((int)result.z() == (int)vec.z());
28+
assert((int)result.w() == (int)vec.w());
29+
}
30+
31+
template <typename From, typename To> void check_signed_unsigned_convert_to() {
32+
check_convert<From, To>();
33+
check_convert<From, sycl::detail::make_unsigned_t<To>>();
34+
check_convert<sycl::detail::make_unsigned_t<From>, To>();
35+
check_convert<sycl::detail::make_unsigned_t<From>,
36+
sycl::detail::make_unsigned_t<To>>();
37+
}
38+
39+
template <typename From> void check_convert_from() {
40+
check_signed_unsigned_convert_to<From, int8_t>();
41+
check_signed_unsigned_convert_to<From, int16_t>();
42+
check_signed_unsigned_convert_to<From, int32_t>();
43+
check_signed_unsigned_convert_to<From, int64_t>();
44+
check_signed_unsigned_convert_to<From, char>();
45+
check_signed_unsigned_convert_to<From, short>();
46+
check_signed_unsigned_convert_to<From, int>();
47+
check_signed_unsigned_convert_to<From, long>();
48+
check_signed_unsigned_convert_to<From, long long>();
49+
check_signed_unsigned_convert_to<From, half>();
50+
check_signed_unsigned_convert_to<From, float>();
51+
check_signed_unsigned_convert_to<From, double>();
2152
}
2253

2354
int main() {
24-
int4 a = {1, 2, 3, 4};
25-
const int4 b = {10, 20, 30, 40};
26-
const int4 gold = {21, 42, 90, 120};
27-
const int2 a_xy = a.xy();
55+
sycl::int4 a = {1, 2, 3, 4};
56+
const sycl::int4 b = {10, 20, 30, 40};
57+
const sycl::int4 gold = {21, 42, 90, 120};
58+
const sycl::int2 a_xy = a.xy();
2859
check_vectors(a, b, {1, 2, 30, 40}, gold);
2960
check_vectors(a, b, {a.x(), a.y(), b.z(), b.w()}, gold);
3061
check_vectors(a, b, {a.x(), 2, b.z(), 40}, gold);
@@ -33,11 +64,11 @@ int main() {
3364
check_vectors(a, b, {a.xy(), b.zw()}, gold);
3465

3566
// Constructing vector from a scalar
36-
cl::sycl::vec<int, 1> vec_from_one_elem(1);
67+
sycl::vec<int, 1> vec_from_one_elem(1);
3768

3869
// implicit conversion
39-
cl::sycl::vec<unsigned char, 2> vec_2(1, 2);
40-
cl::sycl::vec<unsigned char, 4> vec_4(0, vec_2, 3);
70+
sycl::vec<unsigned char, 2> vec_2(1, 2);
71+
sycl::vec<unsigned char, 4> vec_4(0, vec_2, 3);
4172

4273
assert(vec_4.get_count() == 4);
4374
assert(static_cast<unsigned char>(vec_4.x()) == static_cast<unsigned char>(0));
@@ -47,10 +78,10 @@ int main() {
4778

4879
// explicit conversion
4980
int64_t(vec_2.x());
50-
cl::sycl::int4(vec_2.x());
81+
sycl::int4(vec_2.x());
5182

5283
// Check broadcasting operator=
53-
cl::sycl::vec<float, 4> b_vec(1.0);
84+
sycl::vec<float, 4> b_vec(1.0);
5485
b_vec = 0.5;
5586
assert(static_cast<float>(b_vec.x()) == static_cast<float>(0.5));
5687
assert(static_cast<float>(b_vec.y()) == static_cast<float>(0.5));
@@ -60,27 +91,40 @@ int main() {
6091
// Check that vector with 'unsigned long long' elements has enough bits to
6192
// store value.
6293
unsigned long long ull_ref = 1ull - 2ull;
63-
auto ull_vec = cl::sycl::vec<unsigned long long, 1>(ull_ref);
64-
unsigned long long ull_val = ull_vec.template swizzle<cl::sycl::elem::s0>();
94+
auto ull_vec = sycl::vec<unsigned long long, 1>(ull_ref);
95+
unsigned long long ull_val = ull_vec.template swizzle<sycl::elem::s0>();
6596
assert(ull_val == ull_ref);
6697

6798
// Check that the function as() in swizzle vec class is working correctly
68-
cl::sycl::vec<int8_t, 2> inputVec = cl::sycl::vec<int8_t, 2>(0, 1);
69-
auto asVec =
70-
inputVec.template swizzle<cl::sycl::elem::s0, cl::sycl::elem::s1>()
71-
.template as<cl::sycl::vec<int16_t, 1>>();
99+
sycl::vec<int8_t, 2> inputVec = sycl::vec<int8_t, 2>(0, 1);
100+
auto asVec = inputVec.template swizzle<sycl::elem::s0, sycl::elem::s1>()
101+
.template as<sycl::vec<int16_t, 1>>();
72102

73103
// Check that [u]long[n] type aliases match vec<[unsigned] long, n> types.
74-
assert((std::is_same<cl::sycl::vec<long, 2>, cl::sycl::long2>::value));
75-
assert((std::is_same<cl::sycl::vec<long, 3>, cl::sycl::long3>::value));
76-
assert((std::is_same<cl::sycl::vec<long, 4>, cl::sycl::long4>::value));
77-
assert((std::is_same<cl::sycl::vec<long, 8>, cl::sycl::long8>::value));
78-
assert((std::is_same<cl::sycl::vec<long, 16>, cl::sycl::long16>::value));
79-
assert((std::is_same<cl::sycl::vec<unsigned long, 2>, cl::sycl::ulong2>::value));
80-
assert((std::is_same<cl::sycl::vec<unsigned long, 3>, cl::sycl::ulong3>::value));
81-
assert((std::is_same<cl::sycl::vec<unsigned long, 4>, cl::sycl::ulong4>::value));
82-
assert((std::is_same<cl::sycl::vec<unsigned long, 8>, cl::sycl::ulong8>::value));
83-
assert((std::is_same<cl::sycl::vec<unsigned long, 16>, cl::sycl::ulong16>::value));
104+
assert((std::is_same<sycl::vec<long, 2>, sycl::long2>::value));
105+
assert((std::is_same<sycl::vec<long, 3>, sycl::long3>::value));
106+
assert((std::is_same<sycl::vec<long, 4>, sycl::long4>::value));
107+
assert((std::is_same<sycl::vec<long, 8>, sycl::long8>::value));
108+
assert((std::is_same<sycl::vec<long, 16>, sycl::long16>::value));
109+
assert((std::is_same<sycl::vec<unsigned long, 2>, sycl::ulong2>::value));
110+
assert((std::is_same<sycl::vec<unsigned long, 3>, sycl::ulong3>::value));
111+
assert((std::is_same<sycl::vec<unsigned long, 4>, sycl::ulong4>::value));
112+
assert((std::is_same<sycl::vec<unsigned long, 8>, sycl::ulong8>::value));
113+
assert((std::is_same<sycl::vec<unsigned long, 16>, sycl::ulong16>::value));
114+
115+
// Check convert() from and to various types.
116+
check_convert_from<int8_t>();
117+
check_convert_from<int16_t>();
118+
check_convert_from<int32_t>();
119+
check_convert_from<int64_t>();
120+
check_convert_from<char>();
121+
check_convert_from<short>();
122+
check_convert_from<int>();
123+
check_convert_from<long>();
124+
check_convert_from<long long>();
125+
check_convert_from<half>();
126+
check_convert_from<float>();
127+
check_convert_from<double>();
84128

85129
return 0;
86130
}

0 commit comments

Comments
 (0)