There are 4 processes and one of them (0
) is the master which has to build the matrix C
as follow
-1 0 0 -1 0
0 -1 0 0 -1
-1 1 1 -1 1
1 -1 1 1 -1
-1 2 2 -1 2
2 -1 2 2 -1
-1 3 3 -1 3
3 -1 3 3 -1
To do so, the matrix is declared as REAL, DIMENSION(:,:), ALLOCATABLE :: C
and allocated with
IF (myid == 0) THEN
ALLOCATE(C(2*nprocs,-2:+2))
END IF
where nprocs
is the number of processes. Process 0 also sets C = -1
. For the communications I first tried with
CALL MPI_GATHER((/0.0+myid,0.0+myid/),&
& 2,MPI_REAL,&
& C(:,0),&
& 2,MPI_REAL,&
& 0,MPI_COMM_WORLD,ieri)
to fill up the central column, and this worked. Then I tried with
CALL MPI_GATHER((/myid, myid, myid, myid/),&
& 4,MPI_REAL,&
& (/C(1:2*nprocs:2,-1),C(2:2*nprocs:2,-2),C(1:2*nprocs:2,+2),C(2:2*nprocs:2,+1)/),&
& 4,MPI_REAL,&
& 0,MPI_COMM_WORLD,ierr)
to fill the other columns, but it didn't work, giving errors like the following
Fortran runtime error: Index '1' of dimension 1 of array 'c' outside of expected range (140735073734712:140735073734712).
To understand why, I tried to fill the first column alone with the call
CALL MPI_GATHER((/0.0-myid/),&
& 1,MPI_REAL,&
& C(1:2*nprocs:2,-2),&
& 1,MPI_REAL,&
& 0,MPI_COMM_WORLD,ierr)
but the same happened, more or less.
I solved the problem by allocating C
for all the processes (i.e. regardless of the process id). Why does this make the call work?
After this I did a little change (before trying again to fill all the columns at once) simply putting the receive buffer in (/.../)
CALL MPI_GATHER((/0.0-myid/),&
& 1,MPI_REAL,&
& (/C(1:2*nprocs:2,-2)/),&
& 1,MPI_REAL,&
& 0,MPI_COMM_WORLD,ieri)
but this makes the call ineffective (no errors, but not even one element in C
changed).
Hope someone can explain to me
- what's wrong with the constructor
(/.../)
in the receive buffer? - why the receive buffer has to be allocated in the non-root processes?
- it is necessary to use
mpi_gatherv
to accomplish the task? - is there a better way to build up such a matrix?
EDIT Is it possible to use MPI derived data types to build the matrix?