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

Commit 95fd782

Browse files
authored
[SYCL][ESIMD] Add test on logical not operator (#784)
* [SYCL][ESIMD] Add test on logical not operator
1 parent d43bc4e commit 95fd782

File tree

1 file changed

+154
-0
lines changed

1 file changed

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

0 commit comments

Comments
 (0)