15
15
#include < CL/sycl.hpp>
16
16
17
17
#include < cmath>
18
+ #include < unordered_set>
18
19
19
20
using namespace cl ::sycl;
20
21
21
- constexpr float flt_epsilon = 9.77e-4 ;
22
-
23
22
constexpr size_t N = 100 ;
24
23
25
- template <typename T> void assert_close (const T &C, const float ref) {
24
+ template <typename T> void assert_close (const T &C, const cl::sycl::half ref) {
26
25
for (size_t i = 0 ; i < N; i++) {
27
- float diff = C[i] - ref;
28
- assert (std::fabs (diff) < flt_epsilon);
26
+ auto diff = C[i] - ref;
27
+ assert (std::fabs (static_cast <float >(diff)) <
28
+ std::numeric_limits<cl::sycl::half>::epsilon ());
29
29
}
30
30
}
31
31
32
32
void verify_add (queue &q, buffer<half, 1 > &a, buffer<half, 1 > &b, range<1 > &r,
33
- const float ref) {
33
+ const half ref) {
34
34
buffer<half, 1 > c{r};
35
35
36
36
q.submit ([&](handler &cgh) {
@@ -45,7 +45,7 @@ void verify_add(queue &q, buffer<half, 1> &a, buffer<half, 1> &b, range<1> &r,
45
45
}
46
46
47
47
void verify_min (queue &q, buffer<half, 1 > &a, buffer<half, 1 > &b, range<1 > &r,
48
- const float ref) {
48
+ const half ref) {
49
49
buffer<half, 1 > c{r};
50
50
51
51
q.submit ([&](handler &cgh) {
@@ -60,7 +60,7 @@ void verify_min(queue &q, buffer<half, 1> &a, buffer<half, 1> &b, range<1> &r,
60
60
}
61
61
62
62
void verify_mul (queue &q, buffer<half, 1 > &a, buffer<half, 1 > &b, range<1 > &r,
63
- const float ref) {
63
+ const half ref) {
64
64
buffer<half, 1 > c{r};
65
65
66
66
q.submit ([&](handler &cgh) {
@@ -103,17 +103,97 @@ void verify_vec(queue &q) {
103
103
assert (e.get_access <access::mode::read>()[0 ] == 0 );
104
104
}
105
105
106
+ void verify_numeric_limits (queue &q) {
107
+ // Verify on host side
108
+ // Static member variables
109
+ std::numeric_limits<cl::sycl::half>::is_specialized;
110
+ std::numeric_limits<cl::sycl::half>::is_signed;
111
+ std::numeric_limits<cl::sycl::half>::is_integer;
112
+ std::numeric_limits<cl::sycl::half>::is_exact;
113
+ std::numeric_limits<cl::sycl::half>::has_infinity;
114
+ std::numeric_limits<cl::sycl::half>::has_quiet_NaN;
115
+ std::numeric_limits<cl::sycl::half>::has_signaling_NaN;
116
+ std::numeric_limits<cl::sycl::half>::has_denorm;
117
+ std::numeric_limits<cl::sycl::half>::has_denorm_loss;
118
+ std::numeric_limits<cl::sycl::half>::tinyness_before;
119
+ std::numeric_limits<cl::sycl::half>::traps;
120
+ std::numeric_limits<cl::sycl::half>::max_exponent10;
121
+ std::numeric_limits<cl::sycl::half>::max_exponent;
122
+ std::numeric_limits<cl::sycl::half>::min_exponent10;
123
+ std::numeric_limits<cl::sycl::half>::min_exponent;
124
+ std::numeric_limits<cl::sycl::half>::radix;
125
+ std::numeric_limits<cl::sycl::half>::max_digits10;
126
+ std::numeric_limits<cl::sycl::half>::digits;
127
+ std::numeric_limits<cl::sycl::half>::is_bounded;
128
+ std::numeric_limits<cl::sycl::half>::digits10;
129
+ std::numeric_limits<cl::sycl::half>::is_modulo;
130
+ std::numeric_limits<cl::sycl::half>::is_iec559;
131
+ std::numeric_limits<cl::sycl::half>::round_style;
132
+
133
+ // Static member functions
134
+ std::numeric_limits<cl::sycl::half>::min ();
135
+ std::numeric_limits<cl::sycl::half>::max ();
136
+ std::numeric_limits<cl::sycl::half>::lowest ();
137
+ std::numeric_limits<cl::sycl::half>::epsilon ();
138
+ std::numeric_limits<cl::sycl::half>::round_error ();
139
+ std::numeric_limits<cl::sycl::half>::infinity ();
140
+ std::numeric_limits<cl::sycl::half>::quiet_NaN ();
141
+ std::numeric_limits<cl::sycl::half>::signaling_NaN ();
142
+ std::numeric_limits<cl::sycl::half>::denorm_min ();
143
+
144
+ // Verify in kernel function for device side check
145
+ q.submit ([&](cl::sycl::handler &cgh) {
146
+ cgh.single_task <class kernel >([]() {
147
+ // Static member variables
148
+ std::numeric_limits<cl::sycl::half>::is_specialized;
149
+ std::numeric_limits<cl::sycl::half>::is_signed;
150
+ std::numeric_limits<cl::sycl::half>::is_integer;
151
+ std::numeric_limits<cl::sycl::half>::is_exact;
152
+ std::numeric_limits<cl::sycl::half>::has_infinity;
153
+ std::numeric_limits<cl::sycl::half>::has_quiet_NaN;
154
+ std::numeric_limits<cl::sycl::half>::has_signaling_NaN;
155
+ std::numeric_limits<cl::sycl::half>::has_denorm;
156
+ std::numeric_limits<cl::sycl::half>::has_denorm_loss;
157
+ std::numeric_limits<cl::sycl::half>::tinyness_before;
158
+ std::numeric_limits<cl::sycl::half>::traps;
159
+ std::numeric_limits<cl::sycl::half>::max_exponent10;
160
+ std::numeric_limits<cl::sycl::half>::max_exponent;
161
+ std::numeric_limits<cl::sycl::half>::min_exponent10;
162
+ std::numeric_limits<cl::sycl::half>::min_exponent;
163
+ std::numeric_limits<cl::sycl::half>::radix;
164
+ std::numeric_limits<cl::sycl::half>::max_digits10;
165
+ std::numeric_limits<cl::sycl::half>::digits;
166
+ std::numeric_limits<cl::sycl::half>::is_bounded;
167
+ std::numeric_limits<cl::sycl::half>::digits10;
168
+ std::numeric_limits<cl::sycl::half>::is_modulo;
169
+ std::numeric_limits<cl::sycl::half>::is_iec559;
170
+ std::numeric_limits<cl::sycl::half>::round_style;
171
+
172
+ // Static member functions
173
+ std::numeric_limits<cl::sycl::half>::min ();
174
+ std::numeric_limits<cl::sycl::half>::max ();
175
+ std::numeric_limits<cl::sycl::half>::lowest ();
176
+ std::numeric_limits<cl::sycl::half>::epsilon ();
177
+ std::numeric_limits<cl::sycl::half>::round_error ();
178
+ std::numeric_limits<cl::sycl::half>::infinity ();
179
+ std::numeric_limits<cl::sycl::half>::quiet_NaN ();
180
+ std::numeric_limits<cl::sycl::half>::signaling_NaN ();
181
+ std::numeric_limits<cl::sycl::half>::denorm_min ();
182
+ });
183
+ });
184
+ }
185
+
106
186
inline bool bitwise_comparison_fp16 (const half val, const uint16_t exp) {
107
- return reinterpret_cast <const uint16_t &>(val) == exp;
187
+ return reinterpret_cast <const uint16_t &>(val) == exp;
108
188
}
109
189
110
190
inline bool bitwise_comparison_fp32 (const half val, const uint32_t exp) {
111
191
const float fp32 = static_cast <float >(val);
112
- return reinterpret_cast <const uint32_t &>(fp32) == exp;
192
+ return reinterpret_cast <const uint32_t &>(fp32) == exp;
113
193
}
114
194
115
195
int main () {
116
- // We assert that the length is 1 because we use macro to select the device
196
+ // We assert that the length is 1 because we use env to select the device
117
197
assert (device::get_devices ().size () == 1 );
118
198
119
199
auto dev = device::get_devices ()[0 ];
@@ -137,6 +217,7 @@ int main() {
137
217
verify_mul (q, a, b, r, 10.0 );
138
218
verify_div (q, a, b, r, 2.5 );
139
219
verify_vec (q);
220
+ verify_numeric_limits (q);
140
221
141
222
if (!dev.is_host ()) {
142
223
return 0 ;
@@ -197,5 +278,10 @@ int main() {
197
278
assert (bitwise_comparison_fp32 (reinterpret_cast <const half &>(subnormal),
198
279
882900992 ));
199
280
281
+ // std::hash<cl::sycl::half>
282
+ std::unordered_set<half> sets;
283
+ sets.insert (1.2 );
284
+ assert (sets.find (1.2 ) != sets.end ());
285
+
200
286
return 0 ;
201
287
}
0 commit comments