\pagebreak
\section{\code{target} \code{data} Construct}
\label{sec:target_data}

\subsection{Simple \code{target} \code{data} Construct}
\label{subsec:target_data_simple}

This example shows how the \code{target} \code{data} construct maps variables 
to a device data environment. The \code{target} \code{data} construct creates 
a new device data environment and maps the variables \plc{v1}, \plc{v2}, and \plc{p} to the new device 
data environment. The \code{target} construct enclosed in the \code{target} 
\code{data} region creates a new device data environment, which inherits the 
variables \plc{v1}, \plc{v2}, and \plc{p} from the enclosing device data environment. The variable 
\plc{N} is mapped into the new device data environment from the encountering task's data 
environment.

\cexample{target_data}{1}

The Fortran code passes a reference and specifies the extent of the arrays in the 
declaration. No length information is necessary in the map clause, as is required 
with C/C++ pointers.

\ffreeexample{target_data}{1}

\subsection{\code{target} \code{data} Region Enclosing Multiple \code{target} Regions}
\label{subsec:target_data_multiregion}

The following examples show how the \code{target} \code{data} construct maps 
variables to a device data environment of a \code{target} region. The \code{target} 
\code{data} construct creates a device data environment and encloses \code{target} 
regions, which have their own device data environments. The device data environment 
of the \code{target} \code{data} region is inherited by the device data environment 
of an enclosed \code{target} region. The \code{target} \code{data} construct 
is used to create variables that will persist throughout the \code{target} \code{data} 
region.

In the following example the variables \plc{v1} and \plc{v2} are mapped at each \code{target} 
construct. Instead of mapping the variable \plc{p} twice, once at each \code{target} 
construct, \plc{p} is mapped once by the \code{target} \code{data} construct.

\cexample{target_data}{2}


The Fortran code uses reference and specifies the extent of the \plc{p}, \plc{v1} and \plc{v2} arrays. 
No length information is necessary in the \code{map} clause, as is required with 
C/C++ pointers. The arrays \plc{v1} and \plc{v2} are mapped at each \code{target} construct. 
Instead of mapping the array \plc{p} twice, once at each target construct, \plc{p} is mapped 
once by the \code{target} \code{data} construct.

\ffreeexample{target_data}{2}

In the following example, the variable tmp defaults to \code{tofrom} map-type 
and is mapped at each \code{target} construct. The array \plc{Q} is mapped once at 
the enclosing \code{target} \code{data} region instead of at each \code{target} 
construct. 

\cexample{target_data}{3}

In the following example the arrays \plc{v1} and \plc{v2} are mapped at each \code{target} 
construct. Instead of mapping the array \plc{Q} twice at each \code{target} construct, 
\plc{Q} is mapped once by the \code{target} \code{data} construct. Note, the \plc{tmp} 
variable is implicitly remapped for each \code{target} region, mapping the value 
from the device to the host at the end of the first \code{target} region, and 
from the host to the device for the second \code{target} region.

\ffreeexample{target_data}{3}

\subsection{\code{target} \code{data} Construct with Orphaned Call}

The following two examples show how the \code{target} \code{data} construct 
maps variables to a device data environment. The \code{target} \code{data} 
construct's device data environment encloses the \code{target} construct's device 
data environment in the function \code{vec\_mult()}.

When the type of the variable appearing in an array section is pointer, the pointer 
variable and the storage location of the corresponding array section are mapped 
to the device data environment. The pointer variable is treated as if it had appeared 
in a \code{map} clause with a map-type of \code{alloc}. The array section's 
storage location is mapped according to the map-type in the \code{map} clause 
(the default map-type is \code{tofrom}).

The \code{target} construct's device data environment inherits the storage locations 
of the array sections \plc{v1[0:N]}, \plc{v2[:n]}, and \plc{p0[0:N]} from the enclosing target data 
construct's device data environment. Neither initialization nor assignment is performed 
for the array sections in the new device data environment.

The pointer variables \plc{p1}, \plc{v3}, and \plc{v4} are mapped into the target construct's device 
data environment with an implicit map-type of alloc and they are assigned the address 
of the storage location associated with their corresponding array sections. Note 
that the following pairs of array section storage locations are equivalent (\plc{p0[:N]}, 
\plc{p1[:N]}), (\plc{v1[:N]},\plc{v3[:N]}), and (\plc{v2[:N]},\plc{v4[:N]}).

\cexample{target_data}{4}

The Fortran code maps the pointers and storage in an identical manner (same extent, 
but uses indices from 1 to \plc{N}).

The \code{target} construct's device data environment inherits the storage locations 
of the arrays \plc{v1}, \plc{v2} and \plc{p0} from the enclosing \code{target} \code{data} constructs's 
device data environment. However, in Fortran the associated data of the pointer 
is known, and the shape is not required.

The pointer variables \plc{p1}, \plc{v3}, and \plc{v4} are mapped into the \code{target} construct's 
device data environment with an implicit map-type of \code{alloc} and they are 
assigned the address of the storage location associated with their corresponding 
array sections. Note that the following pair of array storage locations are equivalent 
(\plc{p0},\plc{p1}), (\plc{v1},\plc{v3}), and (\plc{v2},\plc{v4}).

\ffreeexample{target_data}{4}


In the following example, the variables \plc{p1}, \plc{v3}, and \plc{v4} are references to the pointer 
variables \plc{p0}, \plc{v1} and \plc{v2} respectively. The \code{target} construct's device data 
environment inherits the pointer variables \plc{p0}, \plc{v1}, and \plc{v2} from the enclosing \code{target} 
\code{data} construct's device data environment. Thus, \plc{p1}, \plc{v3}, and \plc{v4} are already 
present in the device data environment.

\cppexample{target_data}{5}

In the following example, the usual Fortran approach is used for dynamic memory. 
The \plc{p0}, \plc{v1}, and \plc{v2} arrays are allocated in the main program and passed as references 
from one routine to another. In \code{vec\_mult}, \plc{p1}, \plc{v3} and \plc{v4} are references to the 
\plc{p0}, \plc{v1}, and \plc{v2} arrays, respectively. The \code{target} construct's device data 
environment inherits the arrays \plc{p0}, \plc{v1}, and \plc{v2} from the enclosing target data construct's 
device data environment. Thus, \plc{p1}, \plc{v3}, and \plc{v4} are already present in the device 
data environment.

\ffreeexample{target_data}{5}

\subsection{\code{target} \code{data} Construct with \code{if} Clause}
\label{subsec:target_data_if}

The following two examples show how the \code{target} \code{data} construct 
maps variables to a device data environment.

In the following example, the if clause on the \code{target} \code{data} construct 
indicates that if the variable \plc{N} is smaller than a given threshold, then the \code{target} 
\code{data} construct will not create a device data environment.

The \code{target} constructs enclosed in the \code{target} \code{data} region 
must also use an \code{if} clause on the same condition, otherwise the pointer 
variable \plc{p} is implicitly mapped with a map-type of \code{tofrom}, but the storage 
location for the array section \plc{p[0:N]} will not be mapped in the device data environments 
of the \code{target} constructs.

\cexample{target_data}{6}

The \code{if} clauses work the same way for the following Fortran code. The \code{target} 
constructs enclosed in the \code{target} \code{data} region should also use 
an \code{if} clause with the same condition, so that the \code{target} \code{data} 
region and the \code{target} region are either both created for the device, or 
are both ignored.

\ffreeexample{target_data}{6}

In the following example, when the \code{if} clause conditional expression on 
the \code{target} construct evaluates to \plc{false}, the target region will 
execute on the host device. However, the \code{target} \code{data} construct 
created an enclosing device data environment that mapped \plc{p[0:N]} to a device data 
environment on the default device. At the end of the \code{target} \code{data} 
region the array section \plc{p[0:N]} will be assigned from the device data environment 
to the corresponding variable in the data environment of the task that encountered 
the \code{target} \code{data} construct, resulting in undefined values in \plc{p[0:N]}.

\cexample{target_data}{7}

The \code{if} clauses work the same way for the following Fortran code. When 
the \code{if} clause conditional expression on the \code{target} construct 
evaluates to \plc{false}, the \code{target} region will execute on the host 
device. However, the \code{target} \code{data} construct created an enclosing 
device data environment that mapped the \plc{p} array (and \plc{v1} and \plc{v2}) to a device data 
environment on the default target device. At the end of the \code{target} \code{data} 
region the \plc{p} array will be assigned from the device data environment to the corresponding 
variable in the data environment of the task that encountered the \code{target} 
\code{data} construct, resulting in undefined values in \plc{p}.

\ffreeexample{target_data}{7}

