Skip to content

Commit 27b1847

Browse files
authored
[SYCL] Re-allow auto& parameter in range parallel_for (#11315)
Before #10864, our header implementation allowed kernels with an auto& parameter, e.g. `q.parallel_for(1, [=](auto &id) {})` , but strictly speaking, this would not follow the criteria in [4.9.4.2.2. parallel_for invoke](https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#_parallel_for_invoke). After that PR, this behavior unintentionally became disallowed. This PR restores the old behavior while disallowing it under `-DSYCL2020_CONFORMANT_APIS`.
1 parent a0f688f commit 27b1847

File tree

2 files changed

+46
-8
lines changed

2 files changed

+46
-8
lines changed

sycl/include/sycl/handler.hpp

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -349,12 +349,12 @@ template <int Dims> class RoundedRangeIDGenerator {
349349
id<Dims> getId() { return Id; }
350350

351351
template <typename KernelType> auto getItem() {
352-
if constexpr (std::is_invocable_v<KernelType, item<Dims>> ||
353-
std::is_invocable_v<KernelType, item<Dims>, kernel_handler>)
352+
if constexpr (std::is_invocable_v<KernelType, item<Dims> &> ||
353+
std::is_invocable_v<KernelType, item<Dims> &, kernel_handler>)
354354
return detail::Builder::createItem<Dims, true>(UserRange, getId(), {});
355355
else {
356-
static_assert(std::is_invocable_v<KernelType, item<Dims, false>> ||
357-
std::is_invocable_v<KernelType, item<Dims, false>,
356+
static_assert(std::is_invocable_v<KernelType, item<Dims, false> &> ||
357+
std::is_invocable_v<KernelType, item<Dims, false> &,
358358
kernel_handler>,
359359
"Kernel must be invocable with an item!");
360360
return detail::Builder::createItem<Dims, false>(UserRange, getId());
@@ -376,8 +376,10 @@ class RoundedRangeKernel {
376376
void operator()(item<Dims> It) const {
377377
auto RoundedRange = It.get_range();
378378
for (RoundedRangeIDGenerator Gen(It.get_id(), UserRange, RoundedRange); Gen;
379-
Gen.updateId())
380-
KernelFunc(Gen.template getItem<KernelType>());
379+
Gen.updateId()) {
380+
auto item = Gen.template getItem<KernelType>();
381+
KernelFunc(item);
382+
}
381383
}
382384
};
383385

@@ -389,8 +391,10 @@ class RoundedRangeKernelWithKH {
389391
void operator()(item<Dims> It, kernel_handler KH) const {
390392
auto RoundedRange = It.get_range();
391393
for (RoundedRangeIDGenerator Gen(It.get_id(), UserRange, RoundedRange); Gen;
392-
Gen.updateId())
393-
KernelFunc(Gen.template getItem<KernelType>(), KH);
394+
Gen.updateId()) {
395+
auto item = Gen.template getItem<KernelType>();
396+
KernelFunc(item, KH);
397+
}
394398
}
395399
};
396400

@@ -1239,6 +1243,19 @@ class __SYCL_EXPORT handler {
12391243
"Kernel argument cannot have a sycl::nd_item type in "
12401244
"sycl::parallel_for with sycl::range");
12411245

1246+
#ifdef SYCL2020_CONFORMANT_APIS
1247+
static_assert(
1248+
(std::is_invocable_v<KernelType, item<Dims>> ||
1249+
std::is_invocable_v<
1250+
KernelType, item<Dims>,
1251+
kernel_handler>)&&(std::is_invocable_v<KernelType,
1252+
item<Dims, false>> ||
1253+
std::is_invocable_v<KernelType,
1254+
item<Dims, false>,
1255+
kernel_handler>),
1256+
"Kernel should be invocable with a sycl::item");
1257+
#endif
1258+
12421259
// TODO: Properties may change the kernel function, so in order to avoid
12431260
// conflicts they should be included in the name.
12441261
using NameT =

sycl/test/basic_tests/handler/parallel_for_arg_restrictions.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,28 @@ int main() {
7171
CGH.parallel_for(sycl::nd_range{sycl::range{1, 1, 1}, sycl::range{1, 1, 1}},
7272
[=](ConvertibleFromItem<3>) {});
7373
});
74+
Q.submit([&](sycl::handler &CGH) {
75+
// expected-error@sycl/handler.hpp:* {{Kernel should be invocable with a sycl::item}}
76+
CGH.parallel_for(sycl::range{1}, [=](auto &) {});
77+
});
78+
Q.submit([&](sycl::handler &CGH) {
79+
// expected-error@sycl/handler.hpp:* {{Kernel should be invocable with a sycl::item}}
80+
CGH.parallel_for(sycl::range{1, 1}, [=](auto &) {});
81+
});
82+
Q.submit([&](sycl::handler &CGH) {
83+
// expected-error@sycl/handler.hpp:* {{Kernel should be invocable with a sycl::item}}
84+
CGH.parallel_for(sycl::range{1, 1, 1}, [=](auto &) {});
85+
});
7486
#endif // SYCL2020_CONFORMANT_APIS
87+
Q.submit([&](sycl::handler &CGH) {
88+
CGH.parallel_for(sycl::range{1}, [=](auto &) {});
89+
});
90+
Q.submit([&](sycl::handler &CGH) {
91+
CGH.parallel_for(sycl::range{1, 1}, [=](auto &) {});
92+
});
93+
Q.submit([&](sycl::handler &CGH) {
94+
CGH.parallel_for(sycl::range{1, 1, 1}, [=](auto &) {});
95+
});
7596

7697
// Range parallel_for with nd_item.
7798
Q.submit([&](sycl::handler &CGH) {

0 commit comments

Comments
 (0)