Skip to content

Commit 304433f

Browse files
Add test for SYCL 2020 specialization constants (intel#255)
1 parent 4f11b9c commit 304433f

14 files changed

+265
-0
lines changed

SYCL/SpecConstants/2020/common.hpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Common functionality for SYCL 2020 specialization constants tests:
2+
// definition of custom data types, helper functions, etc.
3+
4+
#pragma once
5+
6+
#include <iostream>
7+
#include <string>
8+
9+
struct custom_type_nested {
10+
static constexpr char default_c_value = 'a';
11+
static constexpr float default_f_value = 1.7;
12+
13+
constexpr custom_type_nested() = default;
14+
constexpr custom_type_nested(char c, float f) : c(c), f(f) {}
15+
16+
char c = default_c_value;
17+
float f = default_f_value;
18+
};
19+
20+
inline bool operator==(const custom_type_nested &lhs,
21+
const custom_type_nested &rhs) {
22+
return lhs.c == rhs.c && lhs.f == rhs.f;
23+
}
24+
25+
inline bool operator!=(const custom_type_nested &lhs,
26+
const custom_type_nested &rhs) {
27+
return !(lhs == rhs);
28+
}
29+
30+
inline std::ostream &operator<<(std::ostream &out,
31+
const custom_type_nested &v) {
32+
return out << "custom_type_nested { .c = " << v.c << ", .f = " << v.f << "}"
33+
<< std::endl;
34+
}
35+
36+
struct custom_type {
37+
static constexpr unsigned long long default_ull_value = 42;
38+
39+
constexpr custom_type() = default;
40+
constexpr custom_type(char c, float f, unsigned long long ull)
41+
: n(c, f), ull(ull) {}
42+
43+
custom_type_nested n;
44+
unsigned long long ull = default_ull_value;
45+
};
46+
47+
inline bool operator==(const custom_type &lhs, const custom_type &rhs) {
48+
return lhs.n == rhs.n && lhs.ull == rhs.ull;
49+
}
50+
51+
inline bool operator!=(const custom_type &lhs, const custom_type &rhs) {
52+
return !(lhs == rhs);
53+
}
54+
55+
inline std::ostream &operator<<(std::ostream &out, const custom_type &v) {
56+
return out << "custom_type { .n = \n\t" << v.n << ",\n .ull = " << v.ull
57+
<< "}" << std::endl;
58+
}
59+
60+
template <typename T>
61+
bool check_value(const T &got, const T &ref, const std::string &variable_name) {
62+
if (got != ref) {
63+
std::cout << "Unexpected value of " << variable_name << ": " << got
64+
<< " (got) vs " << ref << " (expected)" << std::endl;
65+
}
66+
67+
return true;
68+
}
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
// This test is intended to check basic operations with SYCL 2020 specialization
2+
// constants using sycl::handler 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 within
6+
// command group scope
7+
// - test that specialization constant values can be set within command group
8+
// scope 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+
sycl::buffer<int> int_buffer(1);
72+
sycl::buffer<double> double_buffer(1);
73+
sycl::buffer<custom_type> custom_type_buffer(1);
74+
75+
q.submit([&](sycl::handler &cgh) {
76+
auto int_acc = int_buffer.get_access<sycl::access::mode::write>(cgh);
77+
auto double_acc = double_buffer.get_access<sycl::access::mode::write>(cgh);
78+
auto custom_type_acc =
79+
custom_type_buffer.get_access<sycl::access::mode::write>(cgh);
80+
cgh.single_task<TestDefaultValuesKernel>([=](sycl::kernel_handler kh) {
81+
int_acc[0] = kh.get_specialization_constant<int_id>();
82+
double_acc[0] = kh.get_specialization_constant<double_id>();
83+
custom_type_acc[0] = kh.get_specialization_constant<custom_type_id>();
84+
});
85+
});
86+
87+
auto int_acc = int_buffer.get_access<sycl::access::mode::read>();
88+
if (!check_value(
89+
0, int_acc[0],
90+
"integer specialization constant (defined without default value)"))
91+
return false;
92+
93+
auto double_acc = double_buffer.get_access<sycl::access::mode::read>();
94+
if (!check_value(3.14, double_acc[0], "double specialization constant"))
95+
return false;
96+
97+
auto custom_type_acc =
98+
custom_type_buffer.get_access<sycl::access::mode::read>();
99+
const custom_type custom_type_ref;
100+
if (!check_value(custom_type_ref, custom_type_acc[0],
101+
"custom_type specialization constant"))
102+
return false;
103+
104+
return true;
105+
}
106+
107+
bool test_set_and_get_on_host(sycl::queue q) {
108+
unsigned errors = 0;
109+
q.submit([&](sycl::handler &cgh) {
110+
if (!check_value(
111+
0, cgh.get_specialization_constant<int_id>(),
112+
"integer specializaiton constant before setting any value"))
113+
++errors;
114+
115+
if (!check_value(3.14, cgh.get_specialization_constant<double_id>(),
116+
"double specializaiton constant before setting any value"))
117+
++errors;
118+
119+
custom_type custom_type_ref;
120+
if (!check_value(
121+
custom_type_ref, cgh.get_specialization_constant<custom_type_id>(),
122+
"custom_type specializaiton constant before setting any value"))
123+
++errors;
124+
125+
int new_int_value = 8;
126+
double new_double_value = 3.0;
127+
custom_type new_custom_type_value('b', 1.0, 12);
128+
cgh.set_specialization_constant<int_id>(new_int_value);
129+
cgh.set_specialization_constant<double_id>(new_double_value);
130+
cgh.set_specialization_constant<custom_type_id>(new_custom_type_value);
131+
132+
if (!check_value(
133+
new_int_value, cgh.get_specialization_constant<int_id>(),
134+
"integer specializaiton constant after setting a new value"))
135+
++errors;
136+
137+
if (!check_value(
138+
new_double_value, cgh.get_specialization_constant<double_id>(),
139+
"double specializaiton constant after setting a new value"))
140+
++errors;
141+
142+
if (!check_value(
143+
new_custom_type_value,
144+
cgh.get_specialization_constant<custom_type_id>(),
145+
"custom_type specializaiton constant after setting a new value"))
146+
++errors;
147+
148+
cgh.single_task<EmptyKernel>([=]() {});
149+
});
150+
151+
return errors == 0;
152+
}
153+
154+
bool test_set_and_get_on_device(sycl::queue q) {
155+
sycl::buffer<int> int_buffer(1);
156+
sycl::buffer<double> double_buffer(1);
157+
sycl::buffer<custom_type> custom_type_buffer(1);
158+
159+
int new_int_value = 8;
160+
double new_double_value = 3.0;
161+
custom_type new_custom_type_value('b', 1.0, 12);
162+
163+
q.submit([&](sycl::handler &cgh) {
164+
auto int_acc = int_buffer.get_access<sycl::access::mode::write>(cgh);
165+
auto double_acc = double_buffer.get_access<sycl::access::mode::write>(cgh);
166+
auto custom_type_acc =
167+
custom_type_buffer.get_access<sycl::access::mode::write>(cgh);
168+
169+
cgh.set_specialization_constant<int_id>(new_int_value);
170+
cgh.set_specialization_constant<double_id>(new_double_value);
171+
cgh.set_specialization_constant<custom_type_id>(new_custom_type_value);
172+
173+
cgh.single_task<TestSetAndGetOnDevice>([=](sycl::kernel_handler kh) {
174+
int_acc[0] = kh.get_specialization_constant<int_id>();
175+
double_acc[0] = kh.get_specialization_constant<double_id>();
176+
custom_type_acc[0] = kh.get_specialization_constant<custom_type_id>();
177+
});
178+
});
179+
180+
auto int_acc = int_buffer.get_access<sycl::access::mode::read>();
181+
if (!check_value(new_int_value, int_acc[0],
182+
"integer specialization constant"))
183+
return false;
184+
185+
auto double_acc = double_buffer.get_access<sycl::access::mode::read>();
186+
if (!check_value(new_double_value, double_acc[0],
187+
"double specialization constant"))
188+
return false;
189+
190+
auto custom_type_acc =
191+
custom_type_buffer.get_access<sycl::access::mode::read>();
192+
if (!check_value(new_custom_type_value, custom_type_acc[0],
193+
"custom_type specialization constant"))
194+
return false;
195+
196+
return true;
197+
}

0 commit comments

Comments
 (0)