Summary
The declare target directive specifies that variables, functions (C, C++ and Fortran), and subroutines
(Fortran) are mapped to a device. The declare target directive is a declarative directive.
Syntax
The syntax of the declare target directive is as follows:
where invoked-by-fptr is a constant logical expression that is evaluated at compile time.
Description
The declare target directive ensures that procedures and global variables can be executed or accessed on a
device. Variables are mapped for all device executions, or for specific device executions through a link
clause.
If an extended-list is present with no clause then the to clause is assumed.
The device_type clause specifies if a version of the procedure or variable should be made available on
the host, device or both. If host is specified only a host version of the procedure or variable is made
available. If any is specified then both device and host versions of the procedure or variable are made
available. If nohost is specified for a procedure then only a device version of the procedure is made
available. If nohost is specified for a variable then that variable is not available on the host. If no
device_type clause is present then the behavior is as if the device_type clause appears with any
specified.
If a variable with static storage duration is declared in a device routine then the named variable is treated as
if it had appeared in a to clause on a declare target directive.
If a function appears in a to clause in the same compilation unit in which the definition of the function
occurs then a device-specific version of the function is created.
If a variable appears in a to clause in the same compilation unit in which the definition of the variable
occurs then the original list item is allocated a corresponding list item in the device data environment of all
devices.
If a procedure appears in a to clause in the same compilation unit in which the definition of the procedure
occurs then a device-specific version of the procedure is created.
If a variable that is host associated appears in a to clause then the original list item is allocated a
corresponding list item in the device data environment of all devices.
If a variable appears in a to clause then the corresponding list item in the device data environment of each
device is initialized once, in the manner specified by the program, but at an unspecified point in the program
prior to the first reference to that list item. The list item is never removed from those device data
environments as if its reference count was initialized to positive infinity.
Including list items in a link clause supports compilation of functions called in a target region that
refer to the list items. The list items are not mapped by the declare target directive. Instead, they are mapped
according to the data mapping rules described in Section 2.21.7.
If a function is referenced in a function that appears as a list item in a to clause on a declare target directive
that does not specify a device_type clause with host and the function reference is not enclosed in a
target construct that specifies a device clause in which the ancestordevice-modifier appears then
the name of the referenced function is treated as if it had appeared in a to clause on a declare target
directive.
If a variable with static storage duration or a function (except lambda for C++) is referenced in the initializer
expression list of a variable with static storage duration that appears as a list item in a to clause on a declare
target directive then the name of the referenced variable or function is treated as if it had appeared in a to
clause on a declare target directive.
The form, preceded by either the declaretarget directive that has no clauses and no extended-list or
the begindeclaretarget directive and followed by a matching enddeclaretarget directive,
defines an implicit extended-list. The implicit extended-list consists of the variable names of
any variable declarations at file or namespace scope that appear between the two directives
and of the function names of any function declarations at file, namespace or class scope that
appear between the two directives. The implicit extended-list is converted to an implicit to
clause.
The declaration-definition-seq preceded by either begindeclaretarget directive or
a declaretarget directive without any clauses or an extended-list and followed by an
enddeclaretarget directive may contain declare target directives. If a device_type clause is
present on the contained declare target directive, then its argument determines which versions are made
available. If a list item appears both in an implicit and explicit list, the explicit list determines which
versions are made available.
If a procedure is referenced in a procedure that appears as a list item in a to clause on a declaretarget
directive that does not specify a device_type clause with host and the procedure reference is not
enclosed in a target construct that specifies a device clause in which the ancestordevice-modifier
appears then the name of the referenced procedure is treated as if it had appeared in a to clause on a
declaretarget directive.
If a declaretarget does not have any clauses and does not have an extended-list then an implicit to
clause with one item is formed from the name of the enclosing subroutine subprogram, function
subprogram or interface body to which it applies.
If a declaretarget directive has a device_type clause then any enclosed internal procedures
cannot contain any declaretarget directives. The enclosing device_type clause implicitly applies
to internal procedures.
If the indirect clause is present and invoked-by-fptr is not specified, the effect of the clause is as if
invoked-by-fptr evaluates to true.
If the indirect clause is present and invoked-by-fptr evaluates to true, any procedures that
appear in a to clause on the directive may be called with an indirect device invocation. If the
indirect clause is present and invoked-by-fptr does not evaluate to true, any procedures that appear
in a to clause on the directive may not be called with an indirect device invocation. Unless
otherwise specified by an indirect clause, procedures may not be called with an indirect device
invocation.
If a function appears in the to clause of a begindeclaretarget directive and in the to clause of a
declare target directive that is contained in the declaration-definition-seq associated with the
begindeclaretarget directive, and if an indirect clause appears on both directives,
then the indirect clause on the begindeclaretarget directive has no effect for that
function.
Execution Model Events
The target-global-data-op event occurs when an original variable is associated with a corresponding
variable on a device as a result of a declare target directive; the event occurs before the first access to the
corresponding variable.
Tool Callbacks
A thread dispatches a registered ompt_callback_target_data_op callback, or a registered
ompt_callback_target_data_op_emi callback with ompt_scope_beginend as its endpoint
argument for each occurrence of a target-global-data-op event in that thread. These callbacks have type
signature ompt_callback_target_data_op_t or ompt_callback_target_data_op_emi_t,
respectively.
Restrictions
Restrictions to the declare target directive are as follows:
A
threadprivate
variable
cannot
appear
in
the
directive.
A
variable
declared
in
the
directive
must
have
a
mappable
type.
The
same
list
item
must
not
appear
multiple
times
in
clauses
on
the
same
directive.
The
same
list
item
must
not
explicitly
appear
in
both
a
to
clause
on
one
declare
target
directive
and
a
link
clause
on
another
declare
target
directive.
If
the
directive
has
a
clause,
it
must
contain
at
least
one
to
clause
or
at
least
one
link
clause.
A
variable
for
which
nohost
is
specified
may
not
appear
in
a
link
clause.
At
most
one
indirect
clause
can
be
specified
on
the
directive.
At
most
one
device_type
clause
can
be
specified
on
the
directive.
If
an
indirect
clause
is
present
and
invoked-by-fptr
evaluates
to
true
then
the
only
permitted
device_type
clause
is
device_type(any).
A
to
clause
or
a
link
clause
cannot
appear
in
a
begindeclaretarget
directive.
The
function
names
of
overloaded
functions
or
template
functions
may
only
be
specified
within
an
implicit
extended-list.
If
a
lambda
declaration
and
definition
appears
between
a
declare
target
directive
and
the
paired
enddeclaretarget
directive,
all
variables
that
are
captured
by
the
lambda
expression
must
also
appear
in
a
to
clause.
A
module
export
or
import
statement
cannot
appear
between
a
declare
target
directive
and
the
paired
enddeclaretarget
directive.
If
a
list
item
is
a
procedure
name,
it
must
not
be
a
generic
name,
procedure
pointer,
entry
name,
or
statement
function
name.
If
the
directive
does
not
have
any
clause
or
has
a
device_type
clause
it
must
appear
in
a
specification
part
of
a
subroutine
subprogram,
function
subprogram
or
interface
body.
If
a
list
item
is
a
procedure
name,
the
directive
must
be
in
the
specification
part
of
that
subroutine
or
function
subprogram
or
in
the
specification
part
of
that
subroutine
or
function
in
an
interface
body.
If
the
directive
has
a
variable
name
in
extended-list,
it
must
appear
in
the
specification
part
of
a
subroutine
subprogram,
function
subprogram,
program
or
module.
If
the
directive
is
specified
in
an
interface
block
for
a
procedure,
it
must
match
a
declaretarget
directive
in
the
definition
of
the
procedure,
including
the
device_type
clause
if
present.
If
an
external
procedure
is
a
type-bound
procedure
of
a
derived
type
and
the
directive
is
specified
in
the
definition
of
the
external
procedure,
it
must
appear
in
the
interface
block
that
is
accessible
to
the
derived-type
definition.
If
any
procedure
is
declared
via
a
procedure
declaration
statement
that
is
not
in
the
type-bound
procedure
part
of
a
derived-type
definition,
any
declaretarget
with
the
procedure
name
must
appear
in
the
same
specification
part.
A
variable
that
is
part
of
another
variable
(as
an
array,
structure
element
or
type
parameter
inquiry)
cannot
appear
in
the
directive.
The
directive
must
appear
in
the
declaration
section
of
a
scoping
unit
in
which
the
common
block
or
variable
is
declared.
If
a
declaretarget
directive
that
specifies
a
common
block
name
appears
in
one
program
unit,
then
such
a
directive
must
also
appear
in
every
other
program
unit
that
contains
a
COMMON
statement
that
specifies
the
same
name,
after
the
last
such
COMMON
statement
in
the
program
unit.
If
a
list
item
is
declared
with
the
BIND
attribute,
the
corresponding
C
entities
must
also
be
specified
in
a
declaretarget
directive
in
the
C
program.
A
variable
can
only
appear
in
a
declaretarget
directive
in
the
scope
in
which
it
is
declared.
It
must
not
be
an
element
of
a
common
block
or
appear
in
an
EQUIVALENCE
statement.
A
variable
that
appears
in
a
declaretarget
directive
must
be
declared
in
the
Fortran
scope
of
a
module
or
have
the
SAVE
attribute,
either
explicitly
or
implicitly.