Skip to content

Commit d0622a6

Browse files
committed
Address TODO for kernel arg properties
Solve the TODO issues with properties that decorate kernel parameter by: * Move the C++ attribute from the parameter's class to a member variable inside the class. The author of the header file will need to decide with member variable to attach the properties to. * Restrict the C++ attribute, so it is only used to decorate a SYCL "special class". When a value of this type is passed as a kernel parameter, each member variable is passed as a separate parameter to the kernel's function. As a result, there is no ambiguity about which function parameter receives the property.
1 parent 4ec2881 commit d0622a6

File tree

1 file changed

+46
-57
lines changed

1 file changed

+46
-57
lines changed

sycl/doc/CompileTimeProperties.md

Lines changed: 46 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ template <typename dataT,
159159
access::target accessTarget,
160160
access::placeholder isPlaceholder,
161161
typename PropertyListT = ext::oneapi::property_list<>>
162-
class accessor {/* ... */};
162+
class __attribute__((sycl_special_class)) accessor {/* ... */};
163163
164164
} // namespace sycl
165165
```
@@ -176,7 +176,8 @@ accessor acc(buf, cgh, property_list{no_alias_v, foo_v<32>});
176176

177177
As before, the header file represents the properties with an internal C++
178178
attribute, where the initial parameters are the names of the properties and
179-
the subsequent parameters are the property values.
179+
the subsequent parameters are the property values. However, this time the
180+
attribute decorates one of the member variables.
180181

181182
```
182183
namespace sycl {
@@ -187,7 +188,7 @@ template <typename dataT,
187188
access::target accessTarget,
188189
access::placeholder isPlaceholder,
189190
typename PropertyListT = ext::oneapi::property_list<>>
190-
class accessor {/* ... */};
191+
class __attribute__((sycl_special_class)) accessor {/* ... */};
191192
192193
// Partial specialization to make PropertyListT visible as a parameter pack
193194
// of properties.
@@ -197,18 +198,20 @@ template <typename dataT,
197198
access::target accessTarget,
198199
access::placeholder isPlaceholder,
199200
typename ...Props>
200-
class
201+
class __attribute__((sycl_special_class)) accessor<dataT,
202+
dimensions,
203+
accessmode,
204+
accessTarget,
205+
isPlaceholder,
206+
property_list<Props...>> {
207+
dataT *ptr
201208
#ifdef __SYCL_DEVICE_ONLY__
202209
[[__sycl_detail__::add_ir_kernel_parameter_attributes(
203210
Props::meta_name..., Props::meta_value...
204211
)]]
205212
#endif
206-
accessor<dataT,
207-
dimensions,
208-
accessmode,
209-
accessTarget,
210-
isPlaceholder,
211-
property_list<Props...>> {/*...*/};
213+
;
214+
};
212215
213216
} // namespace sycl
214217
```
@@ -218,7 +221,9 @@ Illustrating this with the previous example:
218221
```
219222
namespace sycl {
220223
221-
template </* ... */> class
224+
template </* ... */>
225+
class __attribute__((sycl_special_class)) accessor</* ... */> {
226+
dataT *ptr
222227
#ifdef __SYCL_DEVICE_ONLY__
223228
[[__sycl_detail__::add_ir_kernel_parameter_attributes(
224229
"sycl-no-alias", // Name of first property
@@ -227,47 +232,34 @@ template </* ... */> class
227232
32 // Value of second property
228233
)]]
229234
#endif
230-
accessor</* ... */> {/* ... */};
235+
;
236+
};
231237
232238
} // namespace sycl
233239
```
234240

235-
As the name of the C++ attribute suggests, the device compiler front-end uses
236-
the attribute only when the decorated type is the type of a kernel argument,
241+
As the name implies, this C++ attribute is only used to decorate a member
242+
variable of a class type that is as SYCL "special class" (i.e. a class that is
243+
decorated with `__attribute__((sycl_special_class))`). The device compiler
244+
front-end ignores the attribute when it is used in any other syntactic
245+
position.
246+
247+
The device compiler front-end uses this attribute only when the class type
248+
containing the decorated member variable is the type of a kernel argument,
237249
and it silently ignores the attribute when the class is used in any other way.
238250

239-
When the device compiler front-end creates a kernel argument in this way, it
240-
adds one LLVM IR attribute to the kernel function's parameter for each property
241-
in the list. For example, this can be done by calling
251+
When the front-end creates a kernel argument from a SYCL "special class", it
252+
passes each member variable of the class as a separate kernel argument. If the
253+
member variable is decorated with
254+
`[[__sycl_detail__::add_ir_kernel_parameter_attributes()]]`, the front-end adds
255+
one LLVM IR attribute to the kernel function's parameter for each property in
256+
the list. For example, this can be done by calling
242257
[`Function::addParamAttrs(unsigned ArgNo, const AttrBuilder &)`][7]. As
243258
before, the IR attributes are added as strings, so the front-end must convert
244259
the property value to a string if it is not already a string.
245260

246261
[7]: <https://llvm.org/doxygen/classllvm_1_1Function.html#a092beb46ecce99e6b39628ee92ccd95a>
247262

248-
**TODO**: There are a number of open issues with this attribute and with the
249-
semantics of properties that are represented as attributes on kernel
250-
arguments. Suppose there are two SYCL types that take properties: _A_ and
251-
_B_. (For example, this could be two specializations of `annotated_ptr`, each
252-
decorated with different properties.) Now suppose the application creates a
253-
struct that contains members with both of these types, and it passes that
254-
struct as a kernel argument. What is the intended semantic? Does the argument
255-
get decorated with the union of the properties on both _A_ and _B_? What if
256-
those properties are mutually exclusive? A similar case exists when the
257-
application creates a struct that inherits from both _A_ and _B_.
258-
259-
The previous example shows a case when a single kernel argument gets properties
260-
from two (or more) types. However, the opposite can also occur. Certain SYCL
261-
classes are decorated with `__attribute__((sycl_special_class))`, which causes
262-
the compiler to pass each member of that class as a separate kernel argument.
263-
What should happen with the properties that decorate the class? Should the
264-
compiler duplicate the properties on each such kernel argument? Or, maybe it
265-
should be the header file's responsibility not to decorate such a class with
266-
`[[__sycl_detail__::add_ir_kernel_parameter_attributes()]]`, and instead it
267-
should decorate specific member variable(s) with this attribute? How does the
268-
header decide which properties are used to decorate which member variables,
269-
though?
270-
271263

272264
## Properties on kernel functions
273265

@@ -402,8 +394,8 @@ void foo(int *p) {
402394
}
403395
```
404396

405-
We again implement the property list in the header via a C++ attribute, though
406-
this time the attribute decorates a member variable of the class:
397+
We again implement the property list in the header via a C++ attribute, where
398+
the attribute decorates a member variable of the class:
407399

408400
```
409401
namespace sycl::ext::oneapi {
@@ -652,24 +644,21 @@ template <typename dataT,
652644
access::target accessTarget,
653645
access::placeholder isPlaceholder,
654646
typename ...Props>
655-
class
647+
class __attribute__((sycl_special_class)) accessor<dataT,
648+
dimensions,
649+
accessmode,
650+
accessTarget,
651+
isPlaceholder,
652+
property_list<Props...>> {
653+
T *ptr
656654
#ifdef __SYCL_DEVICE_ONLY__
657-
[[__sycl_detail__::add_ir_kernel_parameter_attributes(
655+
[[__sycl_detail__::add_ir_kernel_parameter_attributes(
658656
659-
// The properties in this list are "kernel parameter attributes".
660-
{"sycl-no-alias", "sycl-foo"},
657+
// The properties in this list are "kernel parameter attributes".
658+
{"sycl-no-alias", "sycl-foo"},
661659
662-
Props::meta_name..., Props::meta_value...
663-
)]]
664-
#endif
665-
accessor<dataT,
666-
dimensions,
667-
accessmode,
668-
accessTarget,
669-
isPlaceholder,
670-
property_list<Props...>> {
671-
T *ptr
672-
#ifdef __SYCL_DEVICE_ONLY__
660+
Props::meta_name..., Props::meta_value...
661+
)]]
673662
[[__sycl_detail__::add_ir_member_annotation(
674663
675664
// The properties in this list are "member annotations".

0 commit comments

Comments
 (0)