Operations and Example
Examples of MPI predefined operations that can be used in calls to MPI_Reduce (or a variant) and MPI_Scan are summarized below.
Name | Meaning | C type | Fortran type |
---|---|---|---|
MPI_MAX | maximum | integer, float | integer, real, complex |
MPI_MIN | minimum | integer, float | integer, real, complex |
MPI_SUM | sum | integer, float | integer, real, complex |
MPI_PROD | product | integer, float | integer, real, complex |
MPI_LAND | logical and | integer | logical |
MPI_BAND | bit-wise and | integer, MPI_BYTE | integer, MPI_BYTE |
MPI_LOR | logical or | integer | logical |
MPI_BOR | bit-wise or | integer, MPI_BYTE | integer, MPI_BYTE |
MPI_LXOR | logical xor | integer | logical |
MPI_BXOR | bit-wise xor | integer, MPI_BYTE | integer, MPI_BYTE |
MPI_MAXLOC | max value and location | combination of int, float, double, and long double | combination of integer, real, complex, double precision |
MPI_MINLOC | min value and location | combination of int, float, double, and long double | combination of integer, real, complex, double precision |
Example: MPI_MAX
Each process in a forest dynamics simulation calculates the maximum tree height for its region. Process 0, which is writing output, wants to know the maximum tree height across all the regions.
/* Sketch of using MPI_Reduce */
int maxht, globmx;
.
.
. (calculations that determine maximum height)
.
MPI_Reduce(maxht, globmx, 1, MPI_INTEGER,
MPI_MAX, 0, MPI_COMM_WORLD, ierr);
if(taskid==0)
{
.
. (write output)
.
}
! Sketch of using MPI_REDUCE
INTEGER maxht, globmx
.
.
. (calculations that determine maximum height)
.
.
call MPI_REDUCE (maxht, globmx, 1, MPI_INTEGER, &
MPI_MAX, 0, MPI_COMM_WORLD, ierr)
IF (taskid.eq.0) then
.
. (Write output)
.
END IF
User-defined Operations
You can define your own reduce operation by making use of the MPI_Op_create function. This operation must be associative, but it does not need to be commutative. This is in contrast to all the MPI predefined functions, which are commutative as well as associative. MPI implementations may be able to take advantage of the commutativity in order to make the reduction more efficient. For this reason, one parameter of MPI_Op_create specifies whether or not the operation is commutative.
int MPI_Op_create(MPI_User_function *function, int commute, MPI_Op *op)
MPI_OP_CREATE(function, commute, op, ierror)
MPI_Op_create parameters:
function
- the name of the function that defines the operation
commute
- true/false depending on whether the operation is commutative
op
- is the handle to the user-defined operation that generates the output
Of course, there is the question of the form of the function being used, and you may have noticed that C requires a function of type MPI_User_function:
typedef void MPI_User_function(void* invec, void* inoutvec,
int *len, MPI_Datatype *datatype);
The Fortran declaration for the user function is similarly defined:
After all calls to the user-defined operation have completed, the operation handle can be released by a call to MPI_Op_free.