\subsection{User-Defined Reduction}
\label{subsec:UDR}
\index{reductions!user-defined}
\index{reductions!declare reduction directive@\kcode{declare reduction} directive}
\index{declare reduction directive@\kcode{declare reduction} directive}
\index{directives!declare reduction@\kcode{declare reduction}}
\index{declare reduction directive@\kcode{declare reduction} directive!initializer clause@\kcode{initializer} clause}
\index{declare reduction directive@\kcode{declare reduction} directive!combiner}
\index{declare reduction directive@\kcode{declare reduction} directive!OpenMP variable identifiers}
\index{OpenMP variable identifiers!omp_in@\kcode{omp_in}}
\index{OpenMP variable identifiers!omp_out@\kcode{omp_out}}
\index{OpenMP variable identifiers!omp_priv@\kcode{omp_priv}}
\index{combiner}
\index{clauses!initializer@\kcode{initializer}}
\index{initializer clause@\kcode{initializer} clause}

The \kcode{declare reduction} directive can be used to specify 
user-defined reductions (UDR) for user data types.

%The following examples show how user-defined reductions can be used to support user data types in the \code{reduction} clause.

%The following example computes the enclosing rectangle of a set of points. The point data structure (\code{struct}~\code{point}) is not supported by the \code{reduction} clause. Using two \code{declare}~\code{reduction} directives we define how a reduction for the point data structure is done for the \plc{min} and \plc{max} operations. Each \code{declare}~\code{reduction} directive calls the appropriate function that passes the two special variables that can be used in the user-defined reduction expression: \code{omp\_in}, which holds one of the two values to reduce, and \code{omp\_out}, which holds the other value and should hold also the result of the reduction once the expression has been executed. Note, also, that when defining the user-defined reduction for \plc{min} we specify how the private variables of each thread are to be initialized (that is, the neutral value). This is not the case for \plc{max} as the default values (that is, zero filling) are already adequate.


In the following example, \kcode{declare reduction} directives are used to define
\plc{min} and \plc{max} operations for the \ucode{point} data structure for computing
the rectangle that encloses a set of 2-D points.

Each \kcode{declare reduction} directive defines new reduction identifiers,
\ucode{min} and \ucode{max}, to be used in a \kcode{reduction} clause. The next item in the
declaration list is the data type (\ucode{struct point}) used in the
reduction.
The \kcode{combiner} clause specifies the functions \ucode{minproc} and
\ucode{maxproc} to perform
the min and max operations, respectively, on the user data (of type \ucode{struct point}).
In the function argument list are two special OpenMP variable identifiers, \kcode{omp_in} and \kcode{omp_out},
that denote the two values to be combined in the ``real'' function;
the \kcode{omp_out} identifier indicates which one is to hold the result.

The initializer of the \kcode{declare reduction} directive specifies
the initial value for the private variable of each implicit task.
The \kcode{omp_priv} identifier is used to denote the private variable.

\cexample[6.0]{udr}{1}
%\clearpage

The following example shows the corresponding code in Fortran. 
The \kcode{declare reduction} directives are specified as part of 
the declaration in subroutine \ucode{find_enclosing_rectangle} and 
the procedures that perform the min and max operations are specified as subprograms.

\ffreeexample[6.0]{udr}{1}


The following example shows the same computation as \example{udr.1} but it illustrates that you can craft complex expressions in the user-defined 
reduction declaration. In this case, instead of calling the \ucode{minproc} 
and \ucode{maxproc} functions we inline the code in a single expression.

\cexample[6.0]{udr}{2}

The corresponding code of the same example in Fortran is very similar
except that the assignment expression in the \kcode{combiner} clause for
the \kcode{declare reduction}
directive can only be used for a single variable, in this case through
a type structure constructor \ucode{point($\ldots$)}.

\ffreeexample[6.0]{udr}{2}


\index{OpenMP variable identifiers!omp_orig@\kcode{omp_orig}}
The following example shows the use of special variables in arguments for 
combiner (\kcode{omp_in} and \kcode{omp_out}) and initializer 
(\kcode{omp_priv} and \kcode{omp_orig}) routines.  This example returns 
the maximum value of an array and the corresponding index value. The 
\kcode{declare reduction} directive specifies a user-defined 
reduction operation \ucode{maxloc} for data type \ucode{struct mx_s}. 
The function \ucode{mx_combine} is the combiner and the function \ucode{mx_init} 
is the initializer.

\cexample[6.0]{udr}{3}

Below is the corresponding Fortran version of the above example.  
The \kcode{declare reduction} directive specifies the user-defined 
operation \ucode{maxloc} for user-derived type \ucode{mx_s}.  
The combiner \ucode{mx_combine} and the initializer \ucode{mx_init} are 
specified as subprograms.

\ffreeexample[6.0]{udr}{3}


The following example explains a few details of the user-defined reduction 
in Fortran through modules. The \kcode{declare reduction} directive 
is declared in a module (\ucode{data_red}). 
The reduction-identifier \ucode{.add.} is a user-defined operator that is
to allow accessibility in the scope that performs the reduction
operation.
The user-defined operator \ucode{.add.} and the subroutine \ucode{dt_init} 
specified in the \kcode{initializer} clause are defined in the same subprogram.

The reduction operation (that is, the \kcode{reduction} clause) is in the main program.
The reduction identifier \ucode{.add.} is accessible by use association.
Since \ucode{.add.} is a user-defined operator, the explicit interface
should also be accessible by use association in the current
program unit.
Since the \kcode{declare reduction} associated to this \kcode{reduction} clause
has the \kcode{initializer} clause, the subroutine specified on the clause
must be accessible in the current scoping unit.  In this case,
the subroutine \ucode{dt_init} is accessible by use association.

\ffreeexample[6.0]{udr}{4}


The following example uses user-defined reductions to declare a plus (\kcode{+}) 
reduction for a C++ class. As the \kcode{declare reduction} directive 
is inside the context of the \ucode{V} class the expressions in the 
\kcode{declare reduction} directive are resolved in the context of 
the class. Also, note that the \kcode{initializer} clause uses a copy 
constructor to initialize the private variables of the reduction and it uses 
as parameter to its original variable by using the special variable 
\kcode{omp_orig}.

\cppexample[6.0]{udr}{5}

The following examples shows how user-defined reductions can be defined for 
some STL containers. The first \kcode{declare reduction} defines the 
plus (\kcode{+}) operation for \ucode{std::vector<int>} by making use of the 
\ucode{std::transform} algorithm. The second and third define the merge (or 
concatenation) operation for \ucode{std::vector<int>} and \ucode{std::list<int>}. 
It shows how the user-defined reduction operation can be applied to specific 
data types of an STL.

\cppexample[6.0]{udr}{6}

