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

Commit 3c06ec2

Browse files
authored
[ESIMD] Add smoke test for pack_mask/unpack_mask APIs. (#826)
* [ESIMD] Add smoke test for pack_mask/unpack_mask APIs. Signed-off-by: Konstantin S Bobrovsky <[email protected]>
1 parent 7f0ae77 commit 3c06ec2

File tree

1 file changed

+132
-0
lines changed

1 file changed

+132
-0
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
//==------- esimd_pack_unpack_mask.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 || hip
10+
// TODO: esimd_emulator fails due to unimplemented 'single_task()' method
11+
// XFAIL: esimd_emulator
12+
// RUN: %clangxx -fsycl %s -fsycl-device-code-split=per_kernel -o %t.out
13+
// RUN: %GPU_RUN_PLACEHOLDER %t.out
14+
//
15+
// Smoke test for the esimd pack_mask/unpack_mask APIs.
16+
17+
#include "../esimd_test_utils.hpp"
18+
19+
#include <CL/sycl.hpp>
20+
#include <sycl/ext/intel/experimental/esimd.hpp>
21+
22+
#include <iostream>
23+
24+
using namespace cl::sycl;
25+
using namespace sycl::ext::intel::experimental;
26+
using namespace sycl::ext::intel::experimental::esimd;
27+
28+
template <int, int> struct test_id;
29+
using MaskRawElemT = typename simd_mask<1>::raw_element_type;
30+
static inline constexpr int MAX_N = 32;
31+
32+
// The main test routine.
33+
template <int N, int TestCase, class InitF>
34+
bool test_impl(queue q, const char *title, InitF init_f) {
35+
std::cout << "Testing N=" << N << ", " << title << "...\n";
36+
37+
MaskRawElemT *test_data = sycl::malloc_shared<MaskRawElemT>(N, q);
38+
init_f(test_data);
39+
uint32_t *res_packed = sycl::malloc_shared<uint32_t>(1, q);
40+
MaskRawElemT *res_unpacked = sycl::malloc_shared<MaskRawElemT>(MAX_N, q);
41+
42+
try {
43+
auto e = q.submit([&](handler &cgh) {
44+
cgh.single_task<test_id<N, TestCase>>([=]() SYCL_ESIMD_KERNEL {
45+
simd_mask<N> m(test_data);
46+
uint32_t packed_m = pack_mask(m);
47+
res_packed[0] = packed_m;
48+
unpack_mask<MAX_N>(packed_m).copy_to(res_unpacked);
49+
});
50+
});
51+
e.wait_and_throw();
52+
} catch (sycl::exception const &e) {
53+
std::cout << " SYCL exception caught: " << e.what() << '\n';
54+
sycl::free(test_data, q);
55+
sycl::free(res_packed, q);
56+
sycl::free(res_unpacked, q);
57+
return false;
58+
}
59+
uint32_t gold_packed = 0;
60+
61+
for (int i = 0; i < N; i++) {
62+
if (test_data[i] != 0) {
63+
gold_packed |= (1 << i);
64+
}
65+
}
66+
int err_cnt = 0;
67+
68+
if (gold_packed != *res_packed) {
69+
++err_cnt;
70+
std::cout << " ERROR in pack_mask: 0x" << std::hex << (*res_packed)
71+
<< " != 0x" << gold_packed << std::dec << " [gold]\n";
72+
}
73+
for (unsigned i = 0; i < N; ++i) {
74+
if ((test_data[i] != 0) != (res_unpacked[i] == 1)) {
75+
++err_cnt;
76+
std::cout << " ERROR in lane " << i << ": (0x" << std::hex
77+
<< test_data[i] << "!=0) != (0x" << res_unpacked[i] << std::dec
78+
<< "==1) [gold]\n";
79+
}
80+
}
81+
for (unsigned i = N; i < MAX_N; ++i) {
82+
if (test_data[i] != 0) {
83+
++err_cnt;
84+
std::cout << " ERROR: non-zero lane " << i << ": 0x" << std::hex
85+
<< test_data[i] << std::dec << "\n";
86+
}
87+
}
88+
std::cout << (err_cnt > 0 ? " FAILED\n" : " Passed\n");
89+
sycl::free(test_data, q);
90+
sycl::free(res_packed, q);
91+
sycl::free(res_unpacked, q);
92+
return err_cnt > 0 ? false : true;
93+
}
94+
95+
template <int N> bool test(queue q) {
96+
bool passed = true;
97+
passed &= test_impl<N, 0>(q, "all zero", [=](MaskRawElemT *x) {
98+
for (int i = 0; i < N; i++) {
99+
x[i] = 0;
100+
}
101+
});
102+
passed &= test_impl<N, 1>(q, "all one", [=](MaskRawElemT *x) {
103+
for (int i = 0; i < N; i++) {
104+
x[i] = 1;
105+
}
106+
});
107+
passed &= test_impl<N, 2>(q, "misc", [=](MaskRawElemT *x) {
108+
for (int i = 0; i < N; i++) {
109+
x[i] = i % 3;
110+
}
111+
});
112+
return passed;
113+
}
114+
115+
int main(int argc, char **argv) {
116+
queue q(esimd_test::ESIMDSelector{}, esimd_test::createExceptionHandler());
117+
auto dev = q.get_device();
118+
std::cout << "Running on " << dev.get_info<info::device::name>() << "\n";
119+
120+
bool passed = true;
121+
passed &= test<1>(q);
122+
passed &= test<2>(q);
123+
passed &= test<7>(q);
124+
passed &= test<8>(q);
125+
passed &= test<16>(q);
126+
// TODO disabled due to compiler bug
127+
// passed &= test<31>(q);
128+
// passed &= test<32>(q);
129+
130+
std::cout << (passed ? "=== Test passed\n" : "=== Test FAILED\n");
131+
return passed ? 0 : 1;
132+
}

0 commit comments

Comments
 (0)