333 lines
10 KiB
Groff
333 lines
10 KiB
Groff
.\" Man page generated from reStructuredText.
|
|
.
|
|
.TH "MPI_OP_CREATE" "3" "Feb 14, 2025" "" "Open MPI"
|
|
.
|
|
.nr rst2man-indent-level 0
|
|
.
|
|
.de1 rstReportMargin
|
|
\\$1 \\n[an-margin]
|
|
level \\n[rst2man-indent-level]
|
|
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|
-
|
|
\\n[rst2man-indent0]
|
|
\\n[rst2man-indent1]
|
|
\\n[rst2man-indent2]
|
|
..
|
|
.de1 INDENT
|
|
.\" .rstReportMargin pre:
|
|
. RS \\$1
|
|
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
|
. nr rst2man-indent-level +1
|
|
.\" .rstReportMargin post:
|
|
..
|
|
.de UNINDENT
|
|
. RE
|
|
.\" indent \\n[an-margin]
|
|
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|
.nr rst2man-indent-level -1
|
|
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
|
..
|
|
.sp
|
|
\fI\%MPI_Op_create\fP — Creates a user\-defined combination function handle.
|
|
.SH SYNTAX
|
|
.SS C Syntax
|
|
.INDENT 0.0
|
|
.INDENT 3.5
|
|
.sp
|
|
.nf
|
|
.ft C
|
|
#include <mpi.h>
|
|
|
|
int MPI_Op_create(MPI_User_function *function, int commute,
|
|
MPI_Op *op)
|
|
.ft P
|
|
.fi
|
|
.UNINDENT
|
|
.UNINDENT
|
|
.SS Fortran Syntax
|
|
.INDENT 0.0
|
|
.INDENT 3.5
|
|
.sp
|
|
.nf
|
|
.ft C
|
|
USE MPI
|
|
! or the older form: INCLUDE \(aqmpif.h\(aq
|
|
MPI_OP_CREATE(FUNCTION, COMMUTE, OP, IERROR)
|
|
EXTERNAL FUNCTION
|
|
LOGICAL COMMUTE
|
|
INTEGER OP, IERROR
|
|
.ft P
|
|
.fi
|
|
.UNINDENT
|
|
.UNINDENT
|
|
.SS Fortran 2008 Syntax
|
|
.INDENT 0.0
|
|
.INDENT 3.5
|
|
.sp
|
|
.nf
|
|
.ft C
|
|
USE mpi_f08
|
|
MPI_Op_create(user_fn, commute, op, ierror)
|
|
PROCEDURE(MPI_User_function) :: user_fn
|
|
LOGICAL, INTENT(IN) :: commute
|
|
TYPE(MPI_Op), INTENT(OUT) :: op
|
|
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
|
|
.ft P
|
|
.fi
|
|
.UNINDENT
|
|
.UNINDENT
|
|
.SH INPUT PARAMETERS
|
|
.INDENT 0.0
|
|
.IP \(bu 2
|
|
\fBfunction\fP: User\-defined function (function).
|
|
.IP \(bu 2
|
|
\fBcommute\fP: True if commutative; false otherwise.
|
|
.UNINDENT
|
|
.SH OUTPUT PARAMETERS
|
|
.INDENT 0.0
|
|
.IP \(bu 2
|
|
\fBop\fP: Operation (handle).
|
|
.IP \(bu 2
|
|
\fBierror\fP: Fortran only: Error status (integer).
|
|
.UNINDENT
|
|
.SH DESCRIPTION
|
|
.sp
|
|
\fI\%MPI_Op_create\fP binds a user\-defined global operation to an op handle that
|
|
can subsequently be used in \fI\%MPI_Reduce\fP, \fI\%MPI_Allreduce\fP,
|
|
\fI\%MPI_Reduce_scatter\fP, and \fI\%MPI_Scan\fP\&. The user\-defined operation is assumed
|
|
to be associative. If commute = true, then the operation should be both
|
|
commutative and associative. If commute = false, then the order of
|
|
operands is fixed and is defined to be in ascending, process rank order,
|
|
beginning with process zero. The order of evaluation can be changed,
|
|
taking advantage of the associativity of the operation. If commute =
|
|
true then the order of evaluation can be changed, taking advantage of
|
|
commutativity and associativity.
|
|
.sp
|
|
\fIfunction\fP is the user\-defined function, which must have the following
|
|
four arguments: invec, inoutvec, len, and datatype.
|
|
.sp
|
|
The ANSI\-C prototype for the function is the following:
|
|
.INDENT 0.0
|
|
.INDENT 3.5
|
|
.sp
|
|
.nf
|
|
.ft C
|
|
typedef void MPI_User_function(void *invec, void *inoutvec,
|
|
int *len,
|
|
MPI_Datatype *datatype);
|
|
.ft P
|
|
.fi
|
|
.UNINDENT
|
|
.UNINDENT
|
|
.sp
|
|
The Fortran declaration of the user\-defined function appears below.
|
|
.INDENT 0.0
|
|
.INDENT 3.5
|
|
.sp
|
|
.nf
|
|
.ft C
|
|
FUNCTION USER_FUNCTION( INVEC(*), INOUTVEC(*), LEN, TYPE)
|
|
<type> INVEC(LEN), INOUTVEC(LEN)
|
|
INTEGER LEN, TYPE
|
|
.ft P
|
|
.fi
|
|
.UNINDENT
|
|
.UNINDENT
|
|
.sp
|
|
The datatype argument is a handle to the data type that was passed into
|
|
the call to \fI\%MPI_Reduce\fP\&. The user reduce function should be written such
|
|
that the following holds: Let u[0], …, u[len\-1] be the len elements in
|
|
the communication buffer described by the arguments invec, len, and
|
|
datatype when the function is invoked; let v[0], …, v[len\-1] be len
|
|
elements in the communication buffer described by the arguments
|
|
inoutvec, len, and datatype when the function is invoked; let w[0], …,
|
|
w[len\-1] be len elements in the communication buffer described by the
|
|
arguments inoutvec, len, and datatype when the function returns; then
|
|
w[i] = u[i] o v[i], for i=0 ,…, len\-1, where o is the reduce operation
|
|
that the function computes.
|
|
.sp
|
|
Informally, we can think of invec and inoutvec as arrays of len elements
|
|
that function is combining. The result of the reduction over\-writes
|
|
values in inoutvec, hence the name. Each invocation of the function
|
|
results in the pointwise evaluation of the reduce operator on len
|
|
elements: i.e, the function returns in inoutvec[i] the value invec[i] o
|
|
inoutvec[i], for i = 0…, count\-1, where o is the combining operation
|
|
computed by the function.
|
|
.sp
|
|
By internally comparing the value of the datatype argument to known,
|
|
global handles, it is possible to overload the use of a single
|
|
user\-defined function for several different data types.
|
|
.sp
|
|
General datatypes may be passed to the user function. However, use of
|
|
datatypes that are not contiguous is likely to lead to inefficiencies.
|
|
.sp
|
|
No MPI communication function may be called inside the user function.
|
|
\fI\%MPI_Abort\fP may be called inside the function in case of an error.
|
|
.SH NOTES
|
|
.sp
|
|
Suppose one defines a library of user\-defined reduce functions that are
|
|
overloaded: The datatype argument is used to select the right execution
|
|
path at each invocation, according to the types of the operands. The
|
|
user\-defined reduce function cannot “decode” the datatype argument that
|
|
it is passed, and cannot identify, by itself, the correspondence between
|
|
the datatype handles and the datatype they represent. This
|
|
correspondence was established when the datatypes were created. Before
|
|
the library is used, a library initialization preamble must be executed.
|
|
This preamble code will define the datatypes that are used by the
|
|
library and store handles to these datatypes in global, static variables
|
|
that are shared by the user code and the library code.
|
|
.sp
|
|
\fBExample:\fP Example of user\-defined reduce:
|
|
.sp
|
|
Compute the product of an array of complex numbers, in C.
|
|
.INDENT 0.0
|
|
.INDENT 3.5
|
|
.sp
|
|
.nf
|
|
.ft C
|
|
typedef struct {
|
|
double real,imag;
|
|
} Complex;
|
|
|
|
/* the user\-defined function
|
|
*/
|
|
void myProd( Complex *in, Complex *inout, int *len,
|
|
MPI_Datatype *dptr )
|
|
{
|
|
int i;
|
|
Complex c;
|
|
|
|
for (i=0; i< *len; ++i) {
|
|
c.real = inout\->real*in\->real \-
|
|
inout\->imag*in\->imag;
|
|
c.imag = inout\->real*in\->imag +
|
|
inout\->imag*in\->real;
|
|
*inout = c;
|
|
in++; inout++;
|
|
}
|
|
}
|
|
|
|
/* and, to call it...
|
|
*/
|
|
\&...
|
|
|
|
/* each process has an array of 100 Complexes
|
|
*/
|
|
Complex a[100], answer[100];
|
|
MPI_Op myOp;
|
|
MPI_Datatype ctype;
|
|
|
|
/* explain to MPI how type Complex is defined
|
|
*/
|
|
MPI_Type_contiguous( 2, MPI_DOUBLE, &ctype );
|
|
MPI_Type_commit( &ctype );
|
|
/* create the complex\-product user\-op
|
|
*/
|
|
MPI_Op_create( myProd, True, &myOp );
|
|
|
|
MPI_Reduce( a, answer, 100, ctype, myOp, root, comm );
|
|
|
|
/* At this point, the answer, which consists of 100 Complexes,
|
|
* resides on process root
|
|
*/
|
|
.ft P
|
|
.fi
|
|
.UNINDENT
|
|
.UNINDENT
|
|
.sp
|
|
The Fortran version of \fI\%MPI_Reduce\fP will invoke a user\-defined reduce
|
|
function using the Fortran calling conventions and will pass a
|
|
Fortran\-type datatype argument; the C version will use C calling
|
|
convention and the C representation of a datatype handle. Users who plan
|
|
to mix languages should define their reduction functions accordingly.
|
|
.SH NOTES ON COLLECTIVE OPERATIONS
|
|
.sp
|
|
The reduction functions ( MPI_Op ) do not return an error value. As a
|
|
result, if the functions detect an error, all they can do is either call
|
|
\fI\%MPI_Abort\fP or silently skip the problem. Thus, if you change the error
|
|
handler from MPI_ERRORS_ARE_FATAL to something else, for example,
|
|
MPI_ERRORS_RETURN , then no error may be indicated.
|
|
.sp
|
|
The reason for this is the performance problems in ensuring that all
|
|
collective routines return the same error value.
|
|
.SH ERRORS
|
|
.sp
|
|
Almost all MPI routines return an error value; C routines as the return result
|
|
of the function and Fortran routines in the last argument.
|
|
.sp
|
|
Before the error value is returned, the current MPI error handler associated
|
|
with the communication object (e.g., communicator, window, file) is called.
|
|
If no communication object is associated with the MPI call, then the call is
|
|
considered attached to MPI_COMM_SELF and will call the associated MPI error
|
|
handler. When MPI_COMM_SELF is not initialized (i.e., before
|
|
\fI\%MPI_Init\fP/\fI\%MPI_Init_thread\fP, after \fI\%MPI_Finalize\fP, or when using the Sessions
|
|
Model exclusively) the error raises the initial error handler. The initial
|
|
error handler can be changed by calling \fI\%MPI_Comm_set_errhandler\fP on
|
|
MPI_COMM_SELF when using the World model, or the mpi_initial_errhandler CLI
|
|
argument to mpiexec or info key to \fI\%MPI_Comm_spawn\fP/\fI\%MPI_Comm_spawn_multiple\fP\&.
|
|
If no other appropriate error handler has been set, then the MPI_ERRORS_RETURN
|
|
error handler is called for MPI I/O functions and the MPI_ERRORS_ABORT error
|
|
handler is called for all other MPI functions.
|
|
.sp
|
|
Open MPI includes three predefined error handlers that can be used:
|
|
.INDENT 0.0
|
|
.IP \(bu 2
|
|
\fBMPI_ERRORS_ARE_FATAL\fP
|
|
Causes the program to abort all connected MPI processes.
|
|
.IP \(bu 2
|
|
\fBMPI_ERRORS_ABORT\fP
|
|
An error handler that can be invoked on a communicator,
|
|
window, file, or session. When called on a communicator, it
|
|
acts as if \fI\%MPI_Abort\fP was called on that communicator. If
|
|
called on a window or file, acts as if \fI\%MPI_Abort\fP was called
|
|
on a communicator containing the group of processes in the
|
|
corresponding window or file. If called on a session,
|
|
aborts only the local process.
|
|
.IP \(bu 2
|
|
\fBMPI_ERRORS_RETURN\fP
|
|
Returns an error code to the application.
|
|
.UNINDENT
|
|
.sp
|
|
MPI applications can also implement their own error handlers by calling:
|
|
.INDENT 0.0
|
|
.IP \(bu 2
|
|
\fI\%MPI_Comm_create_errhandler\fP then \fI\%MPI_Comm_set_errhandler\fP
|
|
.IP \(bu 2
|
|
\fI\%MPI_File_create_errhandler\fP then \fI\%MPI_File_set_errhandler\fP
|
|
.IP \(bu 2
|
|
\fI\%MPI_Session_create_errhandler\fP then \fI\%MPI_Session_set_errhandler\fP or at \fI\%MPI_Session_init\fP
|
|
.IP \(bu 2
|
|
\fI\%MPI_Win_create_errhandler\fP then \fI\%MPI_Win_set_errhandler\fP
|
|
.UNINDENT
|
|
.sp
|
|
Note that MPI does not guarantee that an MPI program can continue past
|
|
an error.
|
|
.sp
|
|
See the \fI\%MPI man page\fP for a full list of \fI\%MPI error codes\fP\&.
|
|
.sp
|
|
See the Error Handling section of the MPI\-3.1 standard for
|
|
more information.
|
|
.sp
|
|
\fBSEE ALSO:\fP
|
|
.INDENT 0.0
|
|
.INDENT 3.5
|
|
.INDENT 0.0
|
|
.IP \(bu 2
|
|
\fI\%MPI_Reduce\fP
|
|
.IP \(bu 2
|
|
\fI\%MPI_Reduce_scatter\fP
|
|
.IP \(bu 2
|
|
\fI\%MPI_Allreduce\fP
|
|
.IP \(bu 2
|
|
\fI\%MPI_Scan\fP
|
|
.IP \(bu 2
|
|
\fI\%MPI_Op_free\fP
|
|
.UNINDENT
|
|
.UNINDENT
|
|
.UNINDENT
|
|
.SH COPYRIGHT
|
|
2003-2025, The Open MPI Community
|
|
.\" Generated by docutils manpage writer.
|
|
.
|