next up previous contents
Next: New Distribution Formats Up: Approved Extensions for Data Mapping Previous: Restrictions on Pointers and

Mapping of Derived Type Components

 

An ALIGN, DISTRIBUTE, or DYNAMIC directive may appear within a derived-type-def wherever a component-def-stmt may appear. Every alignee or distributee within such a directive must be the name of a component defined within that derived-type-def. To allow mapping of the structure components, the rules have to be extended as follows:

H807 distributee-extended is object-name
or template-name
or component-name
or structure-component

A derived type is said to be an explicitly mapped type if any of its components is explicitly mapped or if any of its components is of an explicitly mapped type.

H808 alignee-extended is object-name
or component-name
or structure-component

H809 align-target-extended is object-name
or template-name
or component-name
or structure-component

The above constraints imply that components of derived type can be mapped within the derived type definition itself such that when any objects of that type are created the components will be created with the specified mapping.

Consider the following example:

      TYPE DT
        REAL C(100)
!HPF$   DISTRIBUTE C(BLOCK) ONTO P
      END TYPE DT

      TYPE (DT) :: S1
      TYPE (DT) :: S2(100)
a derived type with one component, array C, which is specified to be distributed block. Therefore the scalar variable S1 of derived type DT has a structure component S1%C that is distributed block onto the processor arrangement P. Similarly, the compontent C of each of the elements of the array S2 will also be distributed block onto the processor arrangement P.

An align directive inside a derived type definition may align a component of the derived type with another component of the same derived type or with another object. A structure component can be used as a target to align other objects including components of derived types.

Example:

!HPF$ TEMPLATE T(100)
!HPF$ DISTRIBUTE T(CYLIC)

      TYPE DT
        REAL, DIMENSION(100) :: A, B, C
!HPF$   ALIGN WITH A :: B
!HPF$   DISTRIBUTE (BLOCK) :: A
!HPF$   ALIGN WITH T :: C
      END TYPE DT

Here variables of derived type DT will be created such the component B is aligned with A, which is itself distributed block, and such that the component C is aligned with a template T that is external to the derived type definition.

Note that if a derived type component is given a partial mapping, it is up to the compiler to choose the rest of the mapping of that component. However, it is expected that the compiler will choose the same mapping for this component of all variables of such a derived type. For example, consider a modification of the above code in which the distribution of the component A is omitted. B and A are specified to be aligned but no distribution is given for A. In such a situation, it is expected that all variables of the derived type DT will be created such that the component A (and in turn the component B) have the same distribution.

The constraints for the mapping of derived type components allow the mapping of structure variables at only one level. Consider for example the following code in which a derived type contains a components that is itself a derived type:

      TYPE SIMPLE
        REAL S(100)
!HPF$   DISTRIBUTE S(BLOCK)
      END TYPE SIMPLE

!HPF TEMPLATE, DISTRIBUTE(BLOCK, *) :: HAIRY_TEMPLATE(47,73)

      TYPE COMPLICATED
        INTEGER SIZE
        REAL RV(100,100), KV(100,100), QV(47,73)
! Arrays RV, KV, and QV may be mapped
!HPF$   DISTRIBUTE (BLOCK, BLOCK):: RV, KV
!HPF$   ALIGN WITH HAIRY_TEMPLATE :: QV
        TYPE(SIMPLE) SV(100)
! The following directive is not valid because SIMPLE
!  is an explicitly mapped type.
!HPF$   DISTRIBUTE SV(BLOCK)
      END TYPE COMPLICATED

      TYPE(COMPLICATED) LOTSOF(20)

! The following directive is not valid because COMPLICATED
! is an explicitly mapped type.
!HPF$ DISTRIBUTE LOTSOF(BLOCK)

Here, a component of the derived type SIMPLE has been mapped; thus objects of this type, e.g., SV in type COMPLICATED, cannot be distributed. The array LOTSOF cannot be distributed for the same reason.

Structure components having the POINTER attribute can be remapped using the REALIGN or REDISTRIBUTE directive if they have been declared DYNAMIC. For example, the following code fragment can be used to allocate and map multiple blocks (called SUBGRID here) of a multi-block grid:

!HPF$ PROCESSORS P( number_of_processors())

      TYPE SUBGRID
        INTEGER SIZE
        INTEGER LO, HI          ! target subset of processors
        REAL, POINTER BL(:)
!HPF   DYNAMIC BL
      END TYPE SUBGRID

      TYPE (SUBGRID), ALLOCATABLE :: GRID(:)

      READ (*,*) SUBGRID_COUNT
      ALLOCATE GRID(SUBGRID_COUNT)
      DO I = 1, SUBGRID_COUNT
        READ(*,*) GRID(I)END DO

! Compute processor subsets for each subgrid, setting
! the LO and HI values
      CALL FIGURE_THE_PROCS ( GRID, number_of_processors())
! Allocate each subgrid and distribute to the computed processors subset
      DO I = 1, SUBGRID_COUNT
        ALLOCATE( GRID(I)%BL( GRID(I)%SIZE ) )
!HPF$   REDISTRIBUTE GRID(I)%BL(BLOCK) ONTO P( GRID(I)%LO : GRID(I)%HI )

Rationale. Components of derived types can be remapped only if they have the POINTER attribute in addition to the DYNAMIC attribute. This restriction has been placed to disallow mappings which cannot be directly specified using HPF directives. Consider, for instance, the following code fragment:

      TYPE DT
        REAL C(100)
!HPF$   DISTRIBUTE C(BLOCK) ONTO P
!HPF$   DYNAMIC C                     ! Nonconforming
      END TYPE DT

      TYPE (DT) :: S(10)
       ...
      J = 3
       ...
!HPF$ REDISTRIBUTE S(J)%C(CYCLIC) ONTO P

        ... S(:)%C(2) ...
Here the component C of derived type DT has been declared DYNAMIC. Thus, the array variable S consists of 10 elements each of which is a structure with a component C initially distributed block. The REDISTRIBUTE directive remaps the structure component C of the Jth element of S so that it is distributed cyclic. Consider now the mapping of the data object referred to by the expression S(:)%C(2) which picks out the second element from each of the ten structures that make up the array variable S. After the redistribution of one of the elements of S (element 3 in this case), each element of the object will reside on processor P(1) except for the third element, which will reside on processor P(2). Such a distribution cannot be specified directly using HPF directives.

The Fortran standard disallows such expressions for components with the POINTER attribute. In particular, if a part-name in a data reference has the POINTER attribute then each part-ref to its left must be scalar (F95:6.1.2). Thus, we avoid the above situation by

(End of rationale.)


next up previous contents
Next: New Distribution Formats Up: Approved Extensions for Data Mapping Previous: Restrictions on Pointers and