Gather Purpose:
If an array is scattered across all processes in the group and one wants to collect each piece of the array into a specified array in the order of process rank, the call to use is GATHER.
Scatter Purpose:
On the other hand, if one wants to distribute the data into n equal segments, where the ith segment is sent to the ith process in the group which has n processes, use SCATTER.
MPI provides two variants of the gather/scatter operations: one in which the numbers of data items collected from/sent to nodes can be different; and a more efficient one in the special case where the number per node is the same. Their syntax is given below:
C
| int MPI_Gather |
(void* sbuf, int scount, MPI_Datatype stype, void* rbuf, int rcount, MPI_Datatype rtype, int root, MPI_Comm comm ) |
| int MPI_Scatter |
(void* sbuf, int scount, MPI_Datatype stype, void* rbuf, int rcount, MPI_Datatype rtype, int root, MPI_Comm comm) |
FORTRAN
| MPI_GATHER |
(sbuf, scount, stype, rbuf, rcount, rtype, root, comm, ierr) |
| MPI_SCATTER |
(sbuf, scount, stype, rbuf, rcount, rtype, root, comm, ierr) |
where, for the Gather routines:
| sbuf |
is the starting address of send buffer, |
| scount |
is the number of elements in the send buffer, |
| stype |
is the data type of send buffer elements, |
| rbuf |
is the starting address of the receive buffer, |
| rcount |
is the number of elements for any single receive, |
| rtype |
is the data type of the receive buffer elements, |
| root |
is the rank of receiving process, and |
| comm |
is the communicator. |
Note: rbuf, rcount, rtype are significant for root process only
and for the Scatter routines:
| sbuf |
is the address of the send buffer, |
| scount |
is the number of elements sent to each process, |
| stype |
is the data type of the send buffer elements, |
| rbuf |
is the address of the receive buffer, |
| rcount |
is the number of elements in the receive buffer, |
| rtype |
is the data type of the receive buffer elements, |
| root |
is the rank of the sending process, and |
| comm |
is the communicator. |
Note: sbuf, scount, and stype are significant for root process only
In the gather operation, each process (root process included) sends scount elements of type stype of sbuf to the root process. The root process receives the messages and stores them in rank order in the rbuf. For scatter, the reverse holds. The root process sends a buffer of N chunks of data (N = number of processes in the group) so that process 1 gets the first element, process 2 gets the second element, etc.
Gather & Scatter Effect
In order to illustrate these functions, we give a graph below:
This picture is augmented by the following example for gather.
- Matrix-vector multiplication of matrix distributed by rows
- Output vector needed in entirety by one process
Sample Code
The problem associated with the following sample code is the multiplication of a matrix A, size 100x100, by a vector B of length 100. Since this example uses 4 tasks, each task will work on its own chunk of 25 rows of A. B is the same for each task. The vector C will have 25 elements calculated by each task, stored in cpart. The MPI_Gather routine will retrieve cpart from each task and store the result in ctotal, which is the complete vector C.
DIMENSION A(25,100), b(100), cpart(25), ctotal(100)
INTEGER root
DATA root/0/
DO I=1,25
cpart(I) = 0.
DO K=1,100
cpart(I) = cpart(I) + A(I,K)*b(K)
END DO
END DO
call MPI_GATHER(cpart,25,MPI_REAL,ctotal,25,MPI_REAL,
root, MPI_COMM_WORLD, ierr)
or
double a[100,25],b[100],cpart[25],ctotal[100];
int root;
root=0;
for(i=0;i<25;i++)
{
cpart[i]=0;
for(k=0;k<100;k++)
{
cpart[i]=cpart[i]+a[k,i]*b[k];
}
}
MPI_Gather(cpart,25,MPI_REAL,ctotal,25,MPI_REAL,root,MPI_COMM_WORLD);
A: matrix distributed by rows
b: vector shared by all processes
c: vector updated by each process independently
Here we give two Fortran program fragments to further show the use of MPI_GATHER and MPI_SCATTER.
MPI_GATHER
MPI_SCATTER