%\pagebreak \begin{fortranspecific}[4ex] \section{Fortran Allocatable Array Mapping} \label{sec:fort_allocatable_array_mapping} \index{mapping!allocatable array, Fortran} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The following examples illustrate the use of Fortran allocatable arrays in \kcode{target} regions. In the first example, allocatable variables (\ucode{a} and \ucode{b}) are first allocated on the host, and then mapped onto a device in the Target 1 and 2 sections, respectively. For \ucode{a} the map is implicit and for \ucode{b} an explicit map is used. Both are mapped with the default \kcode{tofrom} map type. The user-level behavior is similar to non-allocatable arrays. However, the mapping operations include creation of the allocatable variable, creation of the allocated storage, setting the allocation status to allocated, and making sure the allocatable variable references the storage. In Target 3 and 4 sections, allocatable variables are mapped in two different ways before they are allocated on the host and subsequently used on the device. In one case, a \kcode{target data} construct creates an enclosing region for the allocatable variable to persist, and in the other case a \kcode{declare target} directive maps the allocation variable for all device executions. In both cases the new array storage is mapped \kcode{tofrom} with the \kcode{always} modifier. An explicit map is used here with an \kcode{always} modifier to ensure that the allocatable variable status is updated on the device. Note: OpenMP 5.1 specifies that an \kcode{always} map modifier guarantees the allocation status update for an existing allocatable variable on the device. %In OpenMP 6.0, this restriction may be relaxed to also guarantee updates %without the \kcode{always} modifier. In Target 3 and 4 sections, the behavior of an allocatable variable is very much like a Fortran pointer, in which a pointer can be mapped to a device with an associated or disassociated status, and associated storage can be mapped and attached as needed. For allocatable variables, the update of the allocation status to allocated (allowing reference to allocated storage) on the device, is similar to pointer attachment. \topmarker{Fortran} \ffreenexample[5.1]{target_fort_allocatable_map}{1} Once an allocatable variable has been allocated on the host, its allocation status may not be changed in a \kcode{target} region, either explicitly or implicitly. The following example illustrates typical operations on allocatable variables that violate this restriction. Note, an assignment that reshapes or reassigns (causing a deallocation and allocation) in a \kcode{target} region is not conforming. Also, an initial intrinsic assignment of an allocatable variable requires deallocation before the \kcode{target} region ends. \topmarker{Fortran} \ffreenexample[5.1]{target_fort_allocatable_map}{2} \newpage The next example illustrates a corner case of this restriction (allocatable status change in a \kcode{target} region). Two allocatable arrays are passed to a subroutine within a \kcode{target} region. The dummy-variable arrays are declared \bcode{allocatable}. Also, the \ucode{ain} variable has the \bcode{intent(in)} attribute, and \ucode{bout} has the \bcode{intent(out)} attribute. For the dummy argument with the attributes \bcode{allocatable} and \bcode{intent(out)}, the compiler will deallocate the associated actual argument when the subroutine is invoked. (However, the allocation on procedure entry can be avoided by specifying the intent as \bcode{intent(inout)}, making the intended use conforming.) \ffreenexample[5.1]{target_fort_allocatable_map}{3} \end{fortranspecific}