!HPF$ INDEPENDENT DO I = 1, 10 WRITE (IOUNIT(I),100) A(I) END DO 100 FORMAT ( F10.4 )
If IOUNIT(I) evaluates to a different value for every value of I from 1 to 10, then the loop writes to a different I/O unit (and thus a different file) on every iteration. The loop is then properly described as independent. On the other hand, if IOUNIT(I)=5 for all I, then the assertion is in eror and the directive is not HPF-conforming.
!HPF$ INDEPENDENT, NEW (J) DO I = 2, 100, 2 !HPF$ INDEPENDENT, NEW(VL, VR, UL, UR) DO J = 2 , 100, 2 VL = P(I,J) - P(I-1,J) VR = P(I+1,J) - P(I,J) UL = P(I,J) - P(I,J-1) UR = P(I,J+1) - P(I,J) P(I,J) = F(I,J) + P(I,J) + 0.25 * (VR - VL + UR- UL) END DO END DO
Without the NEW clause on the J loop, neither loop would be independent, because an interleaved execution of loop iterations might cause other values of VL, VR, UL, and UR to be used in the assignment of P(I,J) tahn those computed in teh same iteration of the loop. The NEWclause, however, specifies that this is not true if distingct storage units are used in each iteration of the loop. Using this implementation makes iterations of the loops independent of each other. Note that there is no interference due to accesses of the array P because of the stride of the DO loop (i.e. I and J are always even, therefore I-1, etc., are always odd.)
When the loops are nested, a reduction variable may need to be protected in an independent outer loop even though the reduction operations in which it occurs are nested inside an inner loop. Moreover, the inner loop and any intervening loops may or may not be independent.
! Nested Loop Example 1. Inner loop is sequential X = 10 OUTER: DO WHILE (X < 1000) ! this loop is sequential !HPF$ INDEPENDENT, NEW(J), REDUCTION(X) MIDDLE: DO I = 1, N INNER: DO J = 1, M X = X + J ! Note that it would be incorrect to refer to X ! here, except in another reduction statement END DO INNER ! Note that it would be incorrect to refer to X ! here, except in another reduction statement END DO MIDDLE PRINT *, X END DO OUTER
Since the variable X occurs in a reduction clause for loop MIDDLE, it is a protected reduction variable throughout that loop, including inside the inner loop. If INNER had an INDEPENDENT directive, it would be incorrect to include X in a REDUCTION or a NEW clause of that directive. The outermost loop is not independent, and so X need not and cannot be protected in that part of its range outside the middle loop.
A variable that occurs in a NEW clause must not be a reduction variable in the same or a containing loop, although it may be used as a reduction variable in a contained loop:
! Nested Loop Example 2. Outer loop NEW clause. !HPF$ INDEPENDENT, NEW(I) OUTER: DO K = 1, 100 !HPF$ INDEPENDENT, NEW (J,X) MIDDLE: DO I = 1, N X = 10 !HPF$ INDEPENDENT, REDUCTION(X) INNER: DO J = 1, M X = X + J**2 ! Note that it would be incorrect to refer to X ! here, except in another reduction statement END DO INNER Y(I) = X END DO MIDDLE END DO OUTER
Here, X is a protected reduction variable only in the inner loop.
INTEGER, DIMENSION(M) :: VECTOR !HPF$ INDEPENDENT, REDUCTION(X, Y) DO I = 1, N-4 X(I:I+4) = X(I:I+4) + A(I) ! As many as 5 updates Y(VECTOR) = Y(VECTOR) + B(I,1:N) END DO
Note that the compiler, if it distributes iterations of this loop in a block-wise manner, will not need to make a private copy of the entire array X on each processor.
If a statement that has the form of a reduction statement occurs while an independent loop is active, but the updated variable is not a protected reduction variable, then the programmer is guaranteeing that no two iterations of the independent loop will update the same location. For example:
!HPF$ INDEPENDENT DO I = 1, N ! X is NOT a reduction variable, but ! I know there are no repeated values in INDX(1:N) ! Updates will be written directly to X(INDX(I)) X(INDX(I)) = X(INDX(I)) + F(I) ! I also guarantee that the condition in the IF statement ! is true for at most one value of I. IF (A(I) > B(I)) Y = Y + 1 END DO