Developer Guide and Reference

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

LOOP

OpenMP* Fortran Compiler Directive: Specifies that the iterations of the associated loops can execute concurrently.

Syntax

!$OMP LOOP [clause[[,] clause]... ]

   do-loop

[!$OMP END LOOP]

clause

Is one of the following:

  • BIND (binding)

    Determines the binding region of the construct. binding is teams, parallel, or thread.

    If teams is specified, and an innermost enclosing teams region exists, the binding region is that innermost teams region. If parallel is specified, the binding region is the innermost enclosing parallel region. It may be an implicit parallel region. If thread is specified, the binding region is not defined.

    If the BIND clause does not appear and the construct is enclosed in a teams or parallel region, the binding region is the innermost enclosing team or parallel region. If no teams or parallel region encloses the loop construct, the binding region is undefined.

    If the binding region is a parallel region, the binding thread set is the set of threads executing the parallel region. If the binding region is a teams region, the biding thread set is the set of primary threads executing the region. If the binding region is not defined, the binding thread is the encountering thread.

  • COLLAPSE (n)

    For n, a value greater than 1 tells the compiler the number of associated loops to collapse into a larger iterations space, which executes without ordering.The associated loop nest must not contain any OpenMP* directives between associated loops in the nest.

    If no COLLAPSE clause appears, or if it appears with a value of 1 for n, only the outermost loop is associated with the LOOP construct.

    At most one COLLAPSE clause is permitted on a LOOP directive.

  • LASTPRIVATE ([CONDITIONAL:] list)

    Only a loop iteration variable of a loop associated with the LOOP construct may appear as a list item in a LASTPRIVATE clause.

  • ORDER ([order-modifier :] CONCURRENT)

  • PRIVATE (list)

  • REDUCTION ([DEFAULT,] reduction-identifier : list)

do-loop

Is a DO loop that may contain other nested DO loops. The DO loops must all be in canonical loop form.

They cannot be DO WHILE loops or loops without loop control. You cannot branch out of a DO loop associated with a LOOP directive. CYCLE and EXIT statements are not permitted. The do-loop can be a DO CONCURRENT loop.

The LOOP construct tells the compiler that all iterations of the associated loops can execute concurrently or in any order.

Data sharing clauses and the COLLAPSE clause are not permitted if do-loop is a DO CONCURRENT loop. Data sharing attributes for DO CONCURRENT loops are determined by locality-specs in the DO CONCURRENT statement. In a DO CONCURRENT loop associated with a LOOP directive, if a variable is referenced in more than one iteration of the DO CONCURRENT loop, and is modified in at least one iteration, the variable must appear in a locality-spec in the DO CONCURRENT statement.

If used, the END LOOP directive must appear immediately after the end of the loop. If you do not specify an END LOOP directive, an END LOOP directive is assumed at the end of the outermost associated do-loop.

A LOOP construct cannot contain calls to procedures containing other OpenMP* constructs or calls to the OpenMP* runtime library functions.

The only OpenMP* constructs permitted inside a LOOP construct are another LOOP, PARALLEL, or SIMD construct or a combined construct whose leftmost construct is a PARALLEL construct.

A LOOP construct that appears in a procedure and is not nested inside another OpenMP* construct must contain a BIND clause.

If more than one loop is associated with the construct, any intervening code between two associated loops executes at least once per iteration of the loop containing the intervening code, and at most once per execution of the innermost loop associated with the construct. If an associated loop has a trip count of zero and that loop does not contain the intervening code, the behavior is undefined.

The set of threads that may execute iterations of the LOOP construct is the binding thread set. Each iteration is executed by one of these threads.

If a loop region is bound to a teams region, the threads in the binding set can continue execution at the end of the loop region without waiting for all iterations of the region to complete execution. All iterations of the loop region must complete execution before the end of the teams region. If the binding region is not a teams region, all iterations of the associated loops must complete execution before the loop region is exited.

If a loop region is bound to a teams or parallel region, it must be encountered by all or none of the binding threads.

A LOOP construct with a BIND clause that specifies a value of teams must be strictly nested inside a teams region. The behavior of a LOOP construct with a BIND clause specifying a value of parallel is undefined if the loop construct is nested inside a SIMD construct.

Referencing a THREADPRIVATE variable in a LOOP construct results in undefined behavior.

If a reduction-modifier is present in a reduction clause, the only permitted value is DEFAULT.

Example

In the following example, the loop iteration variable is private by default, and it is not necessary to explicitly declare it. The END LOOP directive is optional. Iterations of the do loop can execute in any order, or concurrently.

  !$OMP PARALLEL
  !$OMP LOOP
        DO I=1,N
          B(I) = (A(I) + A(I-1)) / 2.0
        END DO
  !$OMP END LOOP
  !$OMP END PARALLEL

In the next example, the loops over J1 and J2 are collapsed and their iteration space is executed by all threads of the current team. The subroutine BAR referenced in the innermost loop cannot contain OpenMP* constructs or calls to procedures that do, and it cannot contain calls to the OpenMP* runtime library. The END LOOP directive is optional:

!$OMP LOOP COLLAPSE(2) PRIVATE(J1, J2, J3)
    DO J1 = J1_L, J1_U, J1_S
        DO J2 = J2_L, J2_U, J2_S
            DO J3 = J3_L, J3_U, J3_S
                CALL BAR(A, J1, J2, J3)
            ENDDO
        ENDDO
    ENDDO
!$OMP END LOOP