REDUCTION Clause

Use the REDUCTION clause on the PARALLEL, DO, SECTIONS, PARALLEL DO, and PARALLEL SECTIONS directives to perform a reduction on the specified variables by using an operator or intrinsic as shown:

Example

REDUCTION (operator or intrinsic :list )

where:

The specified variables must be named variables of intrinsic type and must be SHARED in the enclosing context. Deferred-shape and assumed-size arrays are not allowed. A private copy of each specified variable is created for each thread as if you had used the PRIVATE clause. The private copy is initialized to a value that depends on the operator or intrinsic as shown in the following table. The actual initialization value is consistent with the data type of the reduction variable.

Operators/Intrinsics and Initialization Values for Reduction Variables

Operators/Intrinsic

Initialization Value

+

0

*

1

-

0

.AND.

.TRUE.

.OR.

.FALSE.

.EQV.

.TRUE.

.NEQV.

.FALSE.

MAX

Largest representable number

MIN

Smallest representable number

IAND

All bits on

IOR

0

IEOR

0

At the end of the construct to which the reduction applies, the shared variable is updated to reflect the result of combining the original value of the SHARED reduction variable with the final value of each of the private copies using the specified operator.

Except for subtraction, all of the reduction operators are associative and the compiler can freely reassociate the computation of the final value. The partial results of a subtraction reduction are added to form the final value.

The value of the shared variable becomes undefined when the first thread reaches the clause containing the reduction, and it remains undefined until the reduction computation is complete. Normally, the computation is complete at the end of the REDUCTION construct. However, if you use the REDUCTION clause on a construct to which NOWAIT is also applied, the shared variable remains undefined until a barrier synchronization has been performed. This ensures that all of the threads have completed the REDUCTION clause.

The REDUCTION clause is intended to be used on a region or worksharing construct in which the reduction variable is used only in reduction statements having one of the following forms:

Form

Description

x = x operator expr

x is a scalar variable of intrinsic type

x = expr operator x

except for subtraction

x = intrinsic (x, expr)

intrinsic is either MAX, MIN, IAND, IOR, or IEOR

x = intrinsic (expr, x)

operator is either +, *, -, /, .AND., .OR., .EQV., or .NEQV.

Some reductions can be expressed in other forms. For instance, a MAX reduction might be expressed as follows:

Example

IF (x .LT. expr) x = expr

Alternatively, the reduction might be hidden inside a subroutine call. Be careful that the operator specified in the REDUCTION clause matches the reduction operation.

Any number of reduction clauses can be specified on the directive, but a variable can appear only once in a REDUCTION clause for that directive as shown in the following example:

Example

!$OMP DO REDUCTION(+: A, Y),REDUCTION(.OR.: AM)

The following example shows how to use the REDUCTION clause:

Example

!$OMP PARALLEL DO DEFAULT(PRIVATE),SHARED(A,B),REDUCTION(+: A,B)
DO I=1,N
CALL WORK(ALOCAL,BLOCAL)
A = A + ALOCAL
B = B + BLOCAL
END DO
!$OMP END PARALLEL DO