Skip to content

Commit 18899cc

Browse files
mmoadelibader
andauthored
[SYCL] Diagnose local accessor use in single_task or parallel_for(range) (#8581)
* According to [local accessors](https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#sec:accessor.local) of the SYCL specification, a local accessor must not be used in a SYCL kernel function that is invoked via single_task or via the simple form of parallel_for that takes a range parameter. * Add test. --------- Co-authored-by: Alexey Bader <[email protected]>
1 parent 4a4702e commit 18899cc

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

sycl/include/sycl/handler.hpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,32 @@ class __SYCL_EXPORT handler {
354354
PI_ERROR_INVALID_OPERATION);
355355
}
356356

357+
constexpr static int AccessTargetMask = 0x7ff;
358+
/// According to section 4.7.6.11. of the SYCL specification, a local accessor
359+
/// must not be used in a SYCL kernel function that is invoked via single_task
360+
/// or via the simple form of parallel_for that takes a range parameter.
361+
template <typename KernelName, typename KernelType>
362+
void throwOnLocalAccessorMisuse() const {
363+
using NameT =
364+
typename detail::get_kernel_name_t<KernelName, KernelType>::name;
365+
using KI = sycl::detail::KernelInfo<NameT>;
366+
367+
auto *KernelArgs = &KI::getParamDesc(0);
368+
369+
for (unsigned I = 0; I < KI::getNumParams(); ++I) {
370+
const detail::kernel_param_kind_t &Kind = KernelArgs[I].kind;
371+
const access::target AccTarget =
372+
static_cast<access::target>(KernelArgs[I].info & AccessTargetMask);
373+
if ((Kind == detail::kernel_param_kind_t::kind_accessor) &&
374+
(AccTarget == target::local))
375+
throw sycl::exception(
376+
make_error_code(errc::kernel_argument),
377+
"A local accessor must not be used in a SYCL kernel function "
378+
"that is invoked via single_task or via the simple form of "
379+
"parallel_for that takes a range parameter.");
380+
}
381+
}
382+
357383
/// Extracts and prepares kernel arguments from the lambda using integration
358384
/// header.
359385
void
@@ -906,6 +932,7 @@ class __SYCL_EXPORT handler {
906932
void parallel_for_lambda_impl(range<Dims> NumWorkItems,
907933
KernelType KernelFunc) {
908934
throwIfActionIsCreated();
935+
throwOnLocalAccessorMisuse<KernelName, KernelType>();
909936
using LambdaArgType = sycl::detail::lambda_arg_type<KernelType, item<Dims>>;
910937

911938
// If 1D kernel argument is an integral type, convert it to sycl::item<1>
@@ -1387,6 +1414,7 @@ class __SYCL_EXPORT handler {
13871414
ext::oneapi::experimental::detail::empty_properties_t>
13881415
void single_task_lambda_impl(_KERNELFUNCPARAM(KernelFunc)) {
13891416
throwIfActionIsCreated();
1417+
throwOnLocalAccessorMisuse<KernelName, KernelType>();
13901418
// TODO: Properties may change the kernel function, so in order to avoid
13911419
// conflicts they should be included in the name.
13921420
using NameT =

sycl/source/handler.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,8 @@ void handler::processArg(void *Ptr, const detail::kernel_param_kind_t &Kind,
491491
case kernel_param_kind_t::kind_accessor: {
492492
// For args kind of accessor Size is information about accessor.
493493
// The first 11 bits of Size encodes the accessor target.
494-
const access::target AccTarget = static_cast<access::target>(Size & 0x7ff);
494+
const access::target AccTarget =
495+
static_cast<access::target>(Size & AccessTargetMask);
495496
switch (AccTarget) {
496497
case access::target::device:
497498
case access::target::constant_buffer: {
@@ -616,7 +617,7 @@ void handler::extractArgsAndReqsFromLambda(
616617
// For args kind of accessor Size is information about accessor.
617618
// The first 11 bits of Size encodes the accessor target.
618619
const access::target AccTarget =
619-
static_cast<access::target>(Size & 0x7ff);
620+
static_cast<access::target>(Size & AccessTargetMask);
620621
if ((AccTarget == access::target::device ||
621622
AccTarget == access::target::constant_buffer) ||
622623
(AccTarget == access::target::image ||

0 commit comments

Comments
 (0)