XL Fortran for AIX 8.1

Language Reference

+---------------------------------Fortran 95---------------------------------+

FORALL

Purpose

The FORALL statement performs assignment to groups of subobjects, especially array elements. Unlike the WHERE statement, assignment can be performed on an elemental level rather than on an array level. The FORALL statement also allows pointer assignment.

Format



>>-FORALL--forall_header--forall_assignment--------------------><
 
 

forall_header



>>-(--forall_triplet_spec_list--+---------------------+--)-----><
                                '-,--scalar_mask_expr-'
 
 

forall_triplet_spec



>>-index_name-- = --subscript-- : --subscript-- : --subscript--->
 
>--+-------------+---------------------------------------------><
   '- : --stride-'
 
 

forall_assignment
is either assignment_statement or pointer_assignment_statement

scalar_mask_expr
is a scalar logical expression

subscript, stride
are each scalar integer expressions

Rules

Only pure procedures can be referenced in the mask expression of forall_header and in a forall_assignment (including one referenced by a defined operation or assignment).

index_name must be a scalar integer variable. It is also a statement entity; that is, it does not affect and is not affected by other entities in the scoping unit.

In forall_triplet_spec_list, neither a subscript nor a stride can contain a reference to any index_name in the forall_triplet_spec_list. Evaluation of any expression in forall_header must not affect evaluation of any other expression in forall_header.

Given the forall_triplet_spec

     index1 = s1:s2:s3

the maximum number of index values is determined by:

     max = INT((s2-s1+s3)/s3)

If the stride (s3 above) is not specified, a value of 1 is assumed. If max <= 0 for any index, forall_assignment is not executed. For example,

     index1 = 2:10:3    !  The index values are 2,5,8.
                           max = INT((10-2+3)/3) = 3.
 
     index2 = 6:2:-1    !  The index values are 6,5,4,3,2.
     index2 = 6:2       !  No index values.

If the mask expression is omitted, a value of .TRUE. is assumed.

No atomic object can be assigned to more than once. Assignment to a nonatomic object assigns to all subobjects or associates targets with all subobjects.

Interpreting the FORALL Statement
  1. Evaluate the subscript and stride expressions for each forall_triplet_spec in any order. All possible pairings of index_name values form the set of combinations. For example, given the following statement:
    FORALL (I=1:3,J=4:5) A(I,J) = A(J,I)
    
    The set of combinations of I and J is:
        {(1,4),(1,5),(2,4),(2,5),(3,4),(3,5)}
    

    The -1 and -qnozerosize compiler options do not affect this step.

  2. Evaluate the scalar_mask_expr for the set of combinations, in any order, producing a set of active combinations (those for which scalar_mask_expr evaluated to .TRUE.). For example, if the mask (I+J.NE.6) is applied to the above set, the set of active combinations is:
        {(1,4),(2,5),(3,4),(3,5)}
    
  3. For assignment_statement, evaluate, in any order, all values in the right-hand side expression and all subscripts, strides, and substring bounds in the left-hand side variable for all active combinations of index_name values.

    For pointer_assignment, determine, in any order, what will be the targets of the pointer assignment and evaluate all subscripts, strides, and substring bounds in the pointer for all active combinations of index_name values. Whether or not the target is a pointer, the determination of the target does not include evaluation of its value.

  4. For assignment_statement, assign, in any order, the computed expression values to the corresponding variable entities for all active combinations of index_name values.

    For pointer_assignment, associate, in any order, all targets with the corresponding pointer entities for all active combinations of index_name values.

Loop Parallelization

The FORALL statement and FORALL construct are designed to allow for parallelization of assignment statements. When executing an assignment statement in a FORALL, the assignment of an object will not interfere with the assignment of another object. In the next example, the assignments to elements of A can be executed in any order without changing the results:

  FORALL (I=1:3,J=1:3) A(I,J)=A(J,I)

+-------------------------------IBM Extension--------------------------------+

The INDEPENDENT directive asserts that each iteration of a DO loop or each operation in a FORALL statement or FORALL construct can be executed in any order without affecting the semantics of the program. The operations in a FORALL statement or FORALL construct are defined as:

Thus, the following loop,

         INTEGER, DIMENSION(2000) :: A,B,C
!IBM*  INDEPENDENT
         DO I = 1, 1999, 2
           A(I) = A(I+1)
         END DO

is semantically equivalent to the following array assignment:

         INTEGER, DIMENSION(2000) :: A,B,C
         A(1:1999:2) = A(2:2000:2)
Tip

If it is possible and beneficial to make a specific FORALL parallel, specify the INDEPENDENT directive before the FORALL statement. Because XL Fortran may not always be able to determine whether it is legal to parallelize a FORALL, the INDEPENDENT directive provides an assertion that it is legal.

+----------------------------End of IBM Extension----------------------------+

Examples

INTEGER A(1000,1000), B(200)
I=17
FORALL (I=1:1000,J=1:1000,I.NE.J) A(I,J)=A(J,I)
PRINT *, I    ! The value 17 is printed because the I
              ! in the FORALL has statement scope.
FORALL (N=1:200:2) B(N)=B(N+1)
END

Related Information

+----------------------------End of IBM Extension----------------------------+


[ Top of Page | Previous Page | Next Page | Table of Contents | Index ]