Intel® C++ Compiler 16.0 User and Reference Guide

omp declare reduction

Declares User-Defined Reduction (UDR) functions (reduction identifiers) that can be used as reduction operators in a reduction clause.

Syntax

#pragma omp declare reduction (reduction-identifier : typename-list : combiner) [initializer-clause]

Arguments

reduction-identifier

Is either an identifier or one of the following operators: +, -, *, &, |, ^, && and ||

typename-list

Is a list of type names.

combiner

Is an expression that specifies how partial results can be combined into a single value.

initializer-clause

Is initializer (initializer-expr) where initializer-expr is omp_priv = initializer or function-name ( argument-list ).

At most one initializer-clause can be specified.

If no initializer-clause is specified, the private variables will be initialized following the C rules for initialization of objects with static storage duration.

If no initializer-expr is specified, the private variables will be initialized following the C++ rules for default initialization.

Description

When defining custom reductions, the reduction-identifier and the type identify the declare reduction pragma. The reduction-identifier can later be used in a reduction clause using variables of the type or types specified in the declare reduction pragma. If the pragma applies to several types, it is treated as if there were multiple declare reduction pragmas, one for each type.

The visibility and accessibility of this declaration are the same as those of a variable declared at the same point in the program. The enclosing context of the combiner and of the initializer-expr (if specified) is that of the declare reduction pragma. The combiner and the initializer-expr must be correct in C/C++ as if they were the body of a function defined at the same point in the program.

Note

A reduction-identifier cannot be re-declared in the current scope for the same type or for a type that is compatible according to C/C++ rules.

The following rules and restrictions apply to the combiner:

The following rules and restrictions apply to the optional initializer-expr:

Note

If execution of the combiner or the initializer-expr results in the execution of an OpenMP construct or an OpenMP API call, then the behavior is unspecified.

Example

#define abs(x)   (x<0 ? -x : x)
#define LARGENUM 2147483647
#define N        1000000
int data[N];

// return the smallest magnitude among all the integers in data[N]
int find_min_abs()
{
  int i;
  int result = LARGENUM;

  #pragma omp declare reduction(minabs : int :              \
    omp_out = abs(omp_in) > omp_out ? omp_out : abs(omp_in) \
    initializer (omp_priv=LARGENUM)

  #pragma omp parallel for reduction(minabs:result)
  for (i=0; i<N; i++) {
    if (abs(data[i]) < result) {
      result = abs(data[i]);
    }
  }

  return result;
}