MPI_NEIGHBOR_ALLTOALL_INIT(3)
π MPI_NEIGHBOR_ALLTOALL_INIT π
okay bestie, gather round, because this is the Open MPI manual page for MPI_NEIGHBOR_ALLTOALL_INIT(3) and honestly? it's giving "everybody talks to everybody, but make it topology". π¦
β¨ NAME β¨
MPI_Neighbor_alltoall, MPI_Ineighbor_alltoall, MPI_Neighbor_alltoall β all processes send data to neighboring processes in a virtual topology communicator</p> π
(yes bestie, MPI_Neighbor_alltoall really does show up twice in that list. that's not me being messy, that's literally what the page says. steady. π«Ά)
πΈ SYNTAX πΈ
π C Syntax
#include <mpi.h>
int MPI_Neighbor_alltoall(const void *sendbuf, int sendcount,
MPI_Datatype sendtype, void *recvbuf, int recvcount,
MPI_Datatype recvtype, MPI_Comm comm)
int MPI_Ineighbor_alltoall(const void *sendbuf, int sendcount,
MPI_Datatype sendtype, void *recvbuf, int recvcount,
MPI_Datatype recvtype, MPI_Comm comm, MPI_Request *request)
int MPI_Neighbor_alltoall_init(const void *sendbuf, int sendcount,
MPI_Datatype sendtype, void *recvbuf, int recvcount,
MPI_Datatype recvtype, MPI_Comm comm, MPI_Info info, MPI_Request *request)
π Fortran Syntax
USE MPI
! or the older form: INCLUDE 'mpif.h'
MPI_NEIGHBOR_ALLTOALL(SENDBUF, SENDCOUNT, SENDTYPE, RECVBUF, RECVCOUNT,
RECVTYPE, COMM, IERROR)
<type> SENDBUF(*), RECVBUF(*)
INTEGER SENDCOUNT, SENDTYPE, RECVCOUNT, RECVTYPE
INTEGER COMM, IERROR
MPI_INEIGHBOR_ALLTOALL(SENDBUF, SENDCOUNT, SENDTYPE, RECVBUF, RECVCOUNT,
RECVTYPE, COMM, REQUEST, IERROR)
<type> SENDBUF(*), RECVBUF(*)
INTEGER SENDCOUNT, SENDTYPE, RECVCOUNT, RECVTYPE
INTEGER COMM, REQUEST, IERROR
MPI_NEIGHBOR_ALLTOALL_INIT(SENDBUF, SENDCOUNT, SENDTYPE, RECVBUF, RECVCOUNT,
RECVTYPE, COMM, INFO, REQUEST, IERROR)
<type> SENDBUF(*), RECVBUF(*)
INTEGER SENDCOUNT, SENDTYPE, RECVCOUNT, RECVTYPE
INTEGER COMM, INFO, REQUEST, IERROR
π¦ Fortran 2008 Syntax
USE mpi_f08
MPI_Neighbor_alltoall(sendbuf, sendcount, sendtype, recvbuf, recvcount,
recvtype, comm, ierror)
TYPE(*), DIMENSION(..), INTENT(IN) :: sendbuf
TYPE(*), DIMENSION(..) :: recvbuf
INTEGER, INTENT(IN) :: sendcount, recvcount
TYPE(MPI_Datatype), INTENT(IN) :: sendtype, recvtype
TYPE(MPI_Comm), INTENT(IN) :: comm
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
MPI_Ineighbor_alltoall(sendbuf, sendcount, sendtype, recvbuf, recvcount,
recvtype, comm, request, ierror)
TYPE(*), DIMENSION(..), INTENT(IN), ASYNCHRONOUS :: sendbuf
TYPE(*), DIMENSION(..), ASYNCHRONOUS :: recvbuf
INTEGER, INTENT(IN) :: sendcount, recvcount
TYPE(MPI_Datatype), INTENT(IN) :: sendtype, recvtype
TYPE(MPI_Comm), INTENT(IN) :: comm
TYPE(MPI_Request), INTENT(OUT) :: request
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
MPI_Neighbor_alltoall_init(sendbuf, sendcount, sendtype, recvbuf, recvcount,
recvtype, comm, info, request, ierror)
TYPE(*), DIMENSION(..), INTENT(IN), ASYNCHRONOUS :: sendbuf
TYPE(*), DIMENSION(..), ASYNCHRONOUS :: recvbuf
INTEGER, INTENT(IN) :: sendcount, recvcount
TYPE(MPI_Datatype), INTENT(IN) :: sendtype, recvtype
TYPE(MPI_Comm), INTENT(IN) :: comm
TYPE(MPI_Info), INTENT(IN) :: info
TYPE(MPI_Request), INTENT(OUT) :: request
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
π§ INPUT PARAMETERS π§
sendbufβ starting address of send buffer (choice). it's where your outgoing lil data go πsendcountβ number of elements to send to each process (integer).sendtypeβ datatype of send buffer elements (handle).recvcountβ number of elements to receive from each process (integer).recvtypeβ datatype of receive buffer elements (handle).commβ communicator over which data is to be exchanged (handle). the group chat, basically π¬infoβ Info (handle, persistent only). this one only shows up for the persistent girlies.
π OUTPUT PARAMETERS π
recvbufβ starting address of receive buffer (choice). incoming mail slot π¬requestβ Request (handle, non-blocking only).ierrorβ Fortran only: error status (integer).
π DESCRIPTION π
okay so MPI_Neighbor_alltoall is a collective operation where every process sends and receives the same amount of data to each neighbor. the way this routine actually works, bestie, is that each process performs 2n independent point-to-point communications (where n is the number of neighbors in communicator comm). the neighbors and the buffer layout? all determined by the topology of comm. π
Example of MPI_Neighbor_alltoall semantics for cartesian topologies:
MPI_Cart_get(comm, maxdims, dims, periods, coords);
for (dim = 0, i = 0 ; dim < dims ; ++dim) {
MPI_Cart_shift(comm, dim, 1, &r0, &r1);
MPI_Isend(sendbuf + i * sendcount * extent(sendtype),
sendcount, sendtype, r0, ..., comm, ...);
MPI_Irecv(recvbuf + i * recvcount * extent(recvtype),
recvcount, recvtype, r0, ..., comm, ...);
++i;
MPI_Isend(sendbuf + i * sendcount * extent(sendtype),
sendcount, sendtype, r1, ..., comm, &req[i]);
MPI_Irecv(recvbuf + i * recvcount * extent(recvtype),
recvcount, recvtype, r1, ..., comm, ...);
++i;
}
MPI_Waitall (...);
so each process breaks its local sendbuf up into n blocks β every one of them holding sendcount elements of type sendtype β and splits its recvbuf the same way, according to recvcount and recvtype. Process j sends the k-th block of its local sendbuf to neighbor k, and neighbor k drops that data into the j-th block of its local recvbuf. π₯
the amount of data sent must be equal to the amount of data received, pairwise, between every pair of processes. no cap, that's the rule. π
π¦ NEIGHBOR ORDERING π¦
okay this part is lowkey the most important bit so pay attention bestie π
- for a distributed graph topology, created with
MPI_Dist_graph_create, the sequence of neighbors in the send and receive buffers at each process is defined as the sequence returned byMPI_Dist_graph_neighborsfor destinations and sources, respectively. - for a general graph topology, created with
MPI_Graph_create, the order of neighbors in the send and receive buffers is defined as the sequence of neighbors as returned byMPI_Graph_neighbors. - > heads up: general graph topologies should generally be replaced by the distributed graph topologies. it's giving β¨ upgrade era β¨
- for a Cartesian topology, created with
MPI_Cart_create, the sequence of neighbors in the send and receive buffers at each process is defined by order of the dimensions β first the neighbor in the negative direction and then in the positive direction with displacement1. π§ - the numbers of sources and destinations in the communication routines are
2*ndims, withndimsdefined inMPI_Cart_create. - if a neighbor does not exist β like, at the border of a Cartesian topology in the case of a non-periodic virtual grid dimension (i.e.,
periods[β¦]==false) β then this neighbor is defined to beMPI_PROC_NULL.
and if a neighbor in any of the functions is MPI_PROC_NULL, then the neighborhood collective communication behaves like a point-to-point communication with MPI_PROC_NULL in this direction. that is: the buffer is still part of the sequence of neighbors, but it is neither communicated nor updated. it's there, it's just not doing anything. main character energy, honestly. π
π NOTES π
- the
MPI_IN_PLACEoption forsendbufis not meaningful for this function. - all arguments on all processes are significant. the
commargument, in particular, must describe the same communicator on all processes. andcommmust be either a cartesian, graph, or dist graph communicator. - there are two MPI library functions that are more general than
MPI_Neighbor_alltoall:MPI_Neighbor_alltoallvlets you do all-to-all communication to and from buffers that need not be contiguous β different processes may send and receive different amounts of data. π«ΆMPI_Neighbor_alltoallwexpandsMPI_Neighbor_alltoallv's functionality to allow the exchange of data with different datatypes. π
β still with me? good. more coming. β
π ERRORS π
okay bestie, error time, don't freak out π
Almost all MPI routines hand back an error value β and yeah, that means basically all of them. In C it's the return result of the function, and in Fortran it shows up in the last argument. that's just how she is π
Before that error value ever gets returned to you, the current MPI error handler associated with the communication object gets called β think communicator, window, file, the whole squad. β¨
If there's no communication object associated with the MPI call, then that call is considered attached to MPI_COMM_SELF and it will call the associated MPI error handler. self-attached, main character energy, we love to see it π
And when MPI_COMM_SELF is not initialized β i.e., before MPI_Init / MPI_Init_thread, after MPI_Finalize, or when you're using the Sessions Model exclusively β the error raises the initial error handler. π
Good news tho: the initial error handler can be changed! Call MPI_Comm_set_errhandler on MPI_COMM_SELF when you're using the World model, or use the mpi_initial_errhandler CLI argument to mpiexec, or the info key to MPI_Comm_spawn / MPI_Comm_spawn_multiple. custom error handling? slay π
And if no other appropriate error handler has been set, then the MPI_ERRORS_RETURN error handler is called for MPI I/O functions, while the MPI_ERRORS_ABORT error handler is called for all other MPI functions. no cap β
Open MPI includes three predefined error handlers that you can use, and they are iconic:
MPI_ERRORS_ARE_FATALβ causes the program to abort all connected MPI processes. yeah. everyone. all of them. πMPI_ERRORS_ABORTβ an error handler that can be invoked on a communicator, window, file, or session. When it's called on a communicator, it acts as ifMPI_Abortwas called on that communicator. If it's called on a window or file, it acts as ifMPI_Abortwas called on a communicator containing the group of processes in the corresponding window or file. And if it's called on a session, it aborts only the local process. nuanced π«ΆMPI_ERRORS_RETURNβ returns an error code to the application. simple. clean. hands it right back β¨
MPI applications can also implement their own error handlers by calling:
MPI_Comm_create_errhandlerthenMPI_Comm_set_errhandlerMPI_File_create_errhandlerthenMPI_File_set_errhandlerMPI_Session_create_errhandlerthenMPI_Session_set_errhandleror atMPI_Session_initMPI_Win_create_errhandlerthenMPI_Win_set_errhandler
β οΈ note that MPI does not guarantee that an MPI program can continue past an error. likeβ¦ it might not. don't bank on it bestie π
See the MPI man page for a full list of MPI error codes. And see the Error Handling section of the MPI-3.1 standard for more information. iykyk π
See also:
MPI_Neighbor_alltoallvMPI_Neighbor_alltoallwMPI_Cart_createMPI_Graph_createMPI_Dist_graph_createMPI_Dist_graph_create_adjacent
π COPYRIGHT π
2003-2026, The Open MPI Community
and that's the whole page, bestie!! π¦π this one came from the Open MPI community, dated Sep 10, 2026, and it lives in the manual as MPI_NEIGHBOR_ALLTOALL_INIT(3). go forth and neighbor-alltoall-init responsibly, you're gonna do amazing π₯°πΈβ¨
π¦ where this page comes from
- ubuntu stonking: openmpi-doc 5.0.10-6 Β· other
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms