Skip to content

Commit 17e8f16

Browse files
[SYCL][E2E] Extend raw_kernel_arg extension testing (#15567)
This PR introduces tests for user-defined data types such as `struct`s
1 parent 3c1e0dc commit 17e8f16

File tree

2 files changed

+149
-0
lines changed

2 files changed

+149
-0
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// REQUIRES: aspect-usm_shared_allocations
2+
// REQUIRES: ocloc && level_zero
3+
4+
// RUN: %{build} -o %t.out
5+
// RUN: %{run} %t.out
6+
7+
// Tests raw_kernel_arg which is used to pass user-defined data types
8+
// (structures) as kernel arguments.
9+
#include <sycl/detail/core.hpp>
10+
#include <sycl/usm.hpp>
11+
12+
constexpr size_t NumArgs = 2;
13+
14+
struct __attribute__((packed)) kernel_arg_t {
15+
int in1;
16+
char in2;
17+
float in3;
18+
};
19+
20+
auto constexpr CLSource = R"===(
21+
struct __attribute__((packed)) kernel_arg_t {
22+
int in1;
23+
char in2;
24+
float in3;
25+
};
26+
27+
__kernel void Kernel(struct kernel_arg_t in, __global float4 *out) {
28+
out[0] = (float)in.in1 + (float)in.in2 + in.in3;
29+
}
30+
)===";
31+
32+
template <typename T>
33+
void SetArg(sycl::handler &CGH, T &&Arg, size_t Index, size_t Iteration) {
34+
// Pick how we set the arg based on the bit at Index in Iteration.
35+
if (Iteration & (1 << Index))
36+
CGH.set_arg(Index, sycl::ext::oneapi::experimental::raw_kernel_arg(
37+
&Arg, sizeof(T)));
38+
else
39+
CGH.set_arg(Index, Arg);
40+
}
41+
42+
int main() {
43+
sycl::queue Q;
44+
45+
auto SourceKB =
46+
sycl::ext::oneapi::experimental::create_kernel_bundle_from_source(
47+
Q.get_context(),
48+
sycl::ext::oneapi::experimental::source_language::opencl, CLSource);
49+
auto ExecKB = sycl::ext::oneapi::experimental::build(SourceKB);
50+
51+
int Failed = 0;
52+
53+
float *Out = sycl::malloc_shared<float>(1, Q);
54+
kernel_arg_t InVal = {42, 100, 1.23};
55+
56+
float Expected = static_cast<float>(InVal.in1) +
57+
static_cast<float>(InVal.in2) + InVal.in3;
58+
for (size_t I = 0; I < (2 >> (NumArgs - 1)); ++I) {
59+
Out[0] = 0.0f;
60+
Q.submit([&](sycl::handler &CGH) {
61+
SetArg(CGH, InVal, 0, I);
62+
SetArg(CGH, Out, 1, I);
63+
CGH.single_task(ExecKB.ext_oneapi_get_kernel("Kernel"));
64+
}).wait();
65+
66+
if (Out[0] != Expected) {
67+
std::cout << "Failed for iteration " << I << ": " << Out[0]
68+
<< " != " << Expected << std::endl;
69+
++Failed;
70+
}
71+
}
72+
73+
sycl::free(Out, Q);
74+
return Failed;
75+
}
76+
77+
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// REQUIRES: aspect-usm_shared_allocations
2+
// REQUIRES: ocloc && level_zero
3+
4+
// RUN: %{build} -o %t.out
5+
// RUN: %{run} %t.out
6+
7+
// Tests raw_kernel_arg which is used to pass OpenCL vector types as a special
8+
// case of struct data types.
9+
10+
#include <sycl/detail/core.hpp>
11+
#include <sycl/usm.hpp>
12+
#include <CL/cl.h>
13+
14+
constexpr size_t NumArgs = 4;
15+
16+
auto constexpr CLSource = R"===(
17+
__kernel void Kernel(int4 in1, char4 in2, __global float4 *out, float4 in3) {
18+
out[0] = convert_float4(in1) + convert_float4(in2) + in3;
19+
}
20+
)===";
21+
22+
template <typename T>
23+
void SetArg(sycl::handler &CGH, T &&Arg, size_t Index, size_t Iteration) {
24+
// Pick how we set the arg based on the bit at Index in Iteration.
25+
if (Iteration & (1 << Index))
26+
CGH.set_arg(Index, sycl::ext::oneapi::experimental::raw_kernel_arg(
27+
&Arg, sizeof(T)));
28+
else
29+
CGH.set_arg(Index, Arg);
30+
}
31+
32+
int main() {
33+
sycl::queue Q;
34+
35+
auto SourceKB =
36+
sycl::ext::oneapi::experimental::create_kernel_bundle_from_source(
37+
Q.get_context(),
38+
sycl::ext::oneapi::experimental::source_language::opencl, CLSource);
39+
auto ExecKB = sycl::ext::oneapi::experimental::build(SourceKB);
40+
41+
int Failed = 0;
42+
43+
cl_float4 *Out = sycl::malloc_shared<cl_float4>(1, Q);
44+
cl_int4 IntVal = {42, 42, 42, 42};
45+
cl_char4 CharVal = {100, 100, 100, 100};
46+
cl_float4 FloatVal = {1.23, 1.23, 1.23, 1.23};
47+
48+
float Expected = static_cast<float>(IntVal.s[0]) +
49+
static_cast<float>(CharVal.s[0]) + FloatVal.s[0];
50+
for (size_t I = 0; I < (2 >> (NumArgs - 1)); ++I) {
51+
Out[0].s[I] = 0.0f;
52+
Q.submit([&](sycl::handler &CGH) {
53+
SetArg(CGH, IntVal, 0, I);
54+
SetArg(CGH, CharVal, 1, I);
55+
SetArg(CGH, Out, 2, I);
56+
SetArg(CGH, FloatVal, 3, I);
57+
CGH.single_task(ExecKB.ext_oneapi_get_kernel("Kernel"));
58+
}).wait();
59+
60+
for (size_t Ind = 0; Ind < 4; ++Ind) {
61+
if (Out[0].s[Ind] != Expected) {
62+
std::cout << "Failed for iteration " << I << " at index " << Ind << ": "
63+
<< Out[0].s[Ind] << " != " << Expected << std::endl;
64+
++Failed;
65+
}
66+
}
67+
}
68+
69+
sycl::free(Out, Q);
70+
return Failed;
71+
}
72+

0 commit comments

Comments
 (0)