\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}