!----------------------------------------------------------------------------
PROGRAM Scatter_Gather
!----------------------------------------------------------------------------
! Scatter: an array is distributed in sections from one process to all others
! Gather : a distributed array is reassembled in one process 
! 
! REMARK: this program should be executed with a number of processors 
!   which is power of 2

INCLUDE "mpif.h"
INTEGER, PARAMETER:: N=16
INTEGER:: err, nproc, myid
INTEGER root, i, m
INTEGER:: a(N), b(N)

CALL MPI_INIT(err)
CALL MPI_COMM_SIZE (MPI_COMM_WORLD, nproc, err)
CALL MPI_COMM_RANK (MPI_COMM_WORLD, myid, err)

root = 0
m = N/nproc

IF (myid==root)  a = (/ (i, i=1,N) /)

! m elements of a are distributed to the other processes
CALL MPI_SCATTER (a, m, MPI_INTEGER,   & ! source elements
                  b, m, MPI_INTEGER,   & ! destination elements
               root, MPI_COMM_WORLD, err)! source node, comunic.
                         ! NOTE  m: num. of elems PER PROCESS

! parallel function evaluation
b(1:m) = 2*b(1:m)   ! only the array section stored in the proc.!

! assembling the results in root
CALL MPI_GATHER (b, m, MPI_INTEGER,   & ! source elements
                 a, m, MPI_INTEGER,   & ! destination elements 
              root, MPI_COMM_WORLD, err)! destination node, comunic.

IF (myid==root)  WRITE(*,"('Result:'/(20I3))") a

CALL MPI_FINALIZE(err)
END PROGRAM Scatter_Gather
