Skip to content

Commit 93e8ca3

Browse files
authored
[SYCL] Throw for invalid info::kernel::num_args query (#9061)
According to SYCL2020 spec: This descriptor may only be used to query a kernel that resides in a kernel bundle that was constructed using a backend specific interoperability function or to query a device built-in kernel, and the semantics of this descriptor are defined by each SYCL backend specification. Attempting to use this descriptor for other kernels throws an exception with the errc::invalid error code. Fow now the only one way to create such kernel bundle - use make_kernel(). And creating bundle from built-in kernels is not fully supported, so it should throw in most cases at the present time. Resolves #7630
1 parent 2826eb8 commit 93e8ca3

File tree

6 files changed

+72
-9
lines changed

6 files changed

+72
-9
lines changed

sycl/source/detail/kernel_impl.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,31 @@ bool kernel_impl::isCreatedFromSource() const {
9393
return MCreatedFromSource;
9494
}
9595

96+
bool kernel_impl::isBuiltInKernel(const device &Device) const {
97+
auto BuiltInKernels = Device.get_info<info::device::built_in_kernel_ids>();
98+
if (BuiltInKernels.empty())
99+
return false;
100+
std::string KernelName = get_info<info::kernel::function_name>();
101+
return (std::any_of(
102+
BuiltInKernels.begin(), BuiltInKernels.end(),
103+
[&KernelName](kernel_id &Id) { return Id.get_name() == KernelName; }));
104+
}
105+
106+
void kernel_impl::checkIfValidForNumArgsInfoQuery() const {
107+
if (MKernelBundleImpl->isInterop())
108+
return;
109+
auto Devices = MKernelBundleImpl->get_devices();
110+
if (std::any_of(Devices.begin(), Devices.end(),
111+
[this](device &Device) { return isBuiltInKernel(Device); }))
112+
return;
113+
114+
throw sycl::exception(
115+
sycl::make_error_code(errc::invalid),
116+
"info::kernel::num_args descriptor may only be used to query a kernel "
117+
"that resides in a kernel bundle constructed using a backend specific"
118+
"interoperability function or to query a device built-in kernel");
119+
}
120+
96121
} // namespace detail
97122
} // __SYCL_INLINE_VER_NAMESPACE(_V1)
98123
} // namespace sycl

sycl/source/detail/kernel_impl.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,9 @@ class kernel_impl {
186186
const KernelBundleImplPtr MKernelBundleImpl;
187187
bool MIsInterop = false;
188188
std::mutex MNoncacheableEnqueueMutex;
189+
190+
bool isBuiltInKernel(const device &Device) const;
191+
void checkIfValidForNumArgsInfoQuery() const;
189192
};
190193

191194
template <typename Param>
@@ -196,6 +199,10 @@ inline typename Param::return_type kernel_impl::get_info() const {
196199
// TODO implement
197200
assert(0 && "Not implemented");
198201
}
202+
203+
if constexpr (std::is_same_v<Param, info::kernel::num_args>)
204+
checkIfValidForNumArgsInfoQuery();
205+
199206
return get_kernel_info<Param>(this->getHandleRef(), getPlugin());
200207
}
201208

sycl/test-e2e/Basic/kernel_info.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,25 @@ int main() {
3636

3737
const std::string krnName = krn.get_info<info::kernel::function_name>();
3838
assert(!krnName.empty());
39-
const cl_uint krnArgCount = krn.get_info<info::kernel::num_args>();
40-
assert(krnArgCount > 0);
39+
40+
std::string ErrMsg = "";
41+
std::error_code Errc;
42+
bool ExceptionWasThrown = false;
43+
try {
44+
const cl_uint krnArgCount = krn.get_info<info::kernel::num_args>();
45+
} catch (exception &e) {
46+
ErrMsg = e.what();
47+
Errc = e.code();
48+
ExceptionWasThrown = true;
49+
}
50+
assert(ExceptionWasThrown && "Invalid using of \"info::kernel::num_args\" "
51+
"query should throw an exception.");
52+
assert(ErrMsg ==
53+
"info::kernel::num_args descriptor may only be used to query a kernel "
54+
"that resides in a kernel bundle constructed using a backend specific"
55+
"interoperability function or to query a device built-in kernel");
56+
assert(Errc == errc::invalid);
57+
4158
const context krnCtx = krn.get_info<info::kernel::context>();
4259
assert(krnCtx == q.get_context());
4360
const cl_uint krnRefCount = krn.get_info<info::kernel::reference_count>();

sycl/test-e2e/KernelAndProgram/kernel-bundle-get-kernel.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,11 @@ int main() {
3333
auto ExpectedKernelName =
3434
ExpectedKernel.get_info<sycl::info::kernel::function_name>();
3535

36-
auto FoundKernelNumArgs =
37-
FoundKernel.get_info<sycl::info::kernel::num_args>();
38-
auto ExpectedKernelNumArgs =
39-
ExpectedKernel.get_info<sycl::info::kernel::num_args>();
40-
4136
auto FoundKernelContext = FoundKernel.get_info<sycl::info::kernel::context>();
4237
auto ExpectedKernelContext =
4338
ExpectedKernel.get_info<sycl::info::kernel::context>();
4439

4540
assert(FoundKernelName == ExpectedKernelName);
46-
assert(FoundKernelNumArgs == ExpectedKernelNumArgs);
4741
assert(FoundKernelContext == ExpectedKernelContext);
4842

4943
return 0;

sycl/test-e2e/OnlineCompiler/online_compiler_L0.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,21 @@ sycl::kernel getSYCLKernelWithIL(sycl::queue &Queue,
5656
sycl::make_kernel_bundle<sycl::backend::ext_oneapi_level_zero,
5757
sycl::bundle_state::executable>(
5858
{ZeModule, sycl::ext::oneapi::level_zero::ownership::keep}, Context);
59-
return sycl::make_kernel<sycl::backend::ext_oneapi_level_zero>(
59+
60+
auto Kernel = sycl::make_kernel<sycl::backend::ext_oneapi_level_zero>(
6061
{SyclKB, ZeKernel, sycl::ext::oneapi::level_zero::ownership::keep},
6162
Context);
63+
64+
// Should not throw an exception
65+
try {
66+
auto num_args = Kernel.get_info<sycl::info::kernel::num_args>();
67+
(void)num_args;
68+
} catch (sycl::exception &e) {
69+
assert(false && "Using \"info::kernel::num_args\" query for valid kernel "
70+
"should not throw an exception.");
71+
}
72+
73+
return Kernel;
6274
}
6375
#endif // RUN_KERNELS
6476

sycl/test-e2e/Plugin/interop-opencl-make-kernel.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ int main() {
4545
assert(OpenCLError == CL_SUCCESS);
4646

4747
kernel Kernel = make_kernel<backend::opencl>(OpenCLKernel, Context);
48+
// Should not throw an exception
49+
try {
50+
auto num_args = Kernel.get_info<info::kernel::num_args>();
51+
(void)num_args;
52+
} catch (exception &e) {
53+
assert(false && "Using \"info::kernel::num_args\" query for valid kernel "
54+
"should not throw an exception.");
55+
}
4856

4957
// The associated kernel bundle should not contain the dummy-kernel.
5058
assert(!Kernel.get_kernel_bundle().has_kernel(get_kernel_id<DummyKernel>()));

0 commit comments

Comments
 (0)