mirror of
https://github.com/OpenMP/Examples.git
synced 2025-04-04 05:41:33 +01:00
143 lines
7.1 KiB
TeX
143 lines
7.1 KiB
TeX
\pagebreak
|
|
\section{\code{declare} \code{target} Construct}
|
|
\label{sec:declare_target}
|
|
|
|
\subsection{\code{declare} \code{target} and \code{end} \code{declare} \code{target} for a Function}
|
|
\label{subsec:declare_target_function}
|
|
|
|
The following example shows how the \code{declare} \code{target} directive
|
|
is used to indicate that the corresponding call inside a \code{target} region
|
|
is to a \code{fib} function that can execute on the default target device.
|
|
|
|
A version of the function is also available on the host device. When the \code{if}
|
|
clause conditional expression on the \code{target} construct evaluates to \plc{false},
|
|
the \code{target} region (thus \code{fib}) will execute on the host device.
|
|
|
|
For C/C++ codes the declaration of the function \code{fib} appears between the \code{declare}
|
|
\code{target} and \code{end} \code{declare} \code{target} directives.
|
|
|
|
\cexample[4.0]{declare_target}{1}
|
|
|
|
The Fortran \code{fib} subroutine contains a \code{declare} \code{target} declaration
|
|
to indicate to the compiler to create an device executable version of the procedure.
|
|
The subroutine name has not been included on the \code{declare} \code{target}
|
|
directive and is, therefore, implicitly assumed.
|
|
|
|
The program uses the \code{module\_fib} module, which presents an explicit interface to
|
|
the compiler with the \code{declare} \code{target} declarations for processing
|
|
the \code{fib} call.
|
|
|
|
\ffreeexample[4.0]{declare_target}{1}
|
|
|
|
The next Fortran example shows the use of an external subroutine. Without an explicit
|
|
interface (through module use or an interface block) the \code{declare} \code{target}
|
|
declarations within a external subroutine are unknown to the main program unit;
|
|
therefore, a \code{declare} \code{target} must be provided within the program
|
|
scope for the compiler to determine that a target binary should be available.
|
|
|
|
\ffreeexample[4.0]{declare_target}{2}
|
|
|
|
\subsection{\code{declare} \code{target} Construct for Class Type}
|
|
\label{subsec:declare_target_class}
|
|
|
|
\cppspecificstart
|
|
The following example shows how the \code{declare} \code{target} and \code{end}
|
|
\code{declare} \code{target} directives are used to enclose the declaration
|
|
of a variable \plc{varY} with a class type \code{typeY}. The member function \code{typeY::foo()} cannot
|
|
be accessed on a target device because its declaration did not appear between \code{declare}
|
|
\code{target} and \code{end} \code{declare} \code{target} directives.
|
|
|
|
\cppnexample[4.0]{declare_target}{2}
|
|
\cppspecificend
|
|
|
|
\subsection{\code{declare} \code{target} and \code{end} \code{declare} \code{target} for Variables}
|
|
\label{subsec:declare_target_variables}
|
|
|
|
The following examples show how the \code{declare} \code{target} and \code{end}
|
|
\code{declare} \code{target} directives are used to indicate that global variables
|
|
are mapped to the implicit device data environment of each target device.
|
|
|
|
In the following example, the declarations of the variables \plc{p}, \plc{v1}, and \plc{v2} appear
|
|
between \code{declare} \code{target} and \code{end} \code{declare} \code{target}
|
|
directives indicating that the variables are mapped to the implicit device data
|
|
environment of each target device. The \code{target} \code{update} directive
|
|
is then used to manage the consistency of the variables \plc{p}, \plc{v1}, and \plc{v2} between the
|
|
data environment of the encountering host device task and the implicit device data
|
|
environment of the default target device.
|
|
|
|
\cexample[4.0]{declare_target}{3}
|
|
|
|
The Fortran version of the above C code uses a different syntax. Fortran modules
|
|
use a list syntax on the \code{declare} \code{target} directive to declare
|
|
mapped variables.
|
|
|
|
\ffreeexample[4.0]{declare_target}{3}
|
|
|
|
The following example also indicates that the function \code{Pfun()} is available on the
|
|
target device, as well as the variable \plc{Q}, which is mapped to the implicit device
|
|
data environment of each target device. The \code{target} \code{update} directive
|
|
is then used to manage the consistency of the variable \plc{Q} between the data environment
|
|
of the encountering host device task and the implicit device data environment of
|
|
the default target device.
|
|
|
|
In the following example, the function and variable declarations appear between
|
|
the \code{declare} \code{target} and \code{end} \code{declare} \code{target}
|
|
directives.
|
|
|
|
\cexample[4.0]{declare_target}{4}
|
|
|
|
The Fortran version of the above C code uses a different syntax. In Fortran modules
|
|
a list syntax on the \code{declare} \code{target} directive is used to declare
|
|
mapped variables and procedures. The \plc{N} and \plc{Q} variables are declared as a comma
|
|
separated list. When the \code{declare} \code{target} directive is used to
|
|
declare just the procedure, the procedure name need not be listed -- it is implicitly
|
|
assumed, as illustrated in the \code{Pfun()} function.
|
|
|
|
\ffreeexample[4.0]{declare_target}{4}
|
|
|
|
\subsection{\code{declare} \code{target} and \code{end} \code{declare} \code{target} with \code{declare} \code{simd}}
|
|
\label{subsec:declare_target_simd}
|
|
|
|
The following example shows how the \code{declare} \code{target} and \code{end}
|
|
\code{declare} \code{target} directives are used to indicate that a function
|
|
is available on a target device. The \code{declare} \code{simd} directive indicates
|
|
that there is a SIMD version of the function \code{P()} that is available on the target
|
|
device as well as one that is available on the host device.
|
|
|
|
\cexample[4.0]{declare_target}{5}
|
|
|
|
The Fortran version of the above C code uses a different syntax. Fortran modules
|
|
use a list syntax of the \code{declare} \code{target} declaration for the mapping.
|
|
Here the \plc{N} and \plc{Q} variables are declared in the list form as a comma separated list.
|
|
The function declaration does not use a list and implicitly assumes the function
|
|
name. In this Fortran example row and column indices are reversed relative to the
|
|
C/C++ example, as is usual for codes optimized for memory access.
|
|
|
|
\ffreeexample[4.0]{declare_target}{5}
|
|
|
|
|
|
\subsection{\code{declare}~\code{target} Directive with \code{link} Clause}
|
|
\label{subsec:declare_target_link}
|
|
|
|
In the OpenMP 4.5 standard the \code{declare}~\code{target} directive was extended to allow static
|
|
data to be mapped, \emph{when needed}, through a \code{link} clause.
|
|
|
|
Data storage for items listed in the \code{link} clause becomes available on the device
|
|
when it is mapped implicitly or explicitly in a \code{map} clause, and it persists for the scope of
|
|
the mapping (as specified by a \code{target} construct,
|
|
a \code{target}~\code{data} construct, or
|
|
\code{target}~\code{enter/exit}~\code{data} constructs).
|
|
|
|
Tip: When all the global data items will not fit on a device and are not needed
|
|
simultaneously, use the \code{link} clause and map the data only when it is needed.
|
|
|
|
The following C and Fortran examples show two sets of data (single precision and double precision)
|
|
that are global on the host for the entire execution on the host; but are only used
|
|
globally on the device for part of the program execution. The single precision data
|
|
are allocated and persist only for the first \code{target} region. Similarly, the
|
|
double precision data are in scope on the device only for the second \code{target} region.
|
|
|
|
\cexample[4.5]{declare_target}{6}
|
|
\ffreeexample[4.5]{declare_target}{6}
|
|
|