@@ -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
177177As before, the header file represents the properties with an internal C++
178178attribute, 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```
182183namespace 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```
219222namespace 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,
237249and 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
243258before, the IR attributes are added as strings, so the front-end must convert
244259the 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```
409401namespace 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