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

Commit 0a032c5

Browse files
[SYCL] Add spec constants tests with kernel_bundle (#292)
* Add exception handling into test_set_and_get_on_host test
1 parent db7c529 commit 0a032c5

File tree

2 files changed

+264
-4
lines changed

2 files changed

+264
-4
lines changed

SYCL/SpecConstants/2020/common.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ inline bool operator!=(const custom_type_nested &lhs,
2929

3030
inline std::ostream &operator<<(std::ostream &out,
3131
const custom_type_nested &v) {
32-
return out << "custom_type_nested { .c = " << v.c << ", .f = " << v.f << "}"
33-
<< std::endl;
32+
return out << "custom_type_nested { .c = " << v.c << ", .f = " << v.f << "}";
3433
}
3534

3635
struct custom_type {
@@ -54,14 +53,15 @@ inline bool operator!=(const custom_type &lhs, const custom_type &rhs) {
5453

5554
inline std::ostream &operator<<(std::ostream &out, const custom_type &v) {
5655
return out << "custom_type { .n = \n\t" << v.n << ",\n .ull = " << v.ull
57-
<< "}" << std::endl;
56+
<< "}";
5857
}
5958

6059
template <typename T>
61-
bool check_value(const T &got, const T &ref, const std::string &variable_name) {
60+
bool check_value(const T &ref, const T &got, const std::string &variable_name) {
6261
if (got != ref) {
6362
std::cout << "Unexpected value of " << variable_name << ": " << got
6463
<< " (got) vs " << ref << " (expected)" << std::endl;
64+
return false;
6565
}
6666

6767
return true;
Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
// This test is intended to check basic operations with SYCL 2020 specialization
2+
// constants using sycl::kernel_bundle and sycl::kernel_handler APIs:
3+
// - test that specialization constants can be accessed in kernel and they
4+
// have their default values if `set_specialization_constants` wasn't called
5+
// - test that specialization constant values can be set and retrieved through
6+
// kernel_bundle APIs on host
7+
// - test that specialization constant values can be set through kernel_bundle
8+
// API and correctly retrieved within a kernel
9+
//
10+
// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out
11+
// FIXME: SYCL 2020 specialization constants are not supported on host device
12+
// RUN: %CPU_RUN_PLACEHOLDER %t.out
13+
// RUN: %GPU_RUN_PLACEHOLDER %t.out
14+
// FIXME: ACC devices use emulation path, which is not yet supported
15+
// FIXME: CUDA uses emulation path, which is not yet supported
16+
// UNSUPPORTED: cuda
17+
18+
#include <cstdlib>
19+
#include <iostream>
20+
#include <sycl/sycl.hpp>
21+
22+
#include "common.hpp"
23+
24+
constexpr sycl::specialization_id<int> int_id;
25+
constexpr sycl::specialization_id<double> double_id(3.14);
26+
constexpr sycl::specialization_id<custom_type> custom_type_id;
27+
28+
class TestDefaultValuesKernel;
29+
class EmptyKernel;
30+
class TestSetAndGetOnDevice;
31+
32+
bool test_default_values(sycl::queue q);
33+
bool test_set_and_get_on_host(sycl::queue q);
34+
bool test_set_and_get_on_device(sycl::queue q);
35+
36+
int main() {
37+
auto exception_handler = [&](sycl::exception_list exceptions) {
38+
for (std::exception_ptr const &e : exceptions) {
39+
try {
40+
std::rethrow_exception(e);
41+
} catch (sycl::exception const &e) {
42+
std::cout << "An async SYCL exception was caught: " << e.what()
43+
<< std::endl;
44+
std::exit(1);
45+
}
46+
}
47+
};
48+
49+
sycl::queue q(exception_handler);
50+
51+
if (!test_default_values(q)) {
52+
std::cout << "Test for default values of specialization constants failed!"
53+
<< std::endl;
54+
return 1;
55+
}
56+
57+
if (!test_set_and_get_on_host(q)) {
58+
std::cout << "Test for set and get API on host failed!" << std::endl;
59+
return 1;
60+
}
61+
62+
if (!test_set_and_get_on_device(q)) {
63+
std::cout << "Test for set and get API on device failed!" << std::endl;
64+
return 1;
65+
}
66+
67+
return 0;
68+
};
69+
70+
bool test_default_values(sycl::queue q) {
71+
if (!sycl::has_kernel_bundle<sycl::bundle_state::input>(q.get_context())) {
72+
std::cout << "Cannot obtain kernel_bundle in input state, skipping default "
73+
"values test"
74+
<< std::endl;
75+
// TODO: check that online_compielr aspec is not available
76+
return true;
77+
}
78+
79+
sycl::buffer<int> int_buffer(1);
80+
sycl::buffer<double> double_buffer(1);
81+
sycl::buffer<custom_type> custom_type_buffer(1);
82+
83+
auto input_bundle =
84+
sycl::get_kernel_bundle<sycl::bundle_state::input>(q.get_context());
85+
auto exec_bundle = sycl::build(input_bundle);
86+
87+
q.submit([&](sycl::handler &cgh) {
88+
cgh.use_kernel_bundle(exec_bundle);
89+
auto int_acc = int_buffer.get_access<sycl::access::mode::write>(cgh);
90+
auto double_acc = double_buffer.get_access<sycl::access::mode::write>(cgh);
91+
auto custom_type_acc =
92+
custom_type_buffer.get_access<sycl::access::mode::write>(cgh);
93+
cgh.single_task<TestDefaultValuesKernel>([=](sycl::kernel_handler kh) {
94+
int_acc[0] = kh.get_specialization_constant<int_id>();
95+
double_acc[0] = kh.get_specialization_constant<double_id>();
96+
custom_type_acc[0] = kh.get_specialization_constant<custom_type_id>();
97+
});
98+
});
99+
100+
auto int_acc = int_buffer.get_access<sycl::access::mode::read>();
101+
if (!check_value(
102+
0, int_acc[0],
103+
"integer specialization constant (defined without default value)"))
104+
return false;
105+
106+
auto double_acc = double_buffer.get_access<sycl::access::mode::read>();
107+
if (!check_value(3.14, double_acc[0], "double specialization constant"))
108+
return false;
109+
110+
auto custom_type_acc =
111+
custom_type_buffer.get_access<sycl::access::mode::read>();
112+
const custom_type custom_type_ref;
113+
if (!check_value(custom_type_ref, custom_type_acc[0],
114+
"custom_type specialization constant"))
115+
return false;
116+
117+
return true;
118+
}
119+
120+
bool test_set_and_get_on_host(sycl::queue q) {
121+
if (!sycl::has_kernel_bundle<sycl::bundle_state::input>(q.get_context())) {
122+
std::cout << "Cannot obtain kernel_bundle in input state, skipping default "
123+
"values test"
124+
<< std::endl;
125+
// TODO: check that online_compielr aspec is not available
126+
return true;
127+
}
128+
129+
unsigned errors = 0;
130+
131+
try {
132+
auto input_bundle =
133+
sycl::get_kernel_bundle<sycl::bundle_state::input>(q.get_context());
134+
135+
if (!input_bundle.contains_specialization_constants()) {
136+
std::cout
137+
<< "Obtained kernel_bundle is expected to contain specialization "
138+
"constants, but it doesn't!"
139+
<< std::endl;
140+
return false;
141+
}
142+
143+
// Check default values
144+
if (!check_value(
145+
0, input_bundle.get_specialization_constant<int_id>(),
146+
"integer specializaiton constant before setting any value"))
147+
++errors;
148+
149+
if (!check_value(3.14,
150+
input_bundle.get_specialization_constant<double_id>(),
151+
"double specializaiton constant before setting any value"))
152+
++errors;
153+
154+
custom_type custom_type_ref;
155+
if (!check_value(
156+
custom_type_ref,
157+
input_bundle.get_specialization_constant<custom_type_id>(),
158+
"custom_type specializaiton constant before setting any value"))
159+
++errors;
160+
161+
// Update values
162+
int new_int_value = 42;
163+
double new_double_value = 3.0;
164+
custom_type new_custom_type_value('b', 1.0, 12);
165+
166+
input_bundle.set_specialization_constant<int_id>(new_int_value);
167+
input_bundle.set_specialization_constant<double_id>(new_double_value);
168+
input_bundle.set_specialization_constant<custom_type_id>(
169+
new_custom_type_value);
170+
171+
// And re-check them again
172+
if (!check_value(
173+
new_int_value, input_bundle.get_specialization_constant<int_id>(),
174+
"integer specializaiton constant after setting a new value"))
175+
++errors;
176+
177+
if (!check_value(new_double_value,
178+
input_bundle.get_specialization_constant<double_id>(),
179+
"double specializaiton constant after setting a value"))
180+
++errors;
181+
182+
if (!check_value(
183+
new_custom_type_value,
184+
input_bundle.get_specialization_constant<custom_type_id>(),
185+
"custom_type specializaiton constant after setting a new value"))
186+
++errors;
187+
188+
// Let's try to build the bundle
189+
auto exec_bundle = sycl::build(input_bundle);
190+
191+
// And ensure that updated spec constant values are still there
192+
if (!check_value(new_int_value,
193+
exec_bundle.get_specialization_constant<int_id>(),
194+
"integer specializaiton constant after build"))
195+
++errors;
196+
197+
if (!check_value(new_double_value,
198+
exec_bundle.get_specialization_constant<double_id>(),
199+
"double specializaiton constant after build"))
200+
++errors;
201+
202+
if (!check_value(new_custom_type_value,
203+
exec_bundle.get_specialization_constant<custom_type_id>(),
204+
"custom_type specializaiton constant after build"))
205+
++errors;
206+
} catch (sycl::exception &e) {
207+
}
208+
209+
return 0 == errors;
210+
}
211+
212+
bool test_set_and_get_on_device(sycl::queue q) {
213+
sycl::buffer<int> int_buffer(1);
214+
sycl::buffer<double> double_buffer(1);
215+
sycl::buffer<custom_type> custom_type_buffer(1);
216+
217+
int new_int_value = 42;
218+
double new_double_value = 3.0;
219+
custom_type new_custom_type_value('b', 1.0, 12);
220+
221+
auto input_bundle =
222+
sycl::get_kernel_bundle<sycl::bundle_state::input>(q.get_context());
223+
input_bundle.set_specialization_constant<int_id>(new_int_value);
224+
input_bundle.set_specialization_constant<double_id>(new_double_value);
225+
input_bundle.set_specialization_constant<custom_type_id>(
226+
new_custom_type_value);
227+
auto exec_bundle = sycl::build(input_bundle);
228+
229+
q.submit([&](sycl::handler &cgh) {
230+
cgh.use_kernel_bundle(exec_bundle);
231+
auto int_acc = int_buffer.get_access<sycl::access::mode::write>(cgh);
232+
auto double_acc = double_buffer.get_access<sycl::access::mode::write>(cgh);
233+
auto custom_type_acc =
234+
custom_type_buffer.get_access<sycl::access::mode::write>(cgh);
235+
236+
cgh.single_task<TestSetAndGetOnDevice>([=](sycl::kernel_handler kh) {
237+
int_acc[0] = kh.get_specialization_constant<int_id>();
238+
double_acc[0] = kh.get_specialization_constant<double_id>();
239+
custom_type_acc[0] = kh.get_specialization_constant<custom_type_id>();
240+
});
241+
});
242+
243+
auto int_acc = int_buffer.get_access<sycl::access::mode::read>();
244+
if (!check_value(new_int_value, int_acc[0],
245+
"integer specialization constant"))
246+
return false;
247+
248+
auto double_acc = double_buffer.get_access<sycl::access::mode::read>();
249+
if (!check_value(new_double_value, double_acc[0],
250+
"double specialization constant"))
251+
return false;
252+
253+
auto custom_type_acc =
254+
custom_type_buffer.get_access<sycl::access::mode::read>();
255+
if (!check_value(new_custom_type_value, custom_type_acc[0],
256+
"custom_type specialization constant"))
257+
return false;
258+
259+
return true;
260+
}

0 commit comments

Comments
 (0)