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

Commit faee37a

Browse files
committed
[SYCL][ESIMD] Add test on simd bitwise not operator
1 parent d7452a5 commit faee37a

File tree

1 file changed

+176
-0
lines changed

1 file changed

+176
-0
lines changed
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
//==------- operator_bitwise_not.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, level_zero
9+
// XREQUIRES: gpu
10+
// TODO gpu and level_zero in REQUIRES due to only this platforms supported yet.
11+
// The current "REQUIRES" should be replaced with "gpu" only as mentioned in
12+
// "XREQUIRES".
13+
// UNSUPPORTED: cuda, hip
14+
// RUN: %clangxx -fsycl %s -fsycl-device-code-split=per_kernel -o %t.out
15+
// RUN: %GPU_RUN_PLACEHOLDER %t.out
16+
//
17+
// Test for simd bitwise not operator.
18+
// The test creates source simd instance with reference data and invokes bitwise
19+
// not operator.
20+
// The test verifies that data from simd is not corrupted after calling bitwise
21+
// not operator, that bitwise not operator return type is as expected and
22+
// bitwise not operator result values is correct.
23+
24+
#include "../mutator.hpp"
25+
#include "../shared_element.hpp"
26+
#include "common.hpp"
27+
// For std::abs
28+
#include <cmath>
29+
30+
using namespace sycl::ext::intel::experimental::esimd;
31+
using namespace esimd_test::api::functional;
32+
33+
// Descriptor class for the case of calling bitwise not operator.
34+
struct bitwise_not_operator {
35+
static std::string get_description() { return "bitwise not"; }
36+
37+
template <typename DataT, int NumElems>
38+
static bool call_operator(const DataT *const ref_data,
39+
DataT *const source_simd_result,
40+
DataT *const operator_result) {
41+
auto simd_obj = simd<DataT, NumElems>();
42+
simd_obj.copy_from(ref_data);
43+
auto bitwise_not_result = ~simd_obj;
44+
simd_obj.copy_to(source_simd_result);
45+
bitwise_not_result.copy_to(operator_result);
46+
return std::is_same_v<decltype(~simd_obj), simd<DataT, NumElems>>;
47+
}
48+
};
49+
50+
// Replace specific reference values to the bigger ones, so we can safely
51+
// substract `m_value` later.
52+
template <typename T> class For_bitwise_not {
53+
T m_value;
54+
55+
public:
56+
For_bitwise_not() = default;
57+
58+
void operator()(T &val) {
59+
if constexpr (std::is_signed_v<T>) {
60+
if (std::abs(value<T>::lowest() + 1) == (value<T>::max() - 1)) {
61+
if (val == value<T>::max()) {
62+
val -= 1;
63+
} else if (val == 0) {
64+
val = 1;
65+
}
66+
}
67+
}
68+
}
69+
};
70+
71+
// The main test routine.
72+
// Using functor class to be able to iterate over the pre-defined data types.
73+
template <typename TestCaseT, typename DataT, typename DimT> class run_test {
74+
static constexpr int NumElems = DimT::value;
75+
76+
public:
77+
bool operator()(sycl::queue &queue, const std::string &data_type) {
78+
bool passed = true;
79+
std::vector<DataT> ref_data = generate_ref_data<DataT, NumElems>();
80+
81+
mutate(ref_data, For_bitwise_not<DataT>());
82+
83+
// If current number of elements is equal to one, then run test with each
84+
// one value from reference data.
85+
// If current number of elements is greater than one, then run tests with
86+
// whole reference data.
87+
if constexpr (NumElems == 1) {
88+
for (size_t i = 0; i < ref_data.size(); ++i) {
89+
passed = run_verification(queue, {ref_data[i]}, data_type);
90+
}
91+
} else {
92+
passed = run_verification(queue, ref_data, data_type);
93+
}
94+
return passed;
95+
}
96+
97+
private:
98+
bool run_verification(sycl::queue &queue, const std::vector<DataT> &ref_data,
99+
const std::string &data_type) {
100+
assert(ref_data.size() == NumElems &&
101+
"Reference data size is not equal to the simd vector length.");
102+
103+
bool passed = true;
104+
105+
shared_allocator<DataT> allocator(queue);
106+
shared_vector<DataT> shared_ref_data(ref_data.begin(), ref_data.end(),
107+
allocator);
108+
shared_vector<DataT> source_simd_result(NumElems, allocator);
109+
shared_vector<DataT> operator_result(NumElems, allocator);
110+
111+
shared_element<bool> is_correct_type(queue, true);
112+
113+
queue.submit([&](sycl::handler &cgh) {
114+
const DataT *const ref = shared_ref_data.data();
115+
DataT *const source_simd_result_data_ptr = source_simd_result.data();
116+
DataT *const operator_result_data_ptr = operator_result.data();
117+
auto is_correct_type_ptr = is_correct_type.data();
118+
119+
cgh.single_task<Kernel<DataT, NumElems, TestCaseT>>(
120+
[=]() SYCL_ESIMD_KERNEL {
121+
*is_correct_type_ptr =
122+
TestCaseT::template call_operator<DataT, NumElems>(
123+
ref, source_simd_result_data_ptr, operator_result_data_ptr);
124+
});
125+
});
126+
queue.wait_and_throw();
127+
128+
for (size_t i = 0; i < NumElems; ++i) {
129+
if (!are_bitwise_equal(ref_data[i], source_simd_result[i])) {
130+
passed = false;
131+
132+
const auto description = operators::TestDescription<DataT, NumElems>(
133+
i, source_simd_result[i], ref_data[i], data_type);
134+
log::fail(description);
135+
}
136+
137+
DataT retrieved = operator_result[i];
138+
DataT expected = ~shared_ref_data[i];
139+
if (!are_bitwise_equal(expected, retrieved)) {
140+
passed = false;
141+
const auto description = operators::TestDescription<DataT, NumElems>(
142+
i, retrieved, expected, data_type);
143+
log::fail(description);
144+
}
145+
}
146+
147+
if (!is_correct_type.value()) {
148+
passed = false;
149+
log::note("Test failed due to type of the object that returns " +
150+
TestCaseT::get_description() +
151+
" operator is not equal to the expected one for simd<" +
152+
data_type + ", " + std::to_string(NumElems) + ">.");
153+
}
154+
155+
return passed;
156+
}
157+
};
158+
159+
int main(int, char **) {
160+
sycl::queue queue(esimd_test::ESIMDSelector{},
161+
esimd_test::createExceptionHandler());
162+
163+
bool passed = true;
164+
165+
const auto uint_types = get_tested_types<tested_types::uint>();
166+
const auto sint_types = get_tested_types<tested_types::sint>();
167+
const auto all_dims = get_all_dimensions();
168+
169+
passed &= for_all_combinations<run_test, bitwise_not_operator>(
170+
uint_types, all_dims, queue);
171+
passed &= for_all_combinations<run_test, bitwise_not_operator>(
172+
sint_types, all_dims, queue);
173+
174+
std::cout << (passed ? "=== Test passed\n" : "=== Test FAILED\n");
175+
return passed ? 0 : 1;
176+
}

0 commit comments

Comments
 (0)