Skip to content

Commit 589d488

Browse files
authored
[SYCL][Doc] Clarify restrictions on device global variables (#4697)
Clarify the restrictions for declaring variables of type `device_global`. These restrictions are similar to those we have already for `specialization_id` variables. The restriction against arrays of `device_global` variables is not strictly necessary, but it would take extra effort to implement and we do not have a compelling use case. We could lift the restriction later if we find a need.
1 parent 61f1ae6 commit 589d488

File tree

1 file changed

+88
-2
lines changed

1 file changed

+88
-2
lines changed

sycl/doc/extensions/DeviceGlobal/SYCL_INTEL_device_global.asciidoc

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,6 @@ Since _T_ is restricted to types with trivial default constructors in this versi
185185

186186
The allocation of type _T_ is zero-initialized on each device prior to the first access to that `device_global` variable.
187187

188-
`device_global` may only be declared with static storage duration at namespace scope or class scope. If a `device_global` is declared with any other storage duration or scope, the program is ill-formed.
189-
190188
Properties may be specified for a `device_global` to provide semantic
191189
modification or optimization hint information to the compiler. See the section
192190
below for a list of the properties that are allowed.
@@ -395,6 +393,94 @@ Available only if `sycl::is_property_of_v<propertyT, sycl::ext::oneapi::device_g
395393

396394
|===
397395

396+
=== Restrictions on creating device global objects
397+
398+
There are restrictions on how the application can create objects of type
399+
`device_global`. Applications that violate these restrictions are ill-formed.
400+
401+
* The application may declare a variable of type `device_global` in the
402+
following ways:
403+
+
404+
--
405+
** As a variable at namespace scope, or
406+
** As a static member variable, but only if the member variable is publicly
407+
accessible from namespace scope.
408+
--
409+
+
410+
The application must not create an object of type `device_global` in any other
411+
way. (E.g. variables with automatic storage duration or objects created via
412+
`new` are not allowed.)
413+
414+
* The `device_global` variable must not itself be an array. The underlying
415+
type _T_ may be an array type, but the `device_global` variable itself must
416+
not be an array.
417+
418+
* The `device_global` variable must not be shadowed by another identifier _X_
419+
which has the same name and is declared in an inline namespace, such that the
420+
`device_global` variable is no longer accessible after the declaration of
421+
_X_.
422+
423+
* If the `device_global` variable is declared in a namespace, none of the
424+
enclosing namespace names _N_ may be shadowed by another identifier _X_ which
425+
has the same name as _N_ and is declared in an inline namespace, such that
426+
_N_ is no longer accessible after the declaration of _X_.
427+
428+
[NOTE]
429+
====
430+
The expectation is that some implementations may conceptually insert code at
431+
the end of a translation unit which references each `device_global` variable
432+
that is declared in that translation unit. The restrictions listed above make
433+
this possible by ensuring that these variables are accessible at the end of the
434+
translation unit.
435+
====
436+
437+
The following example illustrates some of these restrictions:
438+
439+
[source, c++]
440+
----
441+
#include <sycl/sycl.hpp>
442+
using namespace sycl::ext::oneapi;
443+
444+
device_global<int> a; // OK
445+
static device_global<int> b; // OK
446+
inline device_global<int> c; // OK
447+
448+
struct Foo {
449+
static device_global<int> d; // OK
450+
};
451+
device_global<int> Foo::d;
452+
453+
struct Bar {
454+
device_global<int> e; // ILLEGAL: non-static member variable not
455+
}; // allowed
456+
457+
struct Baz {
458+
private:
459+
static device_global<int> f; // ILLEGAL: not publicly accessible from
460+
}; // namespace scope
461+
device_global<int> Baz::f;
462+
463+
device_global<int[4]> g; // OK
464+
device_global<int> h[4]; // ILLEGAL: array of "device_global" not
465+
// allowed
466+
467+
device_global<int> same_name; // OK
468+
namespace foo {
469+
device_global<int> same_name; // OK
470+
}
471+
namespace {
472+
device_global<int> same_name; // OK
473+
}
474+
inline namespace other {
475+
device_global<int> same_name; // ILLEGAL: shadows "device_global" variable
476+
} // with same name in enclosing namespace scope
477+
inline namespace {
478+
namespace foo { // ILLEGAL: namespace name shadows "::foo"
479+
} // namespace which contains "device_global"
480+
// variable.
481+
}
482+
----
483+
398484
=== Properties for device global variables
399485

400486
The `device_global` class supports several compile-time-constant properties.

0 commit comments

Comments
 (0)