A variable with the ALLOCATABLE attribute may appear as an alignee in an ALIGN directive or as a distributee in a DISTRIBUTE directive. Such directives do not take effect immediately, however; they take effect each time the array is allocated by an ALLOCATE statement, rather than on entry to the scoping unit. The values of all specification expressions in such a directive are determined once on entry to the scoping unit and may be used multiple times (or not at all). For example:
SUBROUTINE MILLARD_FILLMORE(N,M) REAL, ALLOCATABLE, DIMENSION(:) :: A, B !HPF$ ALIGN B(I) WITH A(I+N) !HPF$DISTRIBUTE A(BLOCK(M*2)) N = 43 M = 91 ALLOCATE(A(27)) ALLOCATE(B(13)) ...
The values of the expressions N and M*2 on entry to the subprogram are conceptually retained by the ALIGN and DISTRIBUTE directives for later use at allocation time. When the array A is allocated, it is distributed with a block size equal to the retained value of M*2, not the value 182. When the array B is allocated, it is aligned relative to A according to the retained value of N, not its new value 43.
Note that it would have been incorrect in the MILLARD_FILLMORE example to perform the two ALLOCATE statements in the opposite order. In general, when an object X is created it may be aligned to another object Y only if Y has already been created or allocated. The following example illustrates several related cases.
SUBROUTINE WARREN_HARDING(P,Q) REAL P(:) REAL Q(:) REAL R(SIZE(Q)) REAL, ALLOCATABLE :: S(:),T(:) !HPF$ ALIGN P(I) WITH T(I) !Nonconforming !HPF$ ALIGN Q(I) WITH *T(I) !Nonconforming !HPF$ ALIGN R(I) WITH T(I) !Nonconforming !HPF$ ALIGN S(I) WITH T(I) ALLOCATE(S(SIZE(Q))) !Nonconforming ALLOCATE(T(SIZE(Q)))
Three ALIGN directives are not HPF-conforming because the array T has not yet been allocated at the time that the various alignments must take place. The four cases differ slightly in their details. The arrays P and Q already exist on entry to the subroutine, but because T is not yet allocated, one cannot correctly prescribe the alignment of P or describe the alignment of Q relative to T. (See Section 4 for a discussion of prescriptive and descriptive directives.) The array R is created on subroutine entry and its size can correctly depend on the SIZE of Q, but the alignment of R cannot be specified in terms of the alignment of T any more than its size can be specified in terms of the size of T. It is permitted to have an alignment directive for S in terms of T, because the alignment action does not take place until S is allocated; however, the first ALLOCATE statement is nonconforming because S needs to be aligned but at that point in time T is still unallocated.
When an array is allocated, it will be aligned to an existing object or template if there is an explicit ALIGN directive for the allocatable variable. If there is no explicit ALIGN directive, then the array will be ultimately aligned with itself. It is forbidden for any other object to be ultimately aligned to an array at the time the array becomes undefined by reason of deallocation. All this applies regardless of whether the name originally used in the ALLOCATE statement when the array was created had the ALLOCATABLE attribute or the POINTER attribute.
Pointers cannot be explicitly mapped in HPF and thus can only be associated with objects which are not explicitly mapped. When used for allocation, the compiler may choose any arbitrary mapping for data allocated through the pointer. Explicit mapping of pointers is allowed under the approved extensions (see section 8.8). Also, the relationship of pointers and sequence attributes is described in