Intel® Fortran Compiler Classic and Intel® Fortran Compiler Developer Guide and Reference

ID 767251
Date 11/07/2023
Public

A newer version of this document is available. Customers should click here to go to the newest version.

Document Table of Contents

SCAN Directive

OpenMP* Fortran Compiler Directive: Specifies a scan computation that updates each list item in each iteration of the loop.

Syntax

loop-associated-directive

do-loop-headers

   block

   !$OMP SCAN clause

   block

do-termination-statements

[end-loop-associated-directive]

loop-associated-directive

Is a SIMD or TARGET SIMD directive.

do-loop-headers

Is one or more Fortran DO statements.

block

Is a structured block (section) of statements or constructs.

clause

Is one of the following:

  • INCLUSIVE (list)

  • EXCLUSIVE (list)

If an INCLUSIVE clause appears, an inclusive scan computation is performed for each list item in the clause. If an EXCLUSIVE clause appears, an exclusive scan computation is performed for each list item in the clause.

do-termination-statements

Is one or more Fortran DO-loop terminal statements, such as END DO, CONTINUE, or a terminal statement for a nonblock DO construct.

end-loop-associated-directive

Is an optional END SIMD or END TARGET SIMD directive.

The SCAN directive can appear in the body of a loop or loop nest that is in a worksharing construct, a worksharing-loop SIMD, or a SIMD construct.

There are two phases for each iteration of a SCAN loop, as follows:

  • The input phase

    For each iteration of an INCLUSIVE scan loop, the statements that appear lexically prior to the SCAN directive constitute the input phase.

    For each iteration, except the last iteration of an EXCLUSIVE scan loop, the statements that lexically precede the directive constitute the input phase.

  • The scan phase

    For each iteration of an INCLUSIVE scan loop, the statements that follow the directive constitute the scan phase.

    For each iteration, except the last iteration of an EXCLUSIVE scan loop, the statements that lexically follow the directive constitute the scan phase.

The last loop iteration does not have an input phase. For this iteration, all statements lexically preceding and following the directive constitute the scan phase. All computations that update a list item during an iteration are contained in the input phase. A statement that references a list item in the scan phase uses the result of the scan operation for that iteration.

For a given iteration, the result of a scan operation is calculated according to the last generalized prefixed sum (PRESUMlast) applied to the sequence of values given by the original value of the list item upon entry of the loop construct, and updated values given the list item in each of the iterations of the loop. The PRESUMlast (op, a1, . . . an) is defined for a binary operation op and a sequence of N values a1, . . . an as follows:

  • If N = 1, a1

  • If N > 1, op (PRESUMlast (op, a1, . . . ak), PRESUMlast (op, ak+1, . . . an)) where 1 <= K <= N

At the beginning of the input phase for each iteration, the list item is initialized with the initializer value of the reduction-identifier specified by the REDUCTION clause on the innermost enclosing OpenMP* construct. For a given iteration, the update value of a list item is the value of the list item upon completion of the iteration’s input phase.

If orig_value is the initial value of a list item upon entry to a worksharing-loop, worksharing SIMD, or SIMD construct, if combiner is the combiner for the reduction-identifier specified in the REDUCTION clause on the construct, and update-valuei is the value for the list item for iteration i, then at the beginning of the scan phase of the first iteration, a list item of an INCLUSIVE clause on a SCAN directive is assigned the result of the operation PRESUMlast (combiner, orig_value, update-value1 . . . update-valuei). At the beginning of the scan phase of the first iteration, a list item of an EXCLUSIVE clause on a SCAN directive is assigned the value orig_value. At the beginning of the scan phase of each subsequent iteration, i > 1, a list item of an EXCLUSIVE clause on a SCAN directive is the result of the operation PRESUMlast (combiner, orig_value, update-value1 . . . update-valuei-1).

A worksharing-loop, worksharing-loop SIMD, or a SIMD construct that has a REDUCTION clause with the INSCAN modifier must contain exactly one SCAN directive in the loop body of the construct, and a list item in an INCLUSIVE or EXCLUSIVE clause must be a list item in the REDUCTION clause of the construct.

With the exception of dependencies for list items in the INCLUSIVE or EXCLUSIVE clause, cross-iteration dependencies across loop iterations are not permitted. Except for INCLUSIVE or EXCLUSIVE clause list-item dependencies, intra-iteration dependencies between a statement lexically preceding the SCAN directive and a statement lexically following a SCAN directive are not permitted.

NOTE:

Currently, ifort only supports SCAN directives on SIMD construct directives. However, ifx supports SCAN directives on SIMD and TARGET SIMD construct directives.

Example

The following contains an inclusive and an exclusive scan SIMD loop:


  real,dimension(10)   :: a, b
  real                 :: s
  integer              :: i
  ...

  do i = 1, 10
    a(i) = real (i)
  end do
  s = 0.0
  ! Inclusive scan
  !$omp simd reduction (inscan, +:s)
  do i = 1, 10
    s    = s + a(i)
    !$omp scan inclusive (s)
    b(i) = s
  end do
  print *, b

  s = 0.0
  ! Exclusive scan
  !$omp simd reduction (inscan, +:s)
  do i = 1, 10
    b(i) = s
    !$omp scan exclusive (s)
    s    = s + a(i)
  end do
  print *, b

The first print statement prints the sequence 1.0 3.0 6.0 10.0 15.0 21.0 28.0 36.0 45.0 55.0. The second print statement prints the sequence 0.0 1.0 3.0 6.0 10.0 15.0 21.0 28.0 36.0 45.0.

See Also