Next: Pointers and Subprograms Up: Pointers Previous: Pointers

## Mapped Pointers

As an approved extension to HPF, pointers and targets can be explicitly mapped. Formally, this implies that the constraints that a distributee and an alignee may not have the POINTER or TARGET attribute as stated in

Sections 3.3 and 3.4 respectively, have to be removed.

As in the case of an allocatable object, the mapping specification for a pointer does not take effect immediately but plays a role when the pointer becomes pointer associated with a target either through allocation or through pointer assignment.

When a pointer with an explicit mapping is used in an ALLOCATE statement, the data is allocated with the specified mapping.

For example:

```      REAL, POINTER, DIMENSION(:) :: A, B
!HPF\$ ALIGN B(I) WITH A(I)
!HPF\$ DISTRIBUTE A(BLOCK)
...
ALLOCATE(A(100))
ALLOCATE(B(50))
...
ALLOCATE(B(200))                  ! Nonconforming
```
Pointer A is declared to have a BLOCK distribution while pointer B is declared to be identically aligned with A. When A is allocated, it is created with a block distribution. When B is allocated, it is aligned with the first 50 elements of A. Note that the allocation statements may not occur in the opposite order, since an object may be aligned to another only if it has already been created or allocated. Also, the second allocation for B is nonconforming, since a larger object, B here, cannot be aligned with a smaller object, A in this case.

A pointer P with an explicit mapping can be pointer associated with a target T through a pointer assignment statement under the following conditions:

1. The mapping of T is a specialization of the mapping of P (in particular, T must be a whole array); and
2. If P is explicitly aligned, its ultimate align target has a fully-specified non-transcriptive distribution; and
3.   P and T are either both DYNAMIC or neither is.

Here are some examples:

```      REAL, POINTER, DIMENSION(:,:) :: P
!HPF\$ DISTRIBUTE P(BLOCK,BLOCK)
REAL, TARGET, DIMENSION (100, 100) ::  B, C, D
!HPF\$ DISTRIBUTE B(BLOCK, BLOCK)
!HPF\$ DISTRIBUTE C(BLOCK, CYCLIC)
...
P => B              ! Conforming
P => B(1:50, 1:50)  ! Nonconforming: target must be a whole array.
P => C              ! Nonconforming: the distribution in the
! second dimension does not match
P => D              ! Nonconforming: D is not explicitly mapped
...
```

The intuitive reason that the pointer assignment P => B(1:50, 1:50) above is nonconforming is similar to the reason that the example in Section 4.4.2 (illustrating the difference between INHERIT A and DISTRIBUTE A * ONTO *) is nonconforming: Suppose for instance that the array B is distributed over a 2x2 processor arrangement. Then thesection B(1:50, 1:50) would live entirely on processor (1,1). This mapping is not correctly described by a (BLOCK, BLOCK) distribution for P.

The following pointer assignment is valid even though no processor arrangement is specified for the pointer; in this case, the mapping of B is a specialization of the mapping of P:

```      REAL, POINTER, DIMENSION(:) :: P
REAL, TARGET, DIMENSION(100) :: B
!HPF\$ PROCESSORS PROC(NUMBER_OF_PROCESSORS())
!HPF\$ DISTRIBUTE P(BLOCK)
!HPF\$ DISTRIBUTE (BLOCK) ONTO PROC :: B
...
P => B              ! Conforming
...

REAL, POINTER, DIMENSION(:) :: P
!HPF DISTRIBUTE * :: P
REAL, TARGET, DIMENSION(100) ::  B, C
!HPF DISTRIBUTE B(BLOCK), C(CYCLIC)
...
P => B              ! Conforming
P => C              ! Conforming
P => C(1:50)        ! Nonconforming: target must be a whole array
...
```

Here, the * is used to indicate a transcriptive distribution for the pointer P and thus it can be pointer associated with both targets B and C distributed by BLOCK and CYCLIC respectively. However, it still cannot be used to point to an array section such as C(1:50). To do that, the pointer must have the INHERIT attribute:

```      REAL, POINTER, DIMENSION(:) :: P
!HPF\$ INHERIT :: P
REAL, TARGET, DIMENSION(100) ::  B, C
!HPF\$ DISTRIBUTE B(BLOCK), C(CYCLIC)
...
P => B              ! Conforming
P => C              ! Conforming
P => C(1:50)        ! Conforming
...
```

To allow pointers to have transcriptive distributions, we have to change the constraint for dist-format-clause as specified

in Section 3.3, to read as follows:

• If either the dist-format-clause or the dist-target in a DISTRIBUTE directive begins with ``*'' then every distributee must be a dummy argument, except if the distributee has the POINTER attribute.

The constraint for align-spec as specified in

Section 3.4, should be changed to read as follows:

• If the align-spec in an ALIGN directive begins with ``*'' then every alignee must be a dummy argument, except if the alignee has the POINTER attribute.

The constraint for inheritee as specified in

Section 4.4.2, should be changed to read as follows:

• An inheritee must be a dummy argument, except if the alignee has the POINTER attribute.

When pointers with such transcriptive mappings are used in an ALLOCATE statement, the compiler may choose any arbitrary mapping for the allocated data. A range declaration (see Section 8.11) can be used to restrict the set of distribution formats.

If a pointer has the DYNAMIC attribute, then any target associated with the pointer (which must therefore also have the DYNAMIC attribute) may be remapped using a REALIGN or REDISTRIBUTE statement under the following restriction:

A pointer may be used in REALIGN and REDISTRIBUTE as an alignee, align-target, or distributee if and only if it is currently associated with a whole array, not an array section.

Note that when an object is remapped, the new mapping is visible through any pointer that may be associated with the object.

Next: Pointers and Subprograms Up: Pointers Previous: Pointers