Skip to content

Commit 1b6d937

Browse files
authored
[SYCL][Graph] Add test for using spirv kernels in graphs (#13532)
Adds new tests to check that the sycl_ext_oneapi_kernel_compiler_spirv extension is compatible with sycl graphs.
1 parent 238753c commit 1b6d937

File tree

5 files changed

+128
-0
lines changed

5 files changed

+128
-0
lines changed

sycl/doc/extensions/experimental/sycl_ext_oneapi_graph.asciidoc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,6 +1799,12 @@ code `invalid` if a user tries to add them to a graph.
17991799
Removing this restriction is something we may look at for future revisions of
18001800
`sycl_ext_oneapi_graph`.
18011801

1802+
==== sycl_ext_oneapi_kernel_compiler_spirv
1803+
1804+
The kernels loaded using
1805+
link:../experimental/sycl_ext_oneapi_kernel_compiler_spirv.asciidoc[sycl_ext_oneapi_kernel_compiler_spirv]
1806+
behave as normal when used in graph nodes.
1807+
18021808
== Examples
18031809

18041810
[NOTE]
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %{build} -o %t.out
2+
// RUN: %{run} %t.out %S/../Inputs/Kernels/kernels.spv
3+
// Extra run to check for leaks in Level Zero using UR_L0_LEAKS_DEBUG
4+
// RUN: %if level_zero %{env SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 %{l0_leak_check} %{run} %t.out %S/../Inputs/Kernels/kernels.spv 2>&1 | FileCheck %s --implicit-check-not=LEAK %}
5+
// Extra run to check for immediate-command-list in Level Zero
6+
// RUN: %if level_zero && linux %{env SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=1 %{l0_leak_check} %{run} %t.out %S/../Inputs/Kernels/kernels.spv 2>&1 | FileCheck %s --implicit-check-not=LEAK %}
7+
8+
// REQUIRES: level_zero
9+
10+
#define GRAPH_E2E_EXPLICIT
11+
12+
#include "../Inputs/kernel_bundle_spirv.cpp"
5.21 KB
Binary file not shown.
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// Tests creating a node using a SPIR-V kernel imported with
2+
// sycl_ext_oneapi_kernel_compiler_spirv. The SPIR-V kernels used in this test
3+
// are identical to the ones used in KernelCompiler/Kernels/kernels.spv
4+
5+
#include "../graph_common.hpp"
6+
#include <fstream>
7+
8+
sycl::kernel_bundle<sycl::bundle_state::executable>
9+
loadKernelsFromFile(sycl::queue &Q, std::string FileName) {
10+
11+
// Read the SPIR-V module from disk.
12+
std::ifstream SpvStream(FileName, std::ios::binary);
13+
SpvStream.seekg(0, std::ios::end);
14+
size_t sz = SpvStream.tellg();
15+
SpvStream.seekg(0);
16+
std::vector<std::byte> Spv(sz);
17+
SpvStream.read(reinterpret_cast<char *>(Spv.data()), sz);
18+
19+
// Create a kernel bundle from the binary SPIR-V.
20+
sycl::kernel_bundle<sycl::bundle_state::ext_oneapi_source> KernelBundleSrc =
21+
exp_ext::create_kernel_bundle_from_source(
22+
Q.get_context(), exp_ext::source_language::spirv, Spv);
23+
24+
// Build the SPIR-V module for our device.
25+
sycl::kernel_bundle<sycl::bundle_state::executable> KernelBundleExe =
26+
exp_ext::build(KernelBundleSrc);
27+
return KernelBundleExe;
28+
}
29+
30+
int main(int, char **argv) {
31+
32+
const sycl::device Dev{sycl::default_selector_v};
33+
const sycl::context Ctx{Dev};
34+
35+
queue Queue{Ctx, Dev};
36+
37+
sycl::kernel_bundle KernelBundle = loadKernelsFromFile(Queue, argv[1]);
38+
const auto getKernel =
39+
[](sycl::kernel_bundle<sycl::bundle_state::executable> &bundle,
40+
const std::string &name) {
41+
return bundle.ext_oneapi_get_kernel(name);
42+
};
43+
44+
sycl::kernel kernel = getKernel(KernelBundle, "my_kernel");
45+
assert(kernel.get_backend() == backend::ext_oneapi_level_zero);
46+
47+
constexpr int N = 4;
48+
std::array<int, N> input_array{0, 1, 2, 3};
49+
std::array<int, N> output_array{};
50+
std::array<int, N> output_array2{};
51+
52+
sycl::buffer input_buffer(input_array.data(), sycl::range<1>(N));
53+
sycl::buffer output_buffer(output_array.data(), sycl::range<1>(N));
54+
sycl::buffer output_buffer2(output_array2.data(), sycl::range<1>(N));
55+
56+
input_buffer.set_write_back(false);
57+
output_buffer.set_write_back(false);
58+
output_buffer2.set_write_back(false);
59+
60+
{
61+
exp_ext::command_graph Graph{
62+
Queue.get_context(),
63+
Queue.get_device(),
64+
{exp_ext::property::graph::assume_buffer_outlives_graph{}}};
65+
66+
add_node(Graph, Queue, ([&](sycl::handler &CGH) {
67+
CGH.set_arg(
68+
0, input_buffer.get_access<sycl::access::mode::read>(CGH));
69+
CGH.set_arg(
70+
1, output_buffer.get_access<sycl::access::mode::write>(CGH));
71+
CGH.parallel_for(sycl::range<1>{N}, kernel);
72+
}));
73+
74+
add_node(Graph, Queue, ([&](sycl::handler &CGH) {
75+
CGH.set_arg(
76+
0, input_buffer.get_access<sycl::access::mode::read>(CGH));
77+
CGH.set_arg(
78+
1,
79+
output_buffer2.get_access<sycl::access::mode::write>(CGH));
80+
CGH.parallel_for(sycl::range<1>{N}, kernel);
81+
}));
82+
83+
auto GraphExec = Graph.finalize();
84+
85+
Queue.submit([&](handler &CGH) { CGH.ext_oneapi_graph(GraphExec); });
86+
Queue.wait_and_throw();
87+
}
88+
89+
host_accessor HostAccOutput(output_buffer);
90+
host_accessor HostAccOutput2(output_buffer2);
91+
92+
for (int i = 0; i < N; i++) {
93+
assert(HostAccOutput[i] == ((i * 2) + 100));
94+
assert(HostAccOutput2[i] == ((i * 2) + 100));
95+
}
96+
97+
return 0;
98+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %{build} -o %t.out
2+
// RUN: %{run} %t.out %S/../Inputs/Kernels/kernels.spv
3+
// Extra run to check for leaks in Level Zero using UR_L0_LEAKS_DEBUG
4+
// RUN: %if level_zero %{env SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=0 %{l0_leak_check} %{run} %t.out %S/../Inputs/Kernels/kernels.spv 2>&1 | FileCheck %s --implicit-check-not=LEAK %}
5+
// Extra run to check for immediate-command-list in Level Zero
6+
// RUN: %if level_zero && linux %{env SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=1 %{l0_leak_check} %{run} %t.out %S/../Inputs/Kernels/kernels.spv 2>&1 | FileCheck %s --implicit-check-not=LEAK %}
7+
8+
// REQUIRES: level_zero
9+
10+
#define GRAPH_E2E_RECORD_REPLAY
11+
12+
#include "../Inputs/kernel_bundle_spirv.cpp"

0 commit comments

Comments
 (0)