Skip to content

Commit 8f33b32

Browse files
[SYCL] Kernel Compiler ensures build option flags are passed all the way through with OpenCL C. (#18853)
The KernelCompiler has this `extractXsFlags` feature for handling the build options when compiling SYCL sources. This inadvertently overlooked the use case for OpenCL C, so I'm adding it here, along with a test. --------- Signed-off-by: Chris Perkins <[email protected]>
1 parent 2e0d73c commit 8f33b32

File tree

2 files changed

+86
-8
lines changed

2 files changed

+86
-8
lines changed

sycl/source/detail/device_image_impl.hpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,7 @@ class device_image_impl {
747747
if (!FetchedFromCache)
748748
UrProgram = createProgramFromSource(Devices, BuildOptions, LogPtr);
749749

750-
std::string XsFlags = extractXsFlags(BuildOptions);
750+
std::string XsFlags = extractXsFlags(BuildOptions, MRTCBinInfo->MLanguage);
751751
auto Res = Adapter->call_nocheck<UrApiKind::urProgramBuildExp>(
752752
UrProgram, DeviceVec.size(), DeviceVec.data(), XsFlags.c_str());
753753
if (Res == UR_RESULT_ERROR_UNSUPPORTED_FEATURE) {
@@ -850,15 +850,20 @@ class device_image_impl {
850850
}
851851

852852
static std::string
853-
extractXsFlags(const std::vector<sycl::detail::string_view> &BuildOptions) {
853+
extractXsFlags(const std::vector<sycl::detail::string_view> &BuildOptions,
854+
syclex::source_language lang) {
854855
std::stringstream SS;
855856
for (sycl::detail::string_view Option : BuildOptions) {
856-
std::string_view OptionSV{Option};
857-
auto Where = OptionSV.find("-Xs");
858-
if (Where != std::string_view::npos) {
859-
Where += 3;
860-
std::string_view Flags = OptionSV.substr(Where);
861-
SS << trimXsFlags(Flags) << " ";
857+
if (lang == syclex::source_language::sycl) {
858+
std::string_view OptionSV{Option};
859+
auto Where = OptionSV.find("-Xs");
860+
if (Where != std::string_view::npos) {
861+
Where += 3;
862+
std::string_view Flags = OptionSV.substr(Where);
863+
SS << trimXsFlags(Flags) << " ";
864+
}
865+
} else {
866+
SS << std::string_view{Option} << " ";
862867
}
863868
}
864869
return SS.str();
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// REQUIRES: ocloc && (opencl || level_zero)
2+
// UNSUPPORTED: accelerator
3+
// UNSUPPORTED-INTENDED: while accelerator is AoT only, this cannot run there.
4+
5+
// RUN: %{build} -o %t.out
6+
// RUN: %{run} %t.out
7+
8+
// This test ensures that the Kernel Compiler build option flags
9+
// are passed all the way through to the final binary when using OpenCL C
10+
// source.
11+
12+
#include <cmath>
13+
14+
#include <sycl/detail/core.hpp>
15+
#include <sycl/kernel_bundle.hpp>
16+
#include <sycl/usm.hpp>
17+
18+
namespace syclex = sycl::ext::oneapi::experimental;
19+
20+
const int N = 8;
21+
const char *KernelCLSource = "__kernel void sqrt_test(__global float* A) {"
22+
" __private int x = get_global_id(0);"
23+
" __private int y = get_global_id(1);"
24+
" __private int w = get_global_size(1);"
25+
" __private int address = x * w + y;"
26+
" A[address] = sqrt(A[address]);"
27+
"}";
28+
29+
int main(void) {
30+
// Only one device is supported at this time, so we limit the queue and
31+
// context to that.
32+
sycl::device d{sycl::default_selector_v};
33+
sycl::context ctx{d};
34+
sycl::queue q{ctx, d};
35+
36+
bool ok =
37+
q.get_device().ext_oneapi_can_build(syclex::source_language::opencl);
38+
if (!ok) {
39+
std::cout << "Apparently this device does not support OpenCL C source "
40+
"kernel bundle extension: "
41+
<< q.get_device().get_info<sycl::info::device::name>()
42+
<< std::endl;
43+
return 0;
44+
}
45+
46+
auto kb_src = syclex::create_kernel_bundle_from_source(
47+
ctx, syclex::source_language::opencl, KernelCLSource);
48+
auto kb_exe =
49+
syclex::build(kb_src, syclex::properties{syclex::build_options(
50+
"-cl-fp32-correctly-rounded-divide-sqrt")});
51+
sycl::kernel sqrt_test = kb_exe.ext_oneapi_get_kernel("sqrt_test");
52+
53+
float *A = sycl::malloc_shared<float>(N, q);
54+
for (int i = 0; i < N; i++)
55+
A[i] = static_cast<float>(i) / N;
56+
57+
q.submit([&](sycl::handler &cgh) {
58+
cgh.set_args(A);
59+
sycl::nd_range ndr{{N}, {1}};
60+
cgh.parallel_for(ndr, sqrt_test);
61+
}).wait();
62+
63+
for (int i = 0; i < N; i++) {
64+
float diff = A[i] - std::sqrt(static_cast<float>(i) / N);
65+
if (diff != 0.0) {
66+
printf("i:%d diff:%.2e\n", i, diff);
67+
return 1; // Error
68+
}
69+
}
70+
sycl::free(A, q);
71+
72+
return 0;
73+
}

0 commit comments

Comments
 (0)