# DECLARE MAPPER

OpenMP* Fortran Compiler Directive: Declares a user-defined mapper for a specified type. It also lets you optionally declare a map-identifier that can be used in a MAP clause in other directives or in a motion-clause of a TARGET UPDATE directive. This feature is only available for ifx.

## Syntax

!$OMP DECLARE MAPPER ([mapper-identifier:] type::var) [clause [[,] clause]...]

mapper-identifier | Is a Fortran identifier, or the literal string DEFAULT. If no mapper-identifier is specified, it is as if DEFAULT was specified. A DECLARE MAPPER directive specifying a mapper-identifier for a given type is not permitted in a scope where another DECLARE MAPPER directive specifying the same mapper-identifier for the same type is accessible.
type | Is an accessible type name within the scope where the directive appears. It cannot be an intrinsic or an abstract type. type cannot be directly or indirectly mapped as part of the mapper through another type, except through the appearance of var as a list item in a MAP clause. If type identifies a derived type, it can be any accessible derived type name. In the Description below, DT refers to a derived type identifier.
var | Is a Fortran identifier. It can be used in all MAP clauses of the DECLARE MAPPER directive. No subobject of var is default mapped; all parts of var must be explicitly mapped. var, or at least one element or component of var, must appear in a MAP clause.
clause | Is MAP ([[map-type-modifier [ , ] [map-type-modifier [ , ] . . .]] map-type: ] list). map-type-modifier is either ALWAYS or CLOSE. map-type is ALLOC, TO, FROM or TOFROM. Each map-type can appear only once in a MAP clause. If map-type is not specified, it is as if TOFROM appeared as the map-type. list items are limited to references of var, or other objects that are accessible in the scope or are previously declared in the scope where the DECLARE MAPPER directive appears. A list item can be an array section.

The DECLARE MAPPER directive is a declarative directive that appears in the specification part of a program. type and mapper-identifier, if present, uniquely identify the mapper.

If a DECLARE MAPPER directive is not specified for a type DT, a predefined mapper exists for type DT as if the type DT had appeared in the directive as follows:

    !$OMP DECLARE MAPPER (DT :: var) MAP (TOFROM: var)

A DECLARE MAPPER directive that uses the mapper-identifier DEFAULT for any type DT overrides this predefined mapper for the type DT, and the user-declared mapper becomes the default mapper for all variables of type DT.

If a MAP clause in another directive maps a list item of a type specified in an accessible DECLARE MAPPER directive, or if a motion clause of a TARGET UPDATE invokes a user-defined mapper and updates a list item of type specified by that mapper, the effect is as if the MAP or motion clause is replaced by a set of MAP or motion clauses derived from the MAP clauses specified on the DECLARE MAPPER directive.

A derived type list-item can have more than one map type: one from DECLARE MAPPER, and one from a MAP clause in a TARGET construct.

The following table shows the final map type a mapper applies for a MAP clause that maps a list item of the given type:

- The rows are the map-type specified by the mapper.

- The columns are the specified map-type of the MAP clause invoking the mapper.

- The parenthesized values in the table represent the final map type for a TARGET EXIT DATA construct that invokes a mapper.

  In this case, if the mapper specifies map-type ALLOC or TO, and the TARGET EXIT DATA MAP clause that invokes the mapper has map-type FROM, the resulting map-type is RELEASE.

Map result type of map type combinations
| ALLOC | TO | FROM | TOFROM | RELEASE | DELETE
ALLOC | ALLOC | ALLOC | ALLOC (RELEASE) | ALLOC | RELEASE | DELETE
TO | ALLOC | TO | ALLOC (RELEASE) | TO | RELEASE | DELETE
FROM | ALLOC | ALLOC | FROM | FROM | RELEASE | DELETE
TOFROM | ALLOC | TO | FROM | TOFROM | RELEASE | DELETE

If a set of DECLARE MAPPER directives result in a cyclic definition of mappers, it causes unspecified behavior.

## Example

The following example contains a DECLARE MAPPER directive that maps derived types of type `my_type`. The variable `var` has the type `my_type` and is used in the MAP clause to reference the derived type and its components.

The MAP clause in the DECLARE MAPPER directive specifies that all components of `my_type` are mapped, as well as the dynamic storage in the array section var%values(1:NUM_ELEMENTS). No map-type is specified, so the map type TOFROM is assumed.

Variables used in TARGET regions that are of type `my_type` will be implicitly mapped as prescribed in the DECLARE MAPPER directive’s MAP clause.

      program main
      integer,parameter      :: nvals = 250
      type my_type
        integer              :: num_vals
        integer, allocatable :: values(:)
      end type
      type (my_type)          :: t
      !$omp declare mapper (my_type :: var) map (var, var%values (1:var%num_vals))

      t%num_vals = nvals
      allocate (t%values(t%num_vals))
      !$omp target
      call initial_vals (t)
      !$omp end target
      ...
      contains
        subroutine initial_vals (v)
        type (my_type) :: v
        v%values = 0
        end subroutine initial_vals
       end program

The following example maps the type `my_type` as seen in the previous example.

Type `my_type` is nested within another derived type, `my_type2`. `my_type2` is mapped by a second DECLARE MAPPER directive.

The array component `unmapped` is not mapped and is available on the host only. The component `temp` is allocated on the target and used as temporary storage on the target device. The component `arr` is mapped with the default map type TOFROM. The two mappers are combined when mapping variables of type `my_type2`.

The second DECLARE MAPPER directive uses a mapper-identifier, and maps the variable `x` and the array `y` as well as the type `my_type2`.

    program main
     integer,parameter      :: nvals = 250
     type my_type
       integer              :: num_vals
       integer, allocatable :: values(:)
     end type
     !$omp declare mapper (my_type :: var) map (var, var%values (1:var%num_vals))

     type my_type2
       type (my_type)        :: my_type_var
       type (my_type)        :: temp
       real,dimension(nvals) :: unmapped
       real,dimension(nvals) :: arr
      end type
      type (my_type2)        :: t
      real                   :: x, y(num_vals)
      !$omp declare mapper (my_mapper : my_type2 :: v) map (v%arr, x, y(:)) &
      !$omp&                map (alloc : v%temp)

      !$omp target map (mapper(my_mapper), tofrom : t)
        call calculate(t, x, y)
      !$omp end target
      ...
       end program

Parent topic: C to D

## See Also

OpenMP Fortran Compiler Directives
Syntax Rules for Compiler Directives
TARGET UPDATE
MAP clause