FORALL construct

Standard: F77 F90 F95 F2003 F2008 Example program


<Syntax>

[ construct-name : ] FORALL forall-spec
      forall-body-construct...
END FORALL [ construct-name ]

forall-spec ::= ( [ integer-type-spec :: ] triplet-spec-list [ , mask-expr ] )

triplet-spec-list ::= triplet [ , triplet ]...
triplet ::= name = expr : expr [ : expr ]

forall-body-construct ::= forall-asgn-stmt
| forall-construct
| forall-stmt
| where-construct
| where-stmt

forall-asgn-stmt ::= variable = expr
| variable => expr

The blank between END and FORALL is optional. The END FORALL statement shall have the same construct-name as the FORALL construct statement, or no construct-name if the FORALL construct statement has none.

The mask-expr shall be scalar and of type Logical. All the triplet expressions shall be scalar and of type Integer. If integer-type-spec appears, each name has that type and kind; otherwise, each name has the type and kind it would have as a variable outside the construct, and that type shall be Integer.

<Semantics>

The iteration space of a FORALL construct is the cross-product of the sets of possible index values defined by each triplet, masked by the mask-expr (if present). The scope of the index names is limited to the FORALL construct (or statement); any variable with the same name outside the construct is unaffected.

Each forall-body-construct is processed completely (for the entire iteration space) before proceeding to the next.

A forall-asgn-stmt is processed by evaluating its expr for every element of the iteration space before the assignment or pointer assignment to the variables. If this assignment is a defined assignment, the procedure invoked must be pure.

Each statement in a nested FORALL or WHERE construct is executed fully (over the entire iteration space) before proceeding on to the next. Again, the masks and expressions are evaluated over the entire iteration space before any assignment.

Because of these semantics, execution of FORALL implicitly creates enormous temporary variables to hold the evaluated expressions and can only copy the values into the variables after evaluation is completed. When the programmer knows that there is no conflict between the variables and expressions but it is difficult for the compiler to tell, the FORALL construct will be much slower than the equivalent set of DO loops. For this reason, FORALL should be avoided when possible; instead, use normal DO loops (or a DO CONCURRENT construct), array assignment or a WHERE construct.

The FORALL construct is considered obsolescent in Fortran 2018.

<Related>

Array Assignment, Array Constructor, Array Section, DO CONCURRENT construct, FORALL statement, INTEGER type, PURE attribute, WHERE construct, WHERE statement