Summary
The requires directive specifies the features that an implementation must provide in order for
the code to compile and to execute correctly. The requires directive is an informational
directive.
Syntax
The syntax of the requires directive is as follows:
#pragmaomprequiresclause[[[,]clause]...]new-line
where clause is either a clause of the form ext_implementation-defined-requirement for an implementation
defined requirement clause or one of the requirement clauses listed below:
The syntax of the requires directive is as follows:
!$omprequiresclause[[[,]clause]...]
where clause is either a clause of the form ext_implementation-defined-requirement for an implementation
defined requirement clause or one of the requirement clauses listed below:
Description
The requires directive specifies features that an implementation must support for correct execution. The
behavior that a requirement clause specifies may override the normal behavior specified elsewhere in this
document. Whether an implementation supports the feature that a given requirement clause specifies is
implementation defined.
The requires directive specifies requirements for the execution of all code in the current compilation
unit.
Note – Use of this directive makes your code less portable. Users should be aware that not all devices or implementations
support all requirements.
When the reverse_offload clause appears on a requires directive, the implementation guarantees
that a target region, for which the target construct specifies a device clause in which
the ancestor modifier appears, can execute on the parent device of an enclosing target
region.
When the unified_address clause appears on a requires directive, the implementation guarantees
that all devices accessible through OpenMP API routines and directives use a unified address space. In this
address space, a pointer will always refer to the same location in memory from all devices accessible
through OpenMP. Any OpenMP mechanism that returns a device pointer is guaranteed to return a device
address that supports pointer arithmetic, and the is_device_ptr clause is not necessary to obtain device
addresses from device pointers for use inside target regions. Host pointers may be passed as device
pointer arguments to device memory routines and device pointers may be passed as host pointer arguments
to device memory routines. Non-host devices may still have discrete memories and dereferencing a
device pointer on the host device or a host pointer on a non-host device remains unspecified
behavior.
When the unified_address clause appears on a requires directive, the base pointer of a zero-length
array section that is mapped on a target construct and for which a matching mapped list item cannot be
found is not initialized to NULL but instead retains its original value.
Memory local to a specific execution context may be exempt from the unified_address
requirement, following the restrictions of locality to a given execution context, thread or contention
group.
The unified_shared_memory clause implies the unified_address requirement, inheriting all of
its behaviors. Additionally, storage locations in memory are accessible to threads on all available devices
that are supported by the implementation, except for memory that is local to a specific execution context as
defined in the description of unified_address above. Every device address that refers to
storage allocated through OpenMP device memory routines is a valid host pointer that may be
dereferenced.
The unified_shared_memory clause makes the map clause optional on target constructs and the
declare target directive optional for variables with static storage duration that are accessed inside functions
to which a declare target directive is applied. Scalar variables are still firstprivate by default when referenced
inside target constructs. Values stored into memory by one device may not be visible to another
device until those two devices synchronize with each other or both devices synchronize with the
host.
The atomic_default_mem_order clause specifies the default memory ordering behavior for
atomic constructs that must be provided by an implementation. Its parameter appears as a clause on any
atomic construct that does not already specify a memory order clause.
The dynamic_allocators clause removes certain restrictions on the use of memory allocators in
target regions. It makes the uses_allocators clause optional on target constructs for
the purpose of using allocators in the corresponding target regions. It allows calls to the
omp_init_allocator and omp_destroy_allocator API routines in target regions. Finally, it
allows default allocators to be used by allocate directives, allocate clauses, and omp_alloc API
routines in target regions.
Implementers are allowed to include additional implementation-defined requirement clauses. All
implementation defined requirements should begin with ext_. Requirement names that do not start with
ext_ are reserved.
The clauses of a requires directive are added to the requires trait in the OpenMP context for all program
points that follow the directive.
Restrictions
The restrictions to the requires directive are as follows:
Each
of
the
clauses
can
appear
at
most
once
on
the
directive.
All
atomic_default_mem_order
clauses
that
appear
on
a
requires
directive
in
the
same
compilation
unit
must
specify
the
same
parameter.
A
requires
directive
with
a
unified_address,
unified_shared_memory,
or
reverse_offload
clause
must
appear
lexically
before
any
device
constructs
or
device
routines.
A
requires
directive
may
not
appear
lexically
after
a
context
selector
in
which
any
clause
of
the
requires
directive
is
used.
A
requires
directive
with
any
of
the
following
clauses
must
appear
in
all
compilation
units
of
a
program
that
contain
device
constructs
or
device
routines
or
in
none
of
them:
reverse_offload
unified_address
unified_shared_memory
The requires directive with atomic_default_mem_order clause may not appear lexically after
any atomic construct on which memory-order-clause is not specified.
∙ The requires directive may only appear at file scope.
∙ The requires directive may only appear at file or namespace scope.
∙ The requires directive must appear in the specification part of a programunit, after any USE
statement, any IMPORT statement, and any IMPLICIT statement, unless the directive appears by
referencing a module and each clause already appeared with the same parameters in the specification part
of the programunit.