Skip to content

Commit 32f0cd5

Browse files
alexeyvoronov-intelbader
authored andcommitted
[SYCL] Fix for memory layout and alignment of the class vec.
Now vectors with a length of 3 will store 4 elements of dataT. Fixed boolean lit test on debug mode. Fixed the alignment of vec<half, N> variants. Now the vec class conform the requirements of item "4.10.2.6 Memory layout and alignment" of the SYCL specification: ''' The elements of an instance of the SYCL vec class template are stored in memory sequentially and contiguously and are aligned to the size of the element type in bytes multiplied by the number of elements: sizeof(dataT) * numElements The exception to this is when the number of element is three in which case the SYCL vec is aligned to the size of the element type in bytes multiplied by four: sizeof(dataT) * 4. ''' The lit test type.cpp was splited into two: aliases.cpp and types.cpp. This is done to make the tests smaller and make the tests consistent with what they're testing. Signed-off-by: Alexey Voronov <[email protected]>
1 parent 67c6ae5 commit 32f0cd5

File tree

4 files changed

+178
-122
lines changed

4 files changed

+178
-122
lines changed

sycl/include/CL/sycl/detail/boolean.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,18 @@ template <> struct Assigner<0> {
4343
}
4444
};
4545

46-
template <int N> struct alignas(N == 3 ? 4 : N) Boolean {
46+
template <int N> struct alignas(VectorAlignment<bool, N>::value) Boolean {
4747
static_assert(((N == 2) || (N == 3) || (N == 4) || (N == 8) || (N == 16)),
4848
"Invalid size");
4949

5050
using element_type = bool;
5151

5252
#ifdef __SYCL_DEVICE_ONLY__
5353
using DataType =
54-
element_type __attribute__((ext_vector_type(N)));
54+
element_type __attribute__((ext_vector_type(VectorLength<N>::value)));
5555
using vector_t = DataType;
5656
#else
57-
using DataType = element_type[N];
57+
using DataType = element_type[VectorLength<N>::value];
5858
#endif
5959

6060
Boolean() : value{false} {}

sycl/include/CL/sycl/types.hpp

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -306,15 +306,24 @@ detail::enable_if_t<is_float_to_int<T, R>::value, R> convertImpl(T Value) {
306306
#endif
307307
}
308308

309+
// 4.10.2.6 Memory layout and alignment
310+
template <int N> struct VectorLength { constexpr static int value = N; };
311+
312+
template <> struct VectorLength<3> { constexpr static int value = 4; };
313+
314+
template <typename T, int N> struct VectorAlignment {
315+
constexpr static int value = sizeof(T) * VectorLength<N>::value;
316+
};
317+
309318
} // namespace detail
310319

311320
template <typename Type, int NumElements> class vec {
312321
using DataT = Type;
313322

314323
// This represent type of underlying value. There should be only one field
315324
// in the class, so vec<float, 16> should be equal to float16 in memory.
316-
using DataType =
317-
typename detail::BaseCLTypeConverter<DataT, NumElements>::DataType;
325+
using DataType = typename detail::BaseCLTypeConverter<
326+
DataT, detail::VectorLength<NumElements>::value>::DataType;
318327

319328
template <bool B, class T, class F>
320329
using conditional_t = typename std::conditional<B, T, F>::type;
@@ -1792,16 +1801,18 @@ using cl_schar16 = cl_char16;
17921801
// As a result half values will be converted to the integer and passed as a
17931802
// kernel argument which is expected to be floating point number.
17941803
#ifndef __SYCL_DEVICE_ONLY__
1795-
template <int NumElements, typename CLType> struct alignas(CLType) half_vec {
1796-
std::array<half, NumElements> s;
1804+
template <int NumElements>
1805+
struct alignas(
1806+
cl::sycl::detail::VectorAlignment<half, NumElements>::value) half_vec {
1807+
std::array<half, cl::sycl::detail::VectorLength<NumElements>::value> s;
17971808
};
17981809

1799-
typedef half __half_t;
1800-
typedef half_vec<2, cl_half2> __half2_vec_t;
1801-
typedef half_vec<4, cl_half3> __half3_vec_t;
1802-
typedef half_vec<4, cl_half4> __half4_vec_t;
1803-
typedef half_vec<8, cl_half8> __half8_vec_t;
1804-
typedef half_vec<16, cl_half16> __half16_vec_t;
1810+
using __half_t = half;
1811+
using __half2_vec_t = half_vec<2>;
1812+
using __half3_vec_t = half_vec<4>;
1813+
using __half4_vec_t = half_vec<4>;
1814+
using __half8_vec_t = half_vec<8>;
1815+
using __half16_vec_t = half_vec<16>;
18051816
#endif
18061817

18071818
#define GET_CL_HALF_TYPE(target, num) __##target##num##_vec_t

sycl/test/basic_tests/aliases.cpp

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// RUN: %clangxx -fsycl %s -o %t.out -lOpenCL
2+
//==------------ aliases.cpp - SYCL type aliases test ----------------------==//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
#include <CL/sycl.hpp>
10+
#include <CL/sycl/detail/common.hpp>
11+
#include <cassert>
12+
#include <iostream>
13+
#include <type_traits>
14+
15+
using namespace std;
16+
17+
using cl_schar = cl_char;
18+
using cl_schar4 = cl_char4;
19+
20+
namespace s = cl::sycl;
21+
22+
#define CHECK_TYPE(TYPE) \
23+
static_assert(sizeof(cl_##TYPE) == sizeof(s::cl_##TYPE), "")
24+
25+
#define CHECK_SIZE(TYPE, SIZE) static_assert(sizeof(TYPE) == SIZE, "");
26+
27+
#define CHECK_SIZE_VEC_N(TYPE, N) \
28+
static_assert(N * sizeof(TYPE) == sizeof(s::vec<TYPE, N>), "");
29+
30+
#define CHECK_SIZE_VEC_N3(TYPE) \
31+
static_assert(sizeof(s::vec<TYPE, 3>) == sizeof(s::vec<TYPE, 4>), "");
32+
33+
#define CHECK_SIZE_VEC(TYPE) \
34+
CHECK_SIZE_VEC_N(TYPE, 2); \
35+
CHECK_SIZE_VEC_N3(TYPE); \
36+
CHECK_SIZE_VEC_N(TYPE, 4); \
37+
CHECK_SIZE_VEC_N(TYPE, 8); \
38+
CHECK_SIZE_VEC_N(TYPE, 16);
39+
40+
#define CHECK_SIZE_TYPE_I(TYPE, SIZE) \
41+
CHECK_SIZE(TYPE, SIZE) \
42+
static_assert(std::is_signed<TYPE>::value, "");
43+
44+
#define CHECK_SIZE_TYPE_UI(TYPE, SIZE) \
45+
CHECK_SIZE(TYPE, SIZE) \
46+
static_assert(std::is_unsigned<TYPE>::value, "");
47+
48+
#define CHECK_SIZE_TYPE_F(TYPE, SIZE) \
49+
CHECK_SIZE(TYPE, SIZE) \
50+
static_assert(std::numeric_limits<TYPE>::is_iec559, "");
51+
52+
int main() {
53+
CHECK_TYPE(bool);
54+
CHECK_TYPE(char);
55+
CHECK_TYPE(schar);
56+
CHECK_TYPE(uchar);
57+
CHECK_TYPE(short);
58+
CHECK_TYPE(ushort);
59+
CHECK_TYPE(half);
60+
CHECK_TYPE(int);
61+
CHECK_TYPE(uint);
62+
CHECK_TYPE(long);
63+
CHECK_TYPE(ulong);
64+
CHECK_TYPE(float);
65+
CHECK_TYPE(double);
66+
CHECK_TYPE(char2);
67+
CHECK_TYPE(uchar3);
68+
CHECK_TYPE(short4);
69+
CHECK_TYPE(ushort8);
70+
CHECK_TYPE(half16);
71+
CHECK_TYPE(int2);
72+
CHECK_TYPE(uint3);
73+
CHECK_TYPE(long4);
74+
CHECK_TYPE(schar4);
75+
CHECK_TYPE(ulong8);
76+
CHECK_TYPE(float16);
77+
CHECK_TYPE(double2);
78+
79+
// Table 4.93: Scalar data type aliases supported by SYCL
80+
CHECK_SIZE_TYPE_UI(s::byte, 1);
81+
82+
CHECK_SIZE_TYPE_I(s::cl_char, 1);
83+
CHECK_SIZE_TYPE_I(s::cl_short, 2);
84+
CHECK_SIZE_TYPE_I(s::cl_int, 4);
85+
CHECK_SIZE_TYPE_I(s::cl_long, 8);
86+
87+
CHECK_SIZE_TYPE_UI(s::cl_uchar, 1);
88+
CHECK_SIZE_TYPE_UI(s::cl_ushort, 2);
89+
CHECK_SIZE_TYPE_UI(s::cl_uint, 4);
90+
CHECK_SIZE_TYPE_UI(s::cl_ulong, 8);
91+
92+
CHECK_SIZE_TYPE_F(s::cl_float, 4);
93+
CHECK_SIZE_TYPE_F(s::cl_double, 8);
94+
CHECK_SIZE(s::cl_half, 2);
95+
96+
CHECK_SIZE_VEC(s::cl_char);
97+
CHECK_SIZE_VEC(s::cl_schar);
98+
CHECK_SIZE_VEC(s::cl_uchar);
99+
CHECK_SIZE_VEC(s::cl_short);
100+
CHECK_SIZE_VEC(s::cl_ushort);
101+
CHECK_SIZE_VEC(s::cl_half);
102+
CHECK_SIZE_VEC(s::cl_int);
103+
CHECK_SIZE_VEC(s::cl_uint);
104+
CHECK_SIZE_VEC(s::cl_long);
105+
CHECK_SIZE_VEC(s::cl_ulong);
106+
CHECK_SIZE_VEC(s::cl_float);
107+
CHECK_SIZE_VEC(s::cl_double);
108+
}

sycl/test/basic_tests/types.cpp

Lines changed: 46 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -6,119 +6,56 @@
66
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
77
//
88
//===----------------------------------------------------------------------===//
9-
#include <CL/sycl.hpp>
10-
#include <CL/sycl/detail/common.hpp>
11-
#include <cassert>
12-
#include <iostream>
13-
#include <type_traits>
14-
15-
using namespace std;
16-
17-
using cl_schar = cl_char;
18-
using cl_schar4 = cl_char4;
19-
20-
namespace s = cl::sycl;
21-
22-
#define CHECK_TYPE(type) \
23-
static_assert(sizeof(cl_##type) == sizeof(cl::sycl::cl_##type), "Wrong " \
24-
"size")
259

26-
#define CHECK_SIZE(T, S) static_assert(sizeof(T) == S, "Wrong size of type");
27-
28-
#define CHECK_SIZE_VEC_N(T, n) \
29-
static_assert(n * sizeof(T) == sizeof(cl::sycl::vec<T, n>), \
30-
"Wrong size of vec<type>");
31-
32-
#define CHECK_SIZE_VEC_N3(T) \
33-
static_assert(sizeof(cl::sycl::vec<T, 3>) == sizeof(cl::sycl::vec<T, 4>), \
34-
"Wrong size of vec<cl_type3>");
35-
36-
#define CHECK_SIZE_VEC(T) \
37-
CHECK_SIZE_VEC_N(T, 2); \
38-
CHECK_SIZE_VEC_N3(T); \
39-
CHECK_SIZE_VEC_N(T, 4); \
40-
CHECK_SIZE_VEC_N(T, 8); \
41-
CHECK_SIZE_VEC_N(T, 16);
10+
#include <CL/sycl.hpp>
4211

43-
#define CHECK_SIZE_TYPE_I(T, S) \
44-
CHECK_SIZE(T, S) \
45-
static_assert(std::is_signed<T>::value, "Expected signed type");
12+
template <typename T, int N> inline void checkVectorSizeAndAlignment() {
13+
using VectorT = cl::sycl::vec<T, N>;
14+
constexpr auto RealLength = (N != 3 ? N : 4);
15+
static_assert(sizeof(VectorT) == (sizeof(T) * RealLength),
16+
"Wrong size of vec<T, N>");
17+
static_assert(alignof(VectorT) == (alignof(T) * RealLength),
18+
"Wrong alignment of vec<T, N>");
19+
}
4620

47-
#define CHECK_SIZE_TYPE_UI(T, S) \
48-
CHECK_SIZE(T, S) \
49-
static_assert(std::is_unsigned<T>::value, "Expected unsigned type");
21+
template <typename T> inline void checkVectorsWithN() {
22+
checkVectorSizeAndAlignment<T, 1>();
23+
checkVectorSizeAndAlignment<T, 2>();
24+
checkVectorSizeAndAlignment<T, 3>();
25+
checkVectorSizeAndAlignment<T, 4>();
26+
checkVectorSizeAndAlignment<T, 8>();
27+
checkVectorSizeAndAlignment<T, 16>();
28+
}
5029

51-
#define CHECK_SIZE_TYPE_F(T, S) \
52-
CHECK_SIZE(T, S) \
53-
static_assert(std::numeric_limits<T>::is_iec559, \
54-
"Expected type conformed to the IEEE 754");
30+
inline void checkVectors() {
31+
checkVectorsWithN<half>();
32+
checkVectorsWithN<float>();
33+
checkVectorsWithN<double>();
34+
checkVectorsWithN<char>();
35+
checkVectorsWithN<signed char>();
36+
checkVectorsWithN<unsigned char>();
37+
checkVectorsWithN<signed short>();
38+
checkVectorsWithN<unsigned short>();
39+
checkVectorsWithN<signed int>();
40+
checkVectorsWithN<unsigned int>();
41+
checkVectorsWithN<signed long>();
42+
checkVectorsWithN<unsigned long>();
43+
checkVectorsWithN<signed long long>();
44+
checkVectorsWithN<unsigned long long>();
45+
checkVectorsWithN<::cl_char>();
46+
checkVectorsWithN<::cl_uchar>();
47+
checkVectorsWithN<::cl_short>();
48+
checkVectorsWithN<::cl_ushort>();
49+
checkVectorsWithN<::cl_int>();
50+
checkVectorsWithN<::cl_uint>();
51+
checkVectorsWithN<::cl_long>();
52+
checkVectorsWithN<::cl_ulong>();
53+
checkVectorsWithN<::cl_half>();
54+
checkVectorsWithN<::cl_float>();
55+
checkVectorsWithN<::cl_double>();
56+
}
5557

5658
int main() {
57-
CHECK_TYPE(bool);
58-
CHECK_TYPE(char);
59-
CHECK_TYPE(schar);
60-
CHECK_TYPE(uchar);
61-
CHECK_TYPE(short);
62-
CHECK_TYPE(ushort);
63-
CHECK_TYPE(half);
64-
CHECK_TYPE(int);
65-
CHECK_TYPE(uint);
66-
CHECK_TYPE(long);
67-
CHECK_TYPE(ulong);
68-
CHECK_TYPE(float);
69-
CHECK_TYPE(double);
70-
CHECK_TYPE(char2);
71-
CHECK_TYPE(uchar3);
72-
CHECK_TYPE(short4);
73-
CHECK_TYPE(ushort8);
74-
CHECK_TYPE(half16);
75-
CHECK_TYPE(int2);
76-
CHECK_TYPE(uint3);
77-
CHECK_TYPE(long4);
78-
CHECK_TYPE(schar4);
79-
CHECK_TYPE(ulong8);
80-
CHECK_TYPE(float16);
81-
CHECK_TYPE(double2);
82-
83-
// Table 4.93: Scalar data type aliases supported by SYCL
84-
CHECK_SIZE_TYPE_UI(cl::sycl::byte, 1);
85-
86-
CHECK_SIZE_TYPE_I(cl::sycl::cl_char, 1);
87-
CHECK_SIZE_TYPE_I(cl::sycl::cl_short, 2);
88-
CHECK_SIZE_TYPE_I(cl::sycl::cl_int, 4);
89-
CHECK_SIZE_TYPE_I(cl::sycl::cl_long, 8);
90-
91-
CHECK_SIZE_TYPE_UI(cl::sycl::cl_uchar, 1);
92-
CHECK_SIZE_TYPE_UI(cl::sycl::cl_ushort, 2);
93-
CHECK_SIZE_TYPE_UI(cl::sycl::cl_uint, 4);
94-
CHECK_SIZE_TYPE_UI(cl::sycl::cl_ulong, 8);
95-
96-
CHECK_SIZE_TYPE_F(cl::sycl::cl_float, 4);
97-
CHECK_SIZE_TYPE_F(cl::sycl::cl_double, 8);
98-
// CHECK_SIZE_TYPE_F(cl::sycl::cl_half, 2);
99-
100-
CHECK_SIZE_VEC(char);
101-
CHECK_SIZE_VEC(short);
102-
CHECK_SIZE_VEC(unsigned short);
103-
CHECK_SIZE_VEC(int);
104-
CHECK_SIZE_VEC(unsigned int);
105-
CHECK_SIZE_VEC(long);
106-
CHECK_SIZE_VEC(unsigned long);
107-
CHECK_SIZE_VEC(long long);
108-
CHECK_SIZE_VEC(unsigned long long);
109-
CHECK_SIZE_VEC(float);
110-
CHECK_SIZE_VEC(double);
111-
112-
CHECK_SIZE_VEC(s::cl_char);
113-
CHECK_SIZE_VEC(s::cl_schar);
114-
CHECK_SIZE_VEC(s::cl_uchar);
115-
CHECK_SIZE_VEC(s::cl_short);
116-
CHECK_SIZE_VEC(s::cl_ushort);
117-
CHECK_SIZE_VEC(s::cl_half);
118-
CHECK_SIZE_VEC(s::cl_int);
119-
CHECK_SIZE_VEC(s::cl_uint);
120-
CHECK_SIZE_VEC(s::cl_long);
121-
CHECK_SIZE_VEC(s::cl_ulong);
122-
CHECK_SIZE_VEC(s::cl_float);
123-
CHECK_SIZE_VEC(s::cl_double);
59+
checkVectors();
60+
return 0;
12461
}

0 commit comments

Comments
 (0)