1
- // ==--------------- bin_un_cmp_ops_heavy .cpp - DPC++ ESIMD on-device test -==//
1
+ // ==-------------- bin_and_cmp_ops_heavy .cpp - DPC++ ESIMD on-device test -==//
2
2
//
3
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
4
// See https://llvm.org/LICENSE.txt for license information.
5
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
6
//
7
7
// ===----------------------------------------------------------------------===//
8
- // REQUIRES: gpu
8
+ // Exclude PVC not to run same test cases twice (via the *_pvc.cpp variant).
9
+ // REQUIRES: gpu && !gpu-intel-pvc
9
10
// UNSUPPORTED: cuda || hip
10
11
// RUN: %clangxx -fsycl %s -o %t.out
11
12
// RUN: %GPU_RUN_PLACEHOLDER %t.out
29
30
30
31
using namespace sycl ;
31
32
using namespace sycl ::ext::intel::esimd;
33
+ using bfloat16 = sycl::ext::oneapi::experimental::bfloat16;
32
34
33
35
template <class T1 , class T2 , int VL, class OpClass , class Ops > class TestID ;
34
36
@@ -68,9 +70,11 @@ template <class T1, class T2, int VL, class OpClass,
68
70
template <class , class , class > class VerifyF ,
69
71
template <class , class , class > class InitF , class Ops >
70
72
bool test (Ops ops, queue &q, comp_t <T1, T2, OpClass> epsilon = 0 ) {
73
+ using T = comp_t <T1, T2, OpClass>;
71
74
// Log test case info
72
- std::cout << " Testing T1=" << typeid (T1).name () << " T2=" << typeid (T2).name ()
73
- << " , VL=" << VL << " ...\n " ;
75
+ std::cout << " Testing T1=" << esimd_test::type_name<T1>()
76
+ << " T2=" << esimd_test::type_name<T2>() << " , VL=" << VL
77
+ << " comp type: " << esimd_test::type_name<T>() << " ...\n " ;
74
78
std::cout << " Operations:" ;
75
79
esimd_test::iterate_ops (ops, [=](OpClass op) {
76
80
std::cout << " '" << esimd_test::Op2Str (op) << " '" ;
@@ -83,7 +87,6 @@ bool test(Ops ops, queue &q, comp_t<T1, T2, OpClass> epsilon = 0) {
83
87
T2 *B = sycl::malloc_shared<T2>(Size, q);
84
88
constexpr int NumOps = (int )Ops::size;
85
89
int CSize = NumOps * Size;
86
- using T = comp_t <T1, T2, OpClass>;
87
90
// Result array. For each pair of A[i] and B[i] elements it reserves NumOps
88
91
// elements to store result of all operations under test applied to the A[i]
89
92
// and B[i]
@@ -181,19 +184,19 @@ template <class T1, class T2, class OpClass> struct verify_strict {
181
184
bool operator ()(T res, T gold, OpClass op) { return res == gold; }
182
185
};
183
186
184
- #define EQ (x, y , epsilon ) \
185
- ((x) > (y) ? (x) - (y) <= epsilon : (y) - (x ) <= epsilon)
187
+ #define EQ (x, gold , epsilon ) \
188
+ ((x == gold) || (std::abs(( double )(x - gold) / ( double )gold ) <= epsilon) )
186
189
187
- template <class T1 , class T2 , class OpClass > struct verify_epsilon {
190
+ template <class T1 , class T2 , class OpClass , bool AllOps = false >
191
+ struct verify_epsilon {
188
192
using T = comp_t <T1, T2, OpClass>;
189
- T epsilon;
190
- verify_epsilon (T epsilon) : epsilon(epsilon) {}
193
+ double epsilon;
194
+ verify_epsilon (double epsilon) : epsilon(epsilon) {}
191
195
192
196
bool operator ()(T res, T gold, OpClass op) {
193
- if constexpr (std::is_same_v<OpClass, esimd_test::BinaryOp>) {
194
- if (op == esimd_test::BinaryOp::div) {
195
- return EQ (res, gold, epsilon);
196
- }
197
+ if (AllOps || ((std::is_same_v<OpClass, esimd_test::BinaryOp>)&&(
198
+ op == esimd_test::BinaryOp::div))) {
199
+ return EQ (res, gold, epsilon);
197
200
}
198
201
return res == gold;
199
202
}
@@ -245,6 +248,8 @@ template <class T1, class T2, class OpClass> struct init_for_shift {
245
248
// shortcuts for less clutter
246
249
template <class T1 , class T2 , class C > using VSf = verify_strict<T1, T2, C>;
247
250
template <class T1 , class T2 , class C > using VEf = verify_epsilon<T1, T2, C>;
251
+ template <class T1 , class T2 , class C >
252
+ using VEfa = verify_epsilon<T1, T2, C, true >;
248
253
template <class T1 , class T2 , class C > using VNf = verify_n<T1, T2, C>;
249
254
template <class T1 , class T2 , class C > using IDf = init_default<T1, T2, C>;
250
255
template <class T1 , class T2 , class C > using ISf = init_for_shift<T1, T2, C>;
@@ -257,7 +262,7 @@ int main(void) {
257
262
bool passed = true ;
258
263
using BinOp = esimd_test::BinaryOp;
259
264
260
- auto arith_ops = esimd_test::ArithBinaryOps ;
265
+ auto arith_ops = esimd_test::ArithBinaryOpsNoDiv ;
261
266
passed &= test<unsigned char , int , 1 , BinOp, VSf, IDf>(arith_ops, q);
262
267
passed &= test<char , float , 7 , BinOp, VEf, IDf>(arith_ops, q, 0 .000001f );
263
268
passed &= test<short , double , 7 , BinOp, VEf, IDf>(arith_ops, q, 1e-15 );
@@ -266,16 +271,49 @@ int main(void) {
266
271
passed &= test<half, unsigned int , 32 , BinOp, VSf, IDf>(arith_ops, q, 1 );
267
272
passed &= test<double , half, 7 , BinOp, VSf, IDf>(arith_ops, q);
268
273
passed &= test<short , uint64_t , 7 , BinOp, VSf, IDf>(arith_ops, q);
269
-
270
- auto int_ops =
271
- esimd_test::IntBinaryOpsNoShift; // different data needed for shift
274
+ #ifdef USE_BF16
275
+ passed &= test<bfloat16, int , 8 , BinOp, VSf, IDf>(arith_ops, q);
276
+ passed &= test<half, bfloat16, 7 , BinOp, VEfa, IDf>(arith_ops, q, 0.03 );
277
+ #endif // USE_BF16
278
+
279
+ // Test division separately, as error probability is higher.
280
+ auto div_op = esimd_test::BinaryOpSeq<BinOp::div>{};
281
+ passed &= test<unsigned char , int , 1 , BinOp, VSf, IDf>(div_op, q);
282
+ passed &= test<char , float , 7 , BinOp, VEf, IDf>(div_op, q, 0 .000001f );
283
+ #ifndef WA_BUG
284
+ passed &= test<short , double , 7 , BinOp, VSf, IDf>(div_op, q);
285
+ #endif // WA_BUG
286
+ passed &= test<float , float , 32 , BinOp, VEf, IDf>(div_op, q, 0 .000001f );
287
+ passed &= test<half, char , 1 , BinOp, verify_n, IDf>(div_op, q, 1 );
288
+ passed &= test<half, unsigned int , 32 , BinOp, VSf, IDf>(div_op, q, 1 );
289
+ #ifndef WA_BUG
290
+ passed &= test<double , half, 7 , BinOp, VSf, IDf>(div_op, q);
291
+ #endif // WA_BUG
292
+ passed &= test<short , uint64_t , 7 , BinOp, VSf, IDf>(div_op, q);
293
+ #ifdef USE_BF16
294
+ passed &= test<bfloat16, short , 8 , BinOp, VSf, IDf>(div_op, q);
295
+ passed &= test<half, bfloat16, 7 , BinOp, VEfa, IDf>(div_op, q, 0.03 );
296
+ #endif // USE_BF16
297
+
298
+ auto int_ops = esimd_test::IntBinaryOpsNoShiftNoDivRem;
272
299
passed &= test<unsigned char , unsigned int , 1 , BinOp, VSf, IDf>(int_ops, q);
273
300
passed &= test<char , uint64_t , 1 , BinOp, VSf, IDf>(int_ops, q);
274
301
passed &= test<uint64_t , char , 32 , BinOp, VSf, IDf>(int_ops, q);
275
302
passed &= test<int , short , 1 , BinOp, VSf, IDf>(int_ops, q);
276
303
passed &= test<short , int , 8 , BinOp, VSf, IDf>(int_ops, q);
277
304
passed &= test<int , int , 7 , BinOp, VSf, IDf>(int_ops, q);
278
305
306
+ auto int_div_ops = esimd_test::IntBinaryOpsDivRem;
307
+ passed &=
308
+ test<unsigned char , unsigned int , 1 , BinOp, VSf, IDf>(int_div_ops, q);
309
+ #ifndef WA_BUG
310
+ passed &= test<char , uint64_t , 1 , BinOp, VSf, IDf>(int_div_ops, q);
311
+ #endif // WA_BUG
312
+ passed &= test<uint64_t , char , 32 , BinOp, VSf, IDf>(int_div_ops, q);
313
+ passed &= test<int , short , 1 , BinOp, VSf, IDf>(int_div_ops, q);
314
+ passed &= test<short , int , 8 , BinOp, VSf, IDf>(int_div_ops, q);
315
+ passed &= test<int , int , 7 , BinOp, VSf, IDf>(int_div_ops, q);
316
+
279
317
auto sh_ops = esimd_test::BinaryOpSeq<BinOp::shl, BinOp::shr>{};
280
318
passed &= test<unsigned char , unsigned int , 1 , BinOp, VSf, ISf>(sh_ops, q);
281
319
passed &= test<char , int64_t , 1 , BinOp, VSf, ISf>(sh_ops, q);
@@ -294,6 +332,10 @@ int main(void) {
294
332
passed &= test<half, unsigned int , 32 , CmpOp, VSf, IDf>(cmp_ops, q, 1 );
295
333
passed &= test<double , half, 7 , CmpOp, VSf, IDf>(cmp_ops, q);
296
334
passed &= test<short , uint64_t , 7 , CmpOp, VSf, IDf>(cmp_ops, q);
335
+ #ifdef USE_BF16
336
+ passed &= test<bfloat16, int , 32 , CmpOp, VSf, IDf>(cmp_ops, q);
337
+ passed &= test<half, bfloat16, 7 , CmpOp, VSf, IDf>(cmp_ops, q);
338
+ #endif // USE_BF16
297
339
298
340
std::cout << (passed ? " Test PASSED\n " : " Test FAILED\n " );
299
341
return passed ? 0 : 1 ;
0 commit comments