Skip to content

Commit b48be20

Browse files
authored
[SYCL][Doc] Update KernelProperties extension (#5343)
This commit makes several changes, to align with other extensions and address feedback and concerns: - To align with changes to the base property list extension, the _v suffix has been dropped from property values. - The "property_list" class is now called "properties". Some text in the extension still refers to the concept of a "property list" because this is easier to read. - Using a member function in conjunction with a tag type prevents kernel functors from accidentally implementing the properties interface, and prevents naming conflicts with existing variables in user code. Signed-off-by: John Pennycook <[email protected]>
1 parent 33fdc58 commit b48be20

File tree

1 file changed

+91
-74
lines changed

1 file changed

+91
-74
lines changed

sycl/doc/extensions/KernelProperties/KernelProperties.asciidoc

Lines changed: 91 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -23,32 +23,26 @@ NOTE: Khronos(R) is a registered trademark and SYCL(TM) and SPIR(TM) are
2323
trademarks of The Khronos Group Inc. OpenCL(TM) is a trademark of Apple Inc.
2424
used by permission by Khronos.
2525

26-
NOTE: This document is better viewed when rendered as html with asciidoctor.
27-
GitHub does not render image icons.
28-
2926
This extension introduces a replacement for the kernel attributes defined in
30-
Section 5.8.1 of the SYCL 2020 specification, in the form of a `property_list`
27+
Section 5.8.1 of the SYCL 2020 specification, in the form of a property list
3128
accepting properties with compile-time constant values.
3229

3330
== Notice
3431

35-
Copyright (c) 2021 Intel Corporation. All rights reserved.
32+
Copyright (c) 2021-2022 Intel Corporation. All rights reserved.
3633

3734
== Status
3835

3936
Working Draft
4037

41-
This is a preview extension specification, intended to provide early access to
42-
a feature for review and community feedback. When the feature matures, this
43-
specification may be released as a formal extension.
44-
45-
Because the interfaces defined by this specification are not final and are
46-
subject to change they are not intended to be used by shipping software
47-
products.
38+
This is a proposed extension specification, intended to gather community
39+
feedback. Interfaces defined in this specification may not be implemented yet
40+
or may be in a preliminary state. The specification itself may also change in
41+
incompatible ways before it is finalized. Shipping software products should not
42+
rely on APIs defined in this specification.
4843

4944
== Version
5045

51-
Built On: {docdate} +
5246
Revision: 1
5347

5448
== Contributors
@@ -61,10 +55,10 @@ Roland Schulz, Intel
6155

6256
== Dependencies
6357

64-
This extension is written against the SYCL 2020 specification, Revision 3 and
58+
This extension is written against the SYCL 2020 specification, Revision 4 and
6559
the following extensions:
6660

67-
- https://github.com/intel/llvm/blob/sycl/sycl/doc/extensions/PropertyList/SYCL_EXT_ONEAPI_property_list.asciidoc[SYCL_EXT_ONEAPI_PROPERTY_LIST]
61+
- https://github.com/intel/llvm/blob/sycl/sycl/doc/extensions/PropertyList/SYCL_EXT_ONEAPI_properties.asciidoc[SYCL_EXT_ONEAPI_PROPERTIES]
6862

6963
== Feature Test Macro
7064

@@ -110,7 +104,7 @@ information, including:
110104
performed at run-time and *after* compiling the kernel.
111105

112106
This extension proposes a replacement for these kernel attributes, in the form
113-
of a `property_list` accepting properties with compile-time constant
107+
of a property list accepting properties with compile-time constant
114108
values, to address several of these issues.
115109

116110
== Kernel Properties
@@ -123,58 +117,60 @@ Section 5.8.1 of the SYCL 2020 specification. Note that deprecated attributes
123117
namespace sycl {
124118
namespace ext {
125119
namespace oneapi {
120+
namespace experimental {
126121

127122
// Corresponds to reqd_work_group_size
128-
struct work_group_size {
123+
struct work_group_size_key {
129124
template <size_t... Dims>
130-
using value_t = property_value<work_group_size, std::integral_constant<size_t, Dims>...>;
131-
}; // work_group_size
125+
using value_t = property_value<work_group_size_key, std::integral_constant<size_t, Dims>...>;
126+
}; // work_group_size_key
132127

133128
// Corresponds to work_group_size_hint
134-
struct work_group_size_hint {
129+
struct work_group_size_hint_key {
135130
template <size_t... Dims>
136-
using value_t = property_value<work_group_size_hint, std::integral_constant<size_t, Dims>...>;
137-
}; // work_group_size_hint
131+
using value_t = property_value<work_group_size_hint_key, std::integral_constant<size_t, Dims>...>;
132+
}; // work_group_size_hint_key
138133

139134
// Corresponds to reqd_sub_group_size
140-
struct sub_group_size {
135+
struct sub_group_size_key {
141136
template <uint32_t Size>
142-
using value_t = property_value<sub_group_size, std::integral_constant<uint32_t, Size>>;
143-
}; // sub_group_size
137+
using value_t = property_value<sub_group_size_key, std::integral_constant<uint32_t, Size>>;
138+
}; // sub_group_size_key
144139

145140
// Corresponds to device_has
146-
struct device_has {
141+
struct device_has_key {
147142
template <sycl::aspect... Aspects>
148-
using value_t = property_value<device_has, std::integral_constant<sycl::aspect, Aspects>...>;
149-
}; // device_has
143+
using value_t = property_value<device_has_key, std::integral_constant<sycl::aspect, Aspects>...>;
144+
}; // device_has_key
150145

151146
template <size_t... Dims>
152-
struct property_value<work_group_size, std::integral_constant<size_t, Dims>...> {
147+
struct property_value<work_group_size_key, std::integral_constant<size_t, Dims>...> {
153148
constexpr size_t operator[](int dim);
154149
};
155150

156151
template <size_t... Dims>
157-
struct property_value<work_group_size_hint, std::integral_constant<size_t, Dims>...> {
152+
struct property_value<work_group_size_hint_key, std::integral_constant<size_t, Dims>...> {
158153
constexpr size_t operator[](int dim);
159154
};
160155

161156
template <sycl::aspect... Aspects>
162-
struct property_value<device_has, std::integral_constant<sycl::aspect, Aspects>...> {
157+
struct property_value<device_has_key, std::integral_constant<sycl::aspect, Aspects>...> {
163158
static constexpr std::array<sycl::aspect, sizeof...(Aspects)> value;
164159
};
165160

166161
template <size_t... Dims>
167-
inline constexpr work_group_size::value_t<Dims...> work_group_size_v;
162+
inline constexpr work_group_size_key::value_t<Dims...> work_group_size;
168163

169164
template <size_t... Dims>
170-
inline constexpr work_group_size_hint::value_t<Dims...> work_group_size_hint_v;
165+
inline constexpr work_group_size_hint_key::value_t<Dims...> work_group_size_hint;
171166

172167
template <uint32_t Size>
173-
inline constexpr sub_group_size::value_t<Size> sub_group_size_v;
168+
inline constexpr sub_group_size_key::value_t<Size> sub_group_size;
174169

175170
template <sycl::aspect... Aspects>
176-
inline constexpr device_has::value_t<Aspects...> device_has_v;
171+
inline constexpr device_has_key::value_t<Aspects...> device_has;
177172

173+
} // namespace experimental
178174
} // namespace oneapi
179175
} // namespace ext
180176
} // namespace sycl
@@ -221,15 +217,15 @@ SYCL implementations may introduce additional kernel properties. If any
221217
combinations of kernel attributes are invalid, this must be clearly documented
222218
as part of the new kernel property definition.
223219

224-
== Adding a `property_list` to a Kernel Launch
220+
== Adding a Property List to a Kernel Launch
225221

226222
To enable properties to be associated with kernels, this extension adds
227223
new overloads to each of the variants of `single_task`, `parallel_for` and
228224
`parallel_for_work_group` defined in the `queue` and `handler` classes. These
229-
new overloads accept a `sycl::ext::oneapi::property_list` argument. For
230-
variants accepting a parameter pack, the `sycl::ext::oneapi::property_list`
225+
new overloads accept a `sycl::ext::oneapi::experimental::properties` argument. For
226+
variants accepting a parameter pack, the `sycl::ext::oneapi::experimental::properties`
231227
argument is inserted immediately prior to the parameter pack; for variants not
232-
accepting a parameter pack, the `sycl::ext::oneapi::property_list` argument is
228+
accepting a parameter pack, the `sycl::ext::oneapi::experimental::properties` argument is
233229
inserted immediately prior to the kernel function.
234230

235231
The overloads introduced by this extension are listed below:
@@ -313,15 +309,15 @@ class handler {
313309
}
314310
```
315311

316-
Passing properties as an argument in this way allows properties to be
312+
Passing a property list as an argument in this way allows properties to be
317313
associated with a kernel function without modifying its type. This enables
318314
the same kernel function (e.g. a lambda) to be submitted multiple times with
319315
different properties, or for libraries building on SYCL to add properties
320316
(e.g. for performance reasons) to user-provided kernel functions.
321317

322318
All the properties defined in this extension have compile-time values. However,
323319
an implementation may support additional properties which could have run-time
324-
values. When this occurs, the `properties` parameter may be a `property_list`
320+
values. When this occurs, the `properties` parameter may be a property list
325321
containing a mix of both run-time and compile-time values, and a SYCL
326322
implementation should respect both run-time and compile-time information when
327323
determining the correct way to launch a kernel. However, only compile-time
@@ -331,28 +327,47 @@ A simple example of using this extension to set a required work-group size
331327
and required sub-group size is given below:
332328

333329
```c++
334-
sycl::ext::oneapi::property_list properties{sycl::ext::oneapi::work_group_size_v<8, 8>,
335-
sycl::ext::oneapi::sub_group_size_v<8>};
330+
sycl::ext::oneapi::experimental::properties properties{sycl::ext::oneapi::experimental::work_group_size<8, 8>,
331+
sycl::ext::oneapi::experimental::sub_group_size<8>};
336332
q.parallel_for(range<2>{16, 16}, properties, [=](id<2> i) {
337333
a[i] = b[i] + c[i];
338334
}).wait();
339335
```
340336

341-
== Encoding Properties into a Kernel
337+
== Embedding Properties into a Kernel
342338

343-
In other situations it may be useful to encode a kernel's properties directly
339+
In other situations it may be useful to embed a kernel's properties directly
344340
into its type, to ensure that a kernel cannot be launched without a property
345341
that it depends upon for correctness.
346342

347343
To enable this use-case, this extension adds a mechanism for implementations to
348344
extract a property list from a kernel functor, if a kernel functor declares
349-
a `property_list` member variable named `properties`. Note that this member
350-
variable must be `static constexpr`, and kernel functors can therefore only
351-
encode properties with compile-time values.
345+
a member function named `get` accepting a `sycl::ext::oneapi::experimental::properties_tag`
346+
tag type and returning an instance of `sycl::ext::oneapi::experimental::properties`.
347+
348+
```c++
349+
namespace sycl {
350+
namespace ext {
351+
namespace oneapi {
352+
namespace experimental {
353+
354+
struct properties_tag {};
355+
356+
}
357+
}
358+
}
359+
}
360+
```
361+
362+
NOTE: https://wg21.link/p1895[P1895] proposes a function called `tag_invoke`
363+
as a general mechanism for customization points that could be used as a
364+
replacement for the `get` function proposed here. If `tag_invoke` becomes
365+
a feature in a future version of {cpp}, a future version of this extension
366+
may expose a new interface compatible with `tag_invoke`.
352367

353368
NOTE: The attribute mechanism in SYCL 2020 allows for different kernel
354369
attributes to be applied to different call operators within the same
355-
functor. The `property_list` member variable applies to all call operators in
370+
functor. An embedded property list applies to all call operators in
356371
the functor.
357372

358373
The example below shows how the kernel from the previous section could be
@@ -370,9 +385,10 @@ struct KernelFunctor {
370385
a[i] = b[i] + c[i];
371386
}
372387

373-
static constexpr auto properties =
374-
sycl::ext::oneapi::property_list{sycl::ext::oneapi::work_group_size_v<8, 8>,
375-
sycl::ext::oneapi::sub_group_size_v<8>};
388+
auto get(sycl::ext::oneapi::experimental::properties_tag) {
389+
return sycl::ext::oneapi::experimental::properties{sycl::ext::oneapi::experimental::work_group_size<8, 8>,
390+
sycl::ext::oneapi::experimental::sub_group_size<8>};
391+
}
376392

377393
sycl::accessor<int, 2> a;
378394
sycl::accessor<int, 2> b;
@@ -385,18 +401,18 @@ struct KernelFunctor {
385401
q.parallel_for(range<2>{16, 16}, KernelFunctor(a, b, c)).wait();
386402
```
387403

388-
If a kernel functor with a `property_list` member variable is enqueued for
389-
execution using an invocation function with a `property_list` argument,
390-
the kernel is launched as-if the member variable and argument were combined. If
391-
the combined list contains any invalid combinations of properties, then this is
392-
an error: invalid combinations that can be detected at compile-time should be
393-
reported via a diagnostic; invalid combinations that can only be detected at
394-
run-time should result in an implementation throwing an `exception` with the
395-
`errc::invalid` error code.
404+
If a kernel functor with embedded properties is enqueued for execution using an
405+
invocation function with a property list argument, the kernel is launched as-if
406+
the embedded properties and argument were combined. If the combined list
407+
contains any invalid combinations of properties, then this is an error: invalid
408+
combinations that can be detected at compile-time should be reported via a
409+
diagnostic; invalid combinations that can only be detected at run-time should
410+
result in an implementation throwing an `exception` with the `errc::invalid`
411+
error code.
396412

397413
== Querying Properties in a Compiled Kernel
398414

399-
Any properties encoded into a kernel type via a property list are reflected
415+
Any properties embedded into a kernel type via a property list are reflected
400416
in the results of a call to `kernel::get_info` with the
401417
`info::kernel::attributes` information descriptor, as if the corresponding
402418
attribute from the SYCL 2020 specification had been applied to the kernel
@@ -408,9 +424,9 @@ The SYCL 2020 `sycl::device_has` attribute can be applied to the declaration
408424
of a non-kernel device function, to assert that the device function uses a
409425
specific set of optional features. This extension provides a mechanism exposing
410426
similar behavior, allowing for kernel properties to be associated with
411-
a function via the `SYCL_EXT_ONEAPI_PROPERTY` macro. Each instance of the
412-
`SYCL_EXT_ONEAPI_PROPERTY` macro accepts one argument, corresponding to a
413-
single property value.
427+
a function via the `SYCL_EXT_ONEAPI_FUNCTION_PROPERTY` macro. Each instance of
428+
the `SYCL_EXT_ONEAPI_FUNCTION_PROPERTY` macro accepts one argument,
429+
corresponding to a single property value.
414430

415431
NOTE: Due to limitations of the C preprocessor, property value expressions
416432
containing commas (e.g. due to template arguments) must be enclosed in
@@ -420,12 +436,13 @@ The example below shows a function that uses two optional features,
420436
corresponding to the `fp16` and `atomic64` aspects.
421437

422438
```c++
423-
SYCL_EXT_ONEAPI_PROPERTY((sycl::device_has_v<aspect::fp16, aspect::atomic64>))
439+
SYCL_EXT_ONEAPI_FUNCTION_PROPERTY((sycl::device_has<aspect::fp16, aspect::atomic64>))
424440
void foo();
425441
```
426442

427443
The table below describes the effects of associating each kernel property
428-
with a non-kernel device function via the `SYCL_EXT_ONEAPI_PROPERTY` macro.
444+
with a non-kernel device function via the `SYCL_EXT_ONEAPI_FUNCTION_PROPERTY`
445+
macro.
429446

430447
|===
431448
|Property|Description
@@ -438,14 +455,14 @@ with a non-kernel device function via the `SYCL_EXT_ONEAPI_PROPERTY` macro.
438455

439456
|===
440457

441-
The `SYCL_EXT_ONEAPI_PROPERTY` macro can be used alongside the
458+
The `SYCL_EXT_ONEAPI_FUNCTION_PROPERTY` macro can be used alongside the
442459
`SYCL_EXTERNAL` macro, and the macros may be specified in any order.
443460
Whenever `SYCL_EXTERNAL` is used, there are two relevant translation units: the
444461
translation unit that _defines_ the function and the translation unit that
445462
_calls_ the function. If a given `SYCL_EXTERNAL` function _F_ is defined in
446463
one translation unit with a set of properties _P_, then all other translation
447464
units that declare that same function _F_ must list the same set of properties
448-
_P_ via the `SYCL_EXT_ONEAPI_PROPERTY` macro. Programs which fail to do this
465+
_P_ via the `SYCL_EXT_ONEAPI_FUNCTION_PROPERTY` macro. Programs which fail to do this
449466
are ill-formed, but no diagnostic is required.
450467

451468
== Issues
@@ -461,14 +478,14 @@ new properties, for example `device_has_all_of` and `device_has_any_of`:
461478
device_has_any_of<device_has<aspect::fp16, device_has<aspect::fp64>>`.
462479
--
463480

464-
. How should the `property_list` member variable behave with inheritance?
481+
. How should an embedded property list behave with inheritance?
465482
+
466483
--
467-
*UNRESOLVED*: The specification currently allows for a class to inspect the
468-
`property_list` member variable from its base class(es) and construct a new
469-
`property_list` member variable that applies to all call operators. Associating
470-
different properties with different call operators via inheritance has the
471-
potential to be confusing and would increase implementation complexity.
484+
*RESOLVED*: The specification currently allows for a class to inspect the
485+
property list embedded into its base class(es) and construct a new property
486+
list that applies to all call operators. Associating different properties with
487+
different call operators via inheritance has the potential to be confusing and
488+
would increase implementation complexity.
472489
--
473490

474491
//. asd

0 commit comments

Comments
 (0)