Skip to content

Commit a92bbec

Browse files
steffenlarsenbader
andauthored
[SYCL] Restrict nd_range parallel_for to nd_item (#11067)
According to the SYCL 2020 specification: > The function object that represents the SYCL kernel function must take one of: 1) a single SYCL nd_item parameter, 2) a single generic parameter (template parameter or auto) that will be treated as an nd_item parameter, 3) any other type converted from SYCL nd_item, representing the currently executing work-item within the range specified by the nd_range parameter. However, the current implementation allows also sycl::item and any argument types convertible from a sycl::item. This commit addresses this discrepancy by disallowing anything other than sycl::nd_item and all types convertible from sycl::nd_item in this kind of parallel_for. Since this may break existing code, this new restriction is guarded by the SYCL2020_CONFORMANT_APIS preprocessor macro. --------- Signed-off-by: Larsen, Steffen <[email protected]> Co-authored-by: Alexey Bader <[email protected]>
1 parent ae254bf commit a92bbec

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed

sycl/include/sycl/handler.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,10 +1191,19 @@ class __SYCL_EXPORT handler {
11911191
verifyUsedKernelBundle(detail::KernelInfo<NameT>::getName());
11921192
using LambdaArgType =
11931193
sycl::detail::lambda_arg_type<KernelType, nd_item<Dims>>;
1194+
#ifdef SYCL2020_CONFORMANT_APIS
1195+
static_assert(
1196+
std::is_convertible_v<sycl::nd_item<Dims>, LambdaArgType>,
1197+
"Kernel argument of a sycl::parallel_for with sycl::nd_range "
1198+
"must be either sycl::nd_item or be convertible from sycl::nd_item");
1199+
using TransformedArgType = sycl::nd_item<Dims>;
1200+
#else
11941201
// If user type is convertible from sycl::item/sycl::nd_item, use
11951202
// sycl::item/sycl::nd_item to transport item information
11961203
using TransformedArgType =
11971204
typename TransformUserItemType<Dims, LambdaArgType>::type;
1205+
#endif
1206+
11981207
(void)ExecutionRange;
11991208
kernel_parallel_for_wrapper<NameT, TransformedArgType, KernelType,
12001209
PropertiesT>(KernelFunc);
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// RUN: %clangxx -fsycl -fsyntax-only -ferror-limit=0 -Xclang -verify -Xclang -verify-ignore-unexpected=note,warning,error %s
2+
// RUN: %clangxx -fsycl -fsyntax-only -ferror-limit=0 -Xclang -verify -Xclang -verify-ignore-unexpected=note,warning,error %s -DSYCL2020_CONFORMANT_APIS
3+
4+
// Tests the requirements on the first argument in a kernel lambda.
5+
// TODO: Some of the behavior is currently guarded behind
6+
// SYCL2020_CONFORMANT_APIS. Remove the definition when this behavior has
7+
// been promoted.
8+
9+
#include <sycl/sycl.hpp>
10+
11+
template <int Dims> struct ConvertibleFromItem {
12+
ConvertibleFromItem(sycl::item<Dims>) {}
13+
};
14+
15+
template <int Dims> struct ConvertibleFromNDItem {
16+
ConvertibleFromNDItem(sycl::nd_item<Dims>) {}
17+
};
18+
19+
int main() {
20+
sycl::queue Q;
21+
22+
// TODO: Remove this when the guarded behavior is promoted.
23+
#ifdef SYCL2020_CONFORMANT_APIS
24+
// ND-range parallel_for with item.
25+
Q.submit([&](sycl::handler &CGH) {
26+
// expected-error@sycl/handler.hpp:* {{Kernel argument of a sycl::parallel_for with sycl::nd_range must be either sycl::nd_item or be convertible from sycl::nd_item}}
27+
CGH.parallel_for(sycl::nd_range{sycl::range{1}, sycl::range{1}},
28+
[=](sycl::item<1>) {});
29+
});
30+
Q.submit([&](sycl::handler &CGH) {
31+
// expected-error@sycl/handler.hpp:* {{Kernel argument of a sycl::parallel_for with sycl::nd_range must be either sycl::nd_item or be convertible from sycl::nd_item}}
32+
CGH.parallel_for(sycl::nd_range{sycl::range{1, 1}, sycl::range{1, 1}},
33+
[=](sycl::item<2>) {});
34+
});
35+
Q.submit([&](sycl::handler &CGH) {
36+
// expected-error@sycl/handler.hpp:* {{Kernel argument of a sycl::parallel_for with sycl::nd_range must be either sycl::nd_item or be convertible from sycl::nd_item}}
37+
CGH.parallel_for(sycl::nd_range{sycl::range{1, 1, 1}, sycl::range{1, 1, 1}},
38+
[=](sycl::item<3>) {});
39+
});
40+
41+
// ND-range parallel_for with id.
42+
Q.submit([&](sycl::handler &CGH) {
43+
// expected-error@sycl/handler.hpp:* {{Kernel argument of a sycl::parallel_for with sycl::nd_range must be either sycl::nd_item or be convertible from sycl::nd_item}}
44+
CGH.parallel_for(sycl::nd_range{sycl::range{1}, sycl::range{1}},
45+
[=](sycl::id<1>) {});
46+
});
47+
Q.submit([&](sycl::handler &CGH) {
48+
// expected-error@sycl/handler.hpp:* {{Kernel argument of a sycl::parallel_for with sycl::nd_range must be either sycl::nd_item or be convertible from sycl::nd_item}}
49+
CGH.parallel_for(sycl::nd_range{sycl::range{1, 1}, sycl::range{1, 1}},
50+
[=](sycl::id<2>) {});
51+
});
52+
Q.submit([&](sycl::handler &CGH) {
53+
// expected-error@sycl/handler.hpp:* {{Kernel argument of a sycl::parallel_for with sycl::nd_range must be either sycl::nd_item or be convertible from sycl::nd_item}}
54+
CGH.parallel_for(sycl::nd_range{sycl::range{1, 1, 1}, sycl::range{1, 1, 1}},
55+
[=](sycl::id<3>) {});
56+
});
57+
58+
// ND-range parallel_for with argument that is convertible from item.
59+
Q.submit([&](sycl::handler &CGH) {
60+
// expected-error@sycl/handler.hpp:* {{Kernel argument of a sycl::parallel_for with sycl::nd_range must be either sycl::nd_item or be convertible from sycl::nd_item}}
61+
CGH.parallel_for(sycl::nd_range{sycl::range{1}, sycl::range{1}},
62+
[=](ConvertibleFromItem<1>) {});
63+
});
64+
Q.submit([&](sycl::handler &CGH) {
65+
// expected-error@sycl/handler.hpp:* {{Kernel argument of a sycl::parallel_for with sycl::nd_range must be either sycl::nd_item or be convertible from sycl::nd_item}}
66+
CGH.parallel_for(sycl::nd_range{sycl::range{1, 1}, sycl::range{1, 1}},
67+
[=](ConvertibleFromItem<2>) {});
68+
});
69+
Q.submit([&](sycl::handler &CGH) {
70+
// expected-error@sycl/handler.hpp:* {{Kernel argument of a sycl::parallel_for with sycl::nd_range must be either sycl::nd_item or be convertible from sycl::nd_item}}
71+
CGH.parallel_for(sycl::nd_range{sycl::range{1, 1, 1}, sycl::range{1, 1, 1}},
72+
[=](ConvertibleFromItem<3>) {});
73+
});
74+
#endif // SYCL2020_CONFORMANT_APIS
75+
76+
// Range parallel_for with nd_item.
77+
Q.submit([&](sycl::handler &CGH) {
78+
// expected-error@sycl/handler.hpp:* {{Kernel argument cannot have a sycl::nd_item type in sycl::parallel_for with sycl::range}}
79+
CGH.parallel_for(sycl::range{1}, [=](sycl::nd_item<1>) {});
80+
});
81+
Q.submit([&](sycl::handler &CGH) {
82+
// expected-error@sycl/handler.hpp:* {{Kernel argument cannot have a sycl::nd_item type in sycl::parallel_for with sycl::range}}
83+
CGH.parallel_for(sycl::range{1, 1}, [=](sycl::nd_item<2>) {});
84+
});
85+
Q.submit([&](sycl::handler &CGH) {
86+
// expected-error@sycl/handler.hpp:* {{Kernel argument cannot have a sycl::nd_item type in sycl::parallel_for with sycl::range}}
87+
CGH.parallel_for(sycl::range{1, 1, 1}, [=](sycl::nd_item<3>) {});
88+
});
89+
90+
// Range parallel_for with argument that is convertible from nd_item.
91+
Q.submit([&](sycl::handler &CGH) {
92+
// expected-error@sycl/handler.hpp:* {{Kernel argument cannot have a sycl::nd_item type in sycl::parallel_for with sycl::range}}
93+
CGH.parallel_for(sycl::range{1}, [=](ConvertibleFromNDItem<1>) {});
94+
});
95+
Q.submit([&](sycl::handler &CGH) {
96+
// expected-error@sycl/handler.hpp:* {{Kernel argument cannot have a sycl::nd_item type in sycl::parallel_for with sycl::range}}
97+
CGH.parallel_for(sycl::range{1, 1}, [=](ConvertibleFromNDItem<2>) {});
98+
});
99+
Q.submit([&](sycl::handler &CGH) {
100+
// expected-error@sycl/handler.hpp:* {{Kernel argument cannot have a sycl::nd_item type in sycl::parallel_for with sycl::range}}
101+
CGH.parallel_for(sycl::range{1, 1, 1}, [=](ConvertibleFromNDItem<3>) {});
102+
});
103+
}

0 commit comments

Comments
 (0)