Copyright Digital Equipment Corp. All rights reserved.

FORALL

 A generalization of the Fortran 95/90 WHERE statement and
 construct.  It allows more general array shapes to be assigned,
 especially in construct form.  Statement format:

   FORALL (triplet-spec [,triplet-spec]...[,mask-expr]) assign-stmt

 Construct format:

   [name: ] FORALL (triplet-spec [,triplet-spec]...[,mask-expr]) 
   forall-body-stmt
   [forall-body-stmt]...
   END FORALL [name]

   name          Is the name of the FORALL construct.

   triplet-spec  Is a triplet specification with the following form:

     subscript-name = subscript-1 : subscript-2 [:stride]

     The "subscript-name" must be a scalar of type integer.  
     It is valid only within the scope of the FORALL; its
     value is undefined on completion of the FORALL.  

     The "subscript"s and "stride" cannot contain a reference 
     to any "subscript-name" in "triplet-spec".

     The "stride" cannot be zero.  If it is omitted, the default 
     value is 1.

     Evaluation of an expression in a triplet specification must 
     not affect the result of evaluating any other expression in 
     another triplet specification.


   mask-expr  Is a logical array expression (called the mask 
              expression). If it is omitted, the value .TRUE. 
              is assumed. The mask expression can reference the 
              subscript name in "triplet-spec".

   assign-stmt  Is an assignment statement or a pointer assignment
                statement. The variable being assigned to must be 
                an array element or array section and must reference 
                all subscript names included in all "triplet-spec"s.  

   forall-body-stmt  Is one of the following:
                     o An "assign-stmt"
                     o A WHERE statement or construct
                       The WHERE statement or construct uses a mask
                       to make array assignments.
                     o A FORALL statement or construct

 If a construct name is specified in the FORALL statement, the same
 name must appear in the corresponding END FORALL statement.

 A FORALL statement is executed by first evaluating all bounds and
 stride expressions in the triplet specifications, giving a set of
 values for each subscript name.  The FORALL assignment statement is
 executed for all combinations of subscript name values for which
 the mask expression is true.

 The FORALL assignment statement is executed as if all expressions
 (on both sides of the assignment) are completely evaluated before
 any part of the left side is changed.  Valid values are assigned to
 corresponding elements of the array being assigned to.  No element
 of an array can be assigned a value more than once.

 A FORALL construct is executed as if it were multiple FORALL
 statements, with the same triplet specifications and mask
 expressions.  Each statement in the FORALL body is executed
 completely before execution begins on the next FORALL body
 statement.

 Any procedure referenced in the mask expression or FORALL
 assignment statement must be pure.

 Pure functions can be used in the mask expression or called
 directly in a FORALL statement.  Pure subroutines cannot be called
 directly in a FORALL statement, but can be called from other pure
 procedures.

 EXAMPLES:

 Consider the following:

   FORALL(I = 1:N, J = 1:N, A(I, J) .NE. 0.0) B(I, J) = 1.0 / A(I, J)

 This statement takes the reciprocal of each nonzero element of
 array A(1:N, 1:N) and assigns it to the corresponding element of
 array B.  Elements of A that are zero do not have their reciprocal
 taken, and no assignments are made to corresponding elements of B.

 Every array assignment statement and WHERE statement can be written
 as a FORALL statement, but some FORALL statements cannot be written
 using just array syntax.  For example, the preceding FORALL
 statement is equivalent to the following:

   WHERE(A /= 0.0) B = 1.0 / A

 It is also equivalent to:

   FORALL (I = 1:N, J = 1:N)
     WHERE(A(I, J) .NE. 0.0) B(I, J) = 1.0/A(I, J)
   END FORALL

 However, the following FORALL example cannot be written using just
 array syntax:

    FORALL(I = 1:N, J = 1:N) H(I, J) = 1.0/REAL(I + J - 1)

 This statement sets array element H(I, J) to the value 1.0/REAL(I +
 J - 1) for values of I and J between 1 and N.

 Consider the following:

   TYPE MONARCH
     INTEGER, POINTER :: P
   END TYPE MONARCH

   TYPE(MONARCH), DIMENSION(8)   :: PATTERN
   INTEGER, DIMENSION(8), TARGET :: OBJECT
   FORALL(J=1:8)  PATTERN(J)%P => OBJECT(1+IEOR(J-1,2))

 This FORALL statement causes elements 1 through 8 of array PATTERN
 to point to elements 3, 4, 1, 2, 7, 8, 5, and 6, respectively, of
 OBJECT.  IEOR can be referenced here because it is pure.

 The following example shows a FORALL construct:

   FORALL(I = 3:N + 1, J = 3:N + 1)
     C(I, J) = C(I, J + 2) + C(I, J - 2) + C(I + 2, J) + C(I - 2, J)
     D(I, J) = C(I, J)
   END FORALL

 The assignment to array D uses the values of C computed in the
 first statement in the construct, not the values before the
 construct began execution.

 FORALL is a language feature of Fortran 95.