Developer Guide and Reference

ID 767251
Date 10/31/2024
Public
Document Table of Contents

ITERATOR Clause Modifier

Parallel Directive Clause Modifier: An identifier that assumes multiple values in the clause in which it appears.

Syntax

ITERATOR (iterators-definition)

iterators-definition

Is iterators-specifier [, iterators-definition]

iterators-specifier

Is [iterator-type :: ] iterator = range-spec

iterator-type

Is an integer type. If not specified, the iterator type is default integer.

iterator

Is a Fortran identifier.

range-spec

Has the form:

first : last [: stride]

where first and last are scalar expressions that can be converted to iterator-type, and stride is a scalar, non-zero integer expression. If stride is not specified, it is assumed to be 1.

Description

An iterator is similar in function to an implied DO variable. If a list-item in a clause is modified with an iterator, it is as if the list-item appears in the clause with each value of the iterator that the iterator assumes in the clause. If the set of values the iterator assumes is empty, it is as if the list item did not appear in the clause.

An iterator assumes the values i1 … iN where i1 = first, ij = ij-1 + stride where j >= 2 and

if stride > 0:

i1 <= last

iN <= last

iN + stride > last

if stride < 0:

i1 >= last

iN >= last

iN + stride < last

For each value i in the set of values the iterator assumes, the value i + stride must be representable as a value of type iterator-type.

The scope of an iterator is the clause argument (list-item) that it modifies. It blocks accessible symbols with the same name in the context of the clause item it modifies. A variable used in an expression of a range-spec is an implicit reference to that variable in all enclosing OpenMP constructs.

An iterator cannot appear in a range-spec in the same clause. An iterator can only be defined once in a clause.

If the value of stride is zero, the behavior is undefined.

Example

In the following example, the parallel region uses a SINGLE construct containing a loop to generate n tasks, each with an OUT dependency specified through an element of the array vector. Each task calls subroutine ASSIGN_ELEMENT to assign the value i to the corresponding element of the array vector.

Following the loop, another task is generated with n IN dependencies, one for each element of the array vector. The dependencies are created using an iterator. This task waits for the tasks generated by the loop to complete and then calls PRINT_VECTOR to print the elements of the array vector.

SUBROUTINE SUB (VECTOR, N)
INTEGER  :: I, N, VECTOR (N)
  !$OMP PARALLEL 
   !$OMP SINGLE
     DO I=1,N
       !$OMP TASK DEPEND (OUT: VECTOR (I))
          CALL ASSIGN_ELEMENT (VECTOR(I), I)
       !$OMP END TASK
     END DO
   
     !$OMP TASK DEPEND (ITERATOR (INTEGER :: ITER = 1:N), IN: VECTOR(ITER))
        CALL PRINT_VECTOR (VECTOR, N)
     !$OMP END TASK
    !$OMP END SINGLE
   !$OMP END PARALLEL
END SUBROUTINE SUB