Skip to content
This repository was archived by the owner on Mar 28, 2023. It is now read-only.

Commit 734b867

Browse files
authored
[SYCL] Add E2E ESIMD bit operations test. (#301)
* [SYCL] Add E2E ESIMD bit operations test. Signed-off-by: kbobrovs <[email protected]>
1 parent 878b041 commit 734b867

File tree

1 file changed

+146
-0
lines changed

1 file changed

+146
-0
lines changed

SYCL/ESIMD/api/esimd_bit_ops.cpp

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
//==------- esimd_bit_ops.cpp - DPC++ ESIMD on-device test ----------------==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
// REQUIRES: gpu
9+
// UNSUPPORTED: cuda
10+
// RUN: %clangxx -fsycl %s -fsycl-device-code-split=per_kernel -o %t.out
11+
// RUN: %GPU_RUN_PLACEHOLDER %t.out
12+
//
13+
// Smoke test for esimd bit operations APIs.
14+
15+
#include "../esimd_test_utils.hpp"
16+
17+
#include <CL/sycl.hpp>
18+
#include <sycl/ext/intel/experimental/esimd.hpp>
19+
20+
#include <iostream>
21+
22+
using namespace cl::sycl;
23+
using namespace sycl::ext::intel::experimental::esimd;
24+
25+
struct bit_op {
26+
enum { cbit, fbl, fbh, num_ops };
27+
};
28+
29+
template <typename T, int N, int Op> struct test_id;
30+
31+
template <typename T> struct char_to_int {
32+
using type = typename std::conditional<
33+
sizeof(T) == 1,
34+
typename std::conditional<std::is_signed<T>::value, int, unsigned>::type,
35+
T>::type;
36+
};
37+
38+
// The main test routine.
39+
template <typename T, int N, int Op> bool test(queue q) {
40+
const char *ops[bit_op::num_ops] = {"cbit", "fbl", "fbh"};
41+
std::cout << "Testing op=" << ops[Op] << " T=" << typeid(T).name()
42+
<< ", N=" << N << "...\n";
43+
44+
T val_all_zero{0};
45+
T val_all_one{static_cast<T>(~val_all_zero)};
46+
T val_two_one{static_cast<T>(T{1} << (sizeof(T) * 8 - 2) | 2)}; // 010...010
47+
48+
T vals[] = {val_all_zero, val_all_one, val_two_one};
49+
constexpr size_t num_vals = sizeof(vals) / sizeof(vals[0]);
50+
51+
constexpr size_t size = N * num_vals;
52+
unsigned int *A = sycl::malloc_shared<unsigned int>(num_vals, q);
53+
54+
for (unsigned int i = 0; i < num_vals; ++i) {
55+
A[i] = 0xFFFFffff;
56+
}
57+
58+
try {
59+
auto e = q.submit([&](handler &cgh) {
60+
cgh.single_task<test_id<T, N, Op>>([=]() SYCL_ESIMD_KERNEL {
61+
// TODO add test cases where each lane contains different value
62+
if constexpr (Op == bit_op::cbit) {
63+
A[0] = esimd_cbit(simd<T, N>{val_all_zero})[N / 2];
64+
A[1] = esimd_cbit(simd<T, N>{val_all_one})[N / 2];
65+
A[2] = esimd_cbit(simd<T, N>{val_two_one})[N / 2];
66+
} else if constexpr (Op == bit_op::fbl) {
67+
A[0] = esimd_fbl(simd<T, N>{val_all_zero})[N / 2];
68+
A[1] = esimd_fbl(simd<T, N>{val_all_one})[N / 2];
69+
A[2] = esimd_fbl(simd<T, N>{val_two_one})[N / 2];
70+
} else {
71+
static_assert(Op == bit_op::fbh);
72+
A[0] = esimd_fbh(simd<T, N>{val_all_zero})[N / 2];
73+
A[1] = esimd_fbh(simd<T, N>{val_all_one})[N / 2];
74+
A[2] = esimd_fbh(simd<T, N>{val_two_one})[N / 2];
75+
}
76+
});
77+
});
78+
e.wait_and_throw();
79+
} catch (cl::sycl::exception const &e) {
80+
std::cout << " SYCL exception caught: " << e.what() << '\n';
81+
sycl::free(A, q);
82+
return false;
83+
}
84+
85+
unsigned int Gold[size] = {
86+
// cbit:
87+
0, // all zero
88+
sizeof(T) * 8, // all one
89+
2, // two one
90+
// fbl:
91+
0xFFFFffff, // all zero
92+
0, // all one
93+
1, // two one
94+
// fbh:
95+
0xFFFFffff, // all zero
96+
std::is_signed<T>::value ? 0xFFFFffff : 0, // all one
97+
1 // two one
98+
};
99+
int err_cnt = 0;
100+
101+
using ValTy = typename char_to_int<T>::type;
102+
103+
for (unsigned i = 0; i < num_vals; ++i) {
104+
T gold = Gold[Op * num_vals + i];
105+
T val = A[i];
106+
std::cout << " " << (ValTy)vals[i] << ": ";
107+
108+
if (val != gold) {
109+
++err_cnt;
110+
std::cout << "ERROR. " << (ValTy)val << " != " << (ValTy)gold
111+
<< "(gold)\n";
112+
} else {
113+
std::cout << "ok\n";
114+
}
115+
}
116+
std::cout << (err_cnt > 0 ? " FAILED\n" : " Passed\n");
117+
sycl::free(A, q);
118+
return err_cnt > 0 ? false : true;
119+
}
120+
121+
int main(int argc, char **argv) {
122+
queue q(esimd_test::ESIMDSelector{}, esimd_test::createExceptionHandler());
123+
auto dev = q.get_device();
124+
std::cout << "Running on " << dev.get_info<info::device::name>() << "\n";
125+
126+
bool passed = true;
127+
passed &= test<char, 32, bit_op::cbit>(q);
128+
passed &= test<unsigned char, 16, bit_op::cbit>(q);
129+
passed &= test<short, 32, bit_op::cbit>(q);
130+
passed &= test<short, 16, bit_op::cbit>(q);
131+
passed &= test<unsigned short, 8, bit_op::cbit>(q);
132+
passed &= test<int, 32, bit_op::cbit>(q);
133+
passed &= test<unsigned int, 32, bit_op::cbit>(q);
134+
// TODO uncomment when implemenation is fixed to support 64-bit ints ops:
135+
// passed &= test<int64_t, 32, bit_op::cbit>(q);
136+
// passed &= test<uint64_t, 32, bit_op::cbit>(q);
137+
138+
passed &= test<int, 32, bit_op::fbl>(q);
139+
passed &= test<unsigned int, 32, bit_op::fbl>(q);
140+
141+
passed &= test<int, 32, bit_op::fbh>(q);
142+
passed &= test<unsigned int, 32, bit_op::fbh>(q);
143+
144+
std::cout << (passed ? "=== Test passed\n" : "=== Test FAILED\n");
145+
return passed ? 0 : 1;
146+
}

0 commit comments

Comments
 (0)