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

Commit 38486e7

Browse files
authored
[ESIMD] Add smoke test for simd_obj_impl::any/all. (#802)
* [ESIMD] Add smoke test for simd_obj_impl::any/all. Signed-off-by: Konstantin S Bobrovsky <[email protected]>
1 parent 22f86b5 commit 38486e7

File tree

1 file changed

+153
-0
lines changed

1 file changed

+153
-0
lines changed

SYCL/ESIMD/api/simd_any_all.cpp

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
//==------- esimd_any_all.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+
// 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 any/all 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;
24+
using namespace sycl::ext::intel::experimental::esimd;
25+
26+
struct bit_op {
27+
enum { any, all, num_ops };
28+
};
29+
30+
template <typename T, int N, int Op> struct test_id;
31+
32+
template <typename T> struct char_to_int {
33+
using type = typename std::conditional<
34+
sizeof(T) == 1,
35+
typename std::conditional<std::is_signed<T>::value, int, unsigned>::type,
36+
T>::type;
37+
};
38+
39+
// The main test routine.
40+
template <typename T, int N, int Op> bool test_impl(queue q) {
41+
const char *ops[bit_op::num_ops] = {"any", "all"};
42+
std::cout << "Testing op=" << ops[Op] << " T=" << typeid(T).name()
43+
<< ", N=" << N << "...\n";
44+
45+
simd<T, N> all_zero((T)0);
46+
simd<T, N> all_one((T)1);
47+
if (std::is_signed_v<T>) {
48+
all_one[0] = -1;
49+
}
50+
simd<T, N> all_two((T)2); // check that non-zero with LSB=0 counts as 'set'
51+
if (std::is_signed_v<T>) {
52+
all_two[N - 1] = -2;
53+
}
54+
simd<T, N> zero_two((T)0);
55+
56+
if (N > 1) {
57+
zero_two[1] = 2;
58+
}
59+
60+
simd<T, N> test_vals_arr[] = {all_zero, all_one, all_two, zero_two};
61+
constexpr size_t num_vals = sizeof(test_vals_arr) / sizeof(test_vals_arr[0]);
62+
T *test_vals = sycl::malloc_shared<T>(num_vals * N, q);
63+
uint16_t *res = sycl::malloc_shared<uint16_t>(num_vals, q);
64+
65+
for (unsigned int i = 0; i < num_vals; ++i) {
66+
res[i] = 0xFFff;
67+
}
68+
memcpy(test_vals, test_vals_arr, sizeof(test_vals_arr));
69+
70+
try {
71+
auto e = q.submit([&](handler &cgh) {
72+
cgh.single_task<test_id<T, N, Op>>([=]() SYCL_ESIMD_KERNEL {
73+
for (int i = 0; i < num_vals; i++) {
74+
simd<T, N> src(test_vals + i * N);
75+
76+
if constexpr (Op == bit_op::any) {
77+
res[i] = src.any();
78+
} else if constexpr (Op == bit_op::all) {
79+
res[i] = src.all();
80+
}
81+
}
82+
});
83+
});
84+
e.wait_and_throw();
85+
} catch (cl::sycl::exception const &e) {
86+
std::cout << " SYCL exception caught: " << e.what() << '\n';
87+
sycl::free(res, q);
88+
sycl::free(test_vals, q);
89+
return false;
90+
}
91+
92+
unsigned int Gold[num_vals * bit_op::num_ops] = {
93+
// any:
94+
0, // all zero
95+
1, // all one
96+
1, // all two
97+
1, // zero, two
98+
// all:
99+
0, // all zero
100+
1, // all one
101+
1, // all two
102+
0, // zero, two
103+
};
104+
int err_cnt = 0;
105+
106+
using ValTy = typename char_to_int<T>::type;
107+
108+
for (unsigned i = 0; i < num_vals; ++i) {
109+
if ((N == 1) && (i == 3)) {
110+
continue; // (zero, two) testcase not available for single element
111+
}
112+
T gold = Gold[Op * num_vals + i];
113+
T val = res[i];
114+
std::cout << " " << ops[Op] << "(" << (simd<ValTy, N>)test_vals_arr[i]
115+
<< ") = " << (ValTy)val;
116+
117+
if (val != gold) {
118+
++err_cnt;
119+
std::cout << " ERROR. " << (ValTy)val << " != " << (ValTy)gold
120+
<< "(gold)\n";
121+
} else {
122+
std::cout << " (ok)\n";
123+
}
124+
}
125+
std::cout << (err_cnt > 0 ? " FAILED\n" : " Passed\n");
126+
sycl::free(res, q);
127+
sycl::free(test_vals, q);
128+
return err_cnt > 0 ? false : true;
129+
}
130+
131+
template <class T1, class T2> bool test(queue q) {
132+
bool passed = true;
133+
passed &= test_impl<T1, 32, bit_op::any>(q);
134+
passed &= test_impl<T1, 8, bit_op::all>(q);
135+
passed &= test_impl<T2, 3, bit_op::any>(q);
136+
passed &= test_impl<T2, 1, bit_op::all>(q);
137+
return passed;
138+
}
139+
140+
int main(int argc, char **argv) {
141+
queue q(esimd_test::ESIMDSelector{}, esimd_test::createExceptionHandler());
142+
auto dev = q.get_device();
143+
std::cout << "Running on " << dev.get_info<info::device::name>() << "\n";
144+
145+
bool passed = true;
146+
passed &= test<int8_t, uint8_t>(q);
147+
passed &= test<int16_t, uint16_t>(q);
148+
passed &= test<int32_t, uint32_t>(q);
149+
passed &= test<int64_t, uint64_t>(q);
150+
151+
std::cout << (passed ? "=== Test passed\n" : "=== Test FAILED\n");
152+
return passed ? 0 : 1;
153+
}

0 commit comments

Comments
 (0)