Collective Communication I

2.3.2 Gather and Scatter

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:

 Gather1

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);

 Image1

    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

 Gather2

MPI_SCATTER
Gather3