Reputation: 341
I would like to use a shared array in an MPI program such that after one process finishes its work, it will put its rank into that array and "update" it by sending it to others without waiting. I tried MPI_Bcast by giving it as "root" parameter the rank of the running process (instead of 0), but when I display the array from each process, it only shows that changes occurred locally (other ranks sent are not in the array).
int array[10];
array[rank] = rank;
MPI_Bcast(array,10,MPI_INT,rank,MPI_COMM_WORLD);
printf("%d, %d - ",array[0],array[1]); //displays: 0, 26872 - 32678, 1
Thanks for helping.
Upvotes: 2
Views: 2914
Reputation: 9817
Typing int array[10];
in the main of a MPI program does not generate a shared array. Each process handle its own version of the array. MPI_Bcast()
has been designed as a way for a given process root
to broadcast its version of the array to all other processes. Thus, the initial version of the array on all other processes is erased.
MPI_Bcast()
is a collective operation: every processes of the communicator must call MPI_Bcast()
using the same root
. The count and type can be different, but the amount of data sent by the root must be equal to the amount received by all processes.
Two options to solve your problem:
MPI_Allgather()
. See these schemes: MPI_Allgather()
can be used to synchronize a global array after modifications by local process. The global array is not "shared", because each process uses a different space in memory, but values of different processes will be similar after a call to MPI_Allgather()
.You are looking for a real shared array.Such an array can be allocated by calling MPI_Win_allocate_shared()
. See the version 3.1 of the MPI standard, paragraph 11.2.3 Window That Allocates Shared Memory on page 407. In particular, attention must be paid to the following warning if you are running programs using multiple nodes of a cluster:
It is the user’s responsibility to ensure that the communicator comm represents a group of processes that can create a shared memory segment that can be accessed by all processes in the group.
You can find and an example of MPI_Win_allocate_shared()
there
In the following example, I will assume that you are interrested in the first option. It is compiled by mpicc main.c -o main
and ran by mpirun -np 42 main
.
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char *argv[])
{
int size, rank;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
int* array=malloc(size*sizeof(int));
if(array==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
//modifying the local portion of the array
array[rank]=rank;
//gather content from each process and broadcast it to all processes
MPI_Allgather(&array[rank],1,MPI_INT,array,1,MPI_INT,MPI_COMM_WORLD);
//each process has its own copy of the array, but the values are the same.
int i,j;
for(i=0;i<size;i++){
if(i==rank){
printf("rank %d got ",rank);
for(j=0;j<size;j++){
printf("%d ",array[j]);
}
printf("\n");
}
MPI_Barrier(MPI_COMM_WORLD);
}
free(array);
MPI_Finalize();
return 0;
}
Upvotes: 3