+---------------------------------Fortran 95---------------------------------+
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_triplet_spec_list--+---------------------+--)----->< '-,--scalar_mask_expr-' |
>>-index_name-- = --subscript-- : --subscript-- : --subscript---> >--+-------------+--------------------------------------------->< '- : --stride-' |
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.
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.
{(1,4),(2,5),(3,4),(3,5)}
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.
For pointer_assignment, associate, in any order, all targets with the corresponding pointer entities for all active combinations of index_name values.
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----------------------------+