\pagebreak \section{\kcode{declare mapper} Directive} \label{sec:declare_mapper} \index{directives!declare mapper@\kcode{declare mapper}} \index{declare mapper directive@\kcode{declare mapper} directive} The following examples show how to use the \kcode{declare mapper} directive to prescribe a map for later use. It is also quite useful for pre-defining partitioned and nested structure elements. In the first example the \kcode{declare mapper} directive specifies that any structure of type \ucode{myvec_t} for which implicit data-mapping rules apply will be mapped according to its \kcode{map} clause. The variable \ucode{v} is used for referencing the structure and its elements within the \kcode{map} clause. Within the \kcode{map} clause the \ucode{v} variable specifies that all elements of the structure are to be mapped. Additionally, the array section \ucode{v.data[0:v.len]} specifies that the dynamic storage for data is to be mapped. Within the main program the \ucode{s} variable is typed as \ucode{myvec_t}. Since the variable is found within the \kcode{target} region and the type has a mapping prescribed by a \kcode{declare mapper} directive, it will be automatically mapped according to its prescription: full structure, plus the dynamic storage of the \ucode{data} element. %Note: By default the mapping is \kcode{tofrom}. %The associated Fortran allocatable \ucode{data} array is automatically mapped with the derived %type, it does not require an array section as in the C/C++ example. \cexample[5.0]{target_mapper}{1} \ffreeexample[5.0]{target_mapper}{1} %\pagebreak \index{mapping!deep copy} \index{map clause@\kcode{map} clause!mapper modifier@\kcode{mapper} modifier} \index{mapper modifier@\kcode{mapper} modifier} The next example illustrates the use of the \plc{mapper-identifier} and deep copy within a structure. The structure, \ucode{dzmat_t}, represents a complex matrix, with separate real (\ucode{r_m}) and imaginary (\ucode{i_m}) elements. Two map identifiers are created for partitioning the \ucode{dzmat_t} structure. For the C/C++ code the first identifier is named \ucode{top_id} and maps the top half of two matrices of type \ucode{dzmat_t}; while the second identifier, \ucode{bottom_id}, maps the lower half of two matrices. Each identifier is applied to a different \kcode{target} construct, as \kcode{map(mapper(\ucode{top_id}), tofrom: \ucode{a,b})} and \kcode{map(mapper(\ucode{bottom_id}), tofrom: \ucode{a,b})}. Each target offload is allowed to execute concurrently on two different devices (\ucode{0} and \ucode{1}) through the \kcode{nowait} clause. %The OpenMP 5.1 \kcode{parallel masked} construct creates a region of two threads %for these \kcode{target} constructs, with a single thread (\plc{primary}) generator. The Fortran code uses the \ucode{left_id} and \ucode{right_id} map identifiers in the \kcode{map(mapper(\ucode{left_id}),tofrom: \ucode{a,b})} and \kcode{map(mapper(\ucode{right_id}),tofrom: \ucode{a,b})} map clauses. The array sections for these left and right contiguous portions of the matrices were defined previously in the \kcode{declare mapper} directive. Note, the \ucode{is} and \ucode{ie} scalars are firstprivate by default for a \kcode{target} region, but are declared firstprivate anyway to remind the user of important firstprivate data-sharing properties required here. \cexample[5.0]{target_mapper}{2} \ffreeexample[5.0]{target_mapper}{2} %\pagebreak In the third example \ucode{myvec} structures are nested within a \ucode{mypoints} structure. The \ucode{myvec_t} type is mapped as in the first example. Following the \ucode{mypoints} structure declaration, the \ucode{mypoints_t} type is mapped by a \kcode{declare mapper} directive. For this structure the \ucode{hostonly_data} element will not be mapped; also the array section of \ucode{x} (\ucode{v.x[:1]}) and \ucode{x} will be mapped; and \ucode{scratch} will be allocated and used as scratch storage on the device. The default map-type mapping, \kcode{tofrom}, applies to the \ucode{x} array section, but not to \ucode{scratch} which is explicitly mapped with the \kcode{alloc} map-type. Note: the variable \ucode{v} is not included in the map list (otherwise the \ucode{hostonly_data} would be mapped)-- just the elements to be mapped are listed. The two mappers are combined when a \ucode{mypoints_t} structure type is mapped, because the mapper \ucode{myvec_t} structure type is used within a \ucode{mypoints_t} type structure. %Note, in the main program \ucode{P} is an array of \ucode{mypoints_t} type structures, %and hence every element of the array is mapped with the mapper prescription. \cexample[5.0]{target_mapper}{3} \ffreeexample[5.0]{target_mapper}{3}