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

Commit 22f86b5

Browse files
authored
[ESIMD] Add smoke test for simd::replicate_vs_w_hs. (#799)
Signed-off-by: Konstantin S Bobrovsky <[email protected]>
1 parent f8430d9 commit 22f86b5

File tree

1 file changed

+191
-0
lines changed

1 file changed

+191
-0
lines changed

SYCL/ESIMD/api/replicate_smoke.cpp

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
//==------- replicate_smoke.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 -o %t.out
11+
// RUN: %GPU_RUN_PLACEHOLDER %t.out
12+
//
13+
// The test checks main functionality of the esimd::replicate_vs_w_hs function.
14+
15+
#include "../esimd_test_utils.hpp"
16+
17+
#include <CL/sycl.hpp>
18+
#include <iostream>
19+
#include <sycl/ext/intel/experimental/esimd.hpp>
20+
21+
using namespace cl::sycl;
22+
using namespace sycl::ext::intel::experimental::esimd;
23+
24+
template <class T> struct char_to_int {
25+
using type = typename std::conditional<
26+
sizeof(T) == 1,
27+
typename std::conditional<std::is_signed<T>::value, int, unsigned>::type,
28+
T>::type;
29+
};
30+
31+
template <class T> bool verify(T *data_arr, T *gold_arr, int NonZeroN, int N) {
32+
int err_cnt = 0;
33+
34+
for (unsigned i = 0; i < NonZeroN; ++i) {
35+
T val = data_arr[i];
36+
T gold = gold_arr[i];
37+
38+
if (val != gold) {
39+
if (++err_cnt < 10) {
40+
using T1 = typename char_to_int<T>::type;
41+
std::cout << " failed at index " << i << ": " << (T1)val
42+
<< " != " << (T1)gold << " (gold)\n";
43+
}
44+
}
45+
}
46+
if (err_cnt > 0) {
47+
std::cout << " pass rate: "
48+
<< ((float)(NonZeroN - err_cnt) / (float)NonZeroN) * 100.0f
49+
<< "% (" << (NonZeroN - err_cnt) << "/" << NonZeroN << ")\n";
50+
}
51+
for (unsigned i = NonZeroN; i < N; ++i) {
52+
T val = data_arr[i];
53+
T gold = (T)0;
54+
55+
if (val != gold) {
56+
if (++err_cnt < 10) {
57+
using T1 = typename char_to_int<T>::type;
58+
std::cout << " additional failure at index " << i << ": " << (T1)val
59+
<< " != " << (T1)gold << " (gold)\n";
60+
}
61+
}
62+
}
63+
return err_cnt == 0;
64+
}
65+
66+
template <class T> struct DataMgr {
67+
T *src;
68+
T *dst;
69+
70+
DataMgr(int N) {
71+
src = new T[N];
72+
dst = new T[N];
73+
74+
for (int i = 0; i < N; i++) {
75+
src[i] = (T)i;
76+
dst[i] = (T)0;
77+
}
78+
}
79+
80+
~DataMgr() {
81+
delete[] src;
82+
delete[] dst;
83+
}
84+
};
85+
86+
template <class T, int VL, int N, int Rep, int Vs, int W, int Hs>
87+
bool test_impl(queue q, int offset, T (&&gold)[N]) {
88+
std::cout << "Testing T=" << typeid(T).name() << " Rep=" << Rep << " "
89+
<< "Vs=" << Vs << " "
90+
<< "W=" << W << " "
91+
<< "Hs=" << Hs << " "
92+
<< "Off=" << offset << "...";
93+
94+
DataMgr<T> dm(VL);
95+
96+
try {
97+
sycl::buffer<T, 1> src_buf(dm.src, VL);
98+
sycl::buffer<T, 1> dst_buf(dm.dst, VL);
99+
100+
q.submit([&](handler &cgh) {
101+
auto src_acc = src_buf.template get_access<access::mode::read>(cgh);
102+
auto dst_acc = dst_buf.template get_access<access::mode::write>(cgh);
103+
104+
cgh.single_task([=]() SYCL_ESIMD_KERNEL {
105+
simd<T, VL> src(src_acc, 0);
106+
simd<T, N> res =
107+
src.template replicate_vs_w_hs<Rep, Vs, W, Hs>(offset);
108+
res.copy_to(dst_acc, 0);
109+
});
110+
}).wait_and_throw();
111+
} catch (sycl::exception const &e) {
112+
std::cout << "SYCL exception caught: " << e.what() << '\n';
113+
return false; // not success
114+
}
115+
bool passed = verify<T>(dm.dst, gold, N, VL);
116+
std::cout << (passed ? "ok" : "FAILED") << "\n";
117+
return passed;
118+
}
119+
120+
template <class T> bool test(queue q) {
121+
bool passed = true;
122+
// 'x' and '.' represent source elements, 'x' represent selected elements
123+
// Numbers in the result - source's elements ordinals
124+
125+
// test_impl: <class T, int VL, int N, int Rep, int Vs, int W, int Hs>
126+
127+
// clang-format off
128+
//|<----------- Vs=16 ----------->|
129+
// v-------v-------v W=3
130+
// . x . . . x . . . x . . . . . . \ Rep=2
131+
// . x . . . x . . . x . . . . . . /
132+
// |<- Hs=4->|
133+
// clang-format on
134+
passed &= test_impl<T, 32, 6, 2, 16, 3, 4>(
135+
q, 1 /*off*/,
136+
{// expected result, other elements are zeroes
137+
(T)1, (T)5, (T)9, (T)17, (T)21, (T)25});
138+
139+
// clang-format off
140+
//|<----------- Vs=17 ------------->|
141+
// v-------v-------v W=3
142+
// . x . . . x . . . x . . . . . . . \ Rep=2
143+
// . x . . . x . . . x . . . . . /
144+
// |<- Hs=4->|
145+
// clang-format on
146+
passed &= test_impl<T, 32, 6, 2, 17, 3, 4>(
147+
q, 1 /*off*/,
148+
{// expected result, other elements are zeroes
149+
(T)1, (T)5, (T)9, (T)18, (T)22, (T)26});
150+
151+
// clang-format off
152+
// AOS 7x3 => SOA 3x7:
153+
// x0y0z0x1y1z1x2y2z2x3y3z3x4y4z4x5y5z5x6y6z6
154+
// =>
155+
// x0x1x2x3x4x5x6y0y1y2y3y4y5y6z0z1z2z3z4z5z6
156+
// Rep=3, VS=1, HS=3, W=7
157+
// clang-format on
158+
passed &= test_impl<T, 21, 21, 3, 1, 7, 3>(
159+
q, 0 /*off*/,
160+
{// expected result, other elements are zeroes
161+
(T)0, (T)3, (T)6, (T)9, (T)12, (T)15, (T)18,
162+
(T)1, (T)4, (T)7, (T)10, (T)13, (T)16, (T)19,
163+
(T)2, (T)5, (T)8, (T)11, (T)14, (T)17, (T)20});
164+
165+
// . . . . . . . . . . x . . . . . . . . . . . . . . . . . . . . .
166+
passed &= test_impl<T, 32, 1, 1, 0, 1, 0>(
167+
q, 10 /*off*/,
168+
{
169+
(T)10 // expected result, other elements are zeroes
170+
});
171+
return passed;
172+
}
173+
174+
int main(int argc, char **argv) {
175+
queue q(esimd_test::ESIMDSelector{}, esimd_test::createExceptionHandler());
176+
auto dev = q.get_device();
177+
std::cout << "Running on " << dev.get_info<info::device::name>() << "\n";
178+
bool passed = true;
179+
180+
passed &= test<half>(q);
181+
passed &= test<unsigned char>(q);
182+
passed &= test<short>(q);
183+
passed &= test<unsigned short>(q);
184+
passed &= test<int>(q);
185+
passed &= test<uint64_t>(q);
186+
passed &= test<float>(q);
187+
passed &= test<double>(q);
188+
189+
std::cout << (passed ? "Test passed\n" : "Test FAILED\n");
190+
return passed ? 0 : 1;
191+
}

0 commit comments

Comments
 (0)