i am quite new to parallel processing. I have an example of calculating and storing elements of a 2D array in a sequential way. I wanted to convert this into a parallel program using MPI.

Following is the code for sequential program.

#include <stdio.h>
int x,y,xMax=10,yMax=10;
int main ()
{
  int arr[yMax][xMax];
  for(y =0; y<yMax;x++)
  {
      for (x=0;x<xMax;x++)
      {
         arr[y][x]=x+y;
         printf("%d",arr[y][x]);
      }
      printf("\n");
  }
}

I tried to convert this to an equivalent MPI program by parallelizing the outer for loop as follows: Here I want every process to calculate values for each array row and send the output array to root process which at the end will gather all the arrays and combine them into single 2D array.

#include <stdio.h>
#include <mpi.h>
int x,y,xMax=10,yMax=10,size,rank;
int main()
{
   int arr[xMax];
   int arrall[yMax][xMax];  
   MPI_Init(NULL,NULL);
   MPI_Comm_size(MPI_COMM_WORLD, &size);
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
   for(y =0+rank; y<yMax;y=y+size)
   {
      for (x=0;y<xMax;x++)
      {
         arr[y][x]=x+y;

      }
      MPI_Send(arr,xMax,MPI_INT,0,0,MPI_COMM_WORLD);
   }
  if(rank==0)
  {
  MPI_Gather(arr,xMax,MPI_INT,&arrall,xMax*yMax,MPI_INT,0,MPI_COMM_WORLD);
  }  
  MPI_Finalize();
}

But when i compile the program and wait quite a while for it but it still does not give any result. and it does not show the errors. I am trying on this for quite some time and searched for the any solution but unable to find. Any help will be much appreciated. Thanks

share|improve this question
up vote 0 down vote accepted

You are actually thinking too complicated. The collective operations in MPI take care of both the sending and receiving part. As mark writes, point to point messages such as MPI_Send will only match with point to point messages (e.g. MPI_Recv), and collectives only match with the same collective.

The whole communication is done with the a single call to MPI_Gather for all processes:

MPI_Gather(arr,xMax,MPI_INT,arrall,xMax,MPI_INT,0,MPI_COMM_WORLD);

Notice, that the recvcount is xMax, because it specifies the number of elements in every single receive.

Some more remarks:

  • You have to ensure that size == yMax
  • This only works because 2D arrays are layed out row-wise contiguously in memory. This does not work with pointer-"2D"-arrays.
  • In a real MPI program, you want to avoid gathering the whole working data on a single rank, as it presents a limit for scalability. Instead you should do everything distributed.

Edit: One specific way for more than one row per rank:

int rows_per_rank = yMax / size;
assert(rows_per_rank * size == yMax);
MPI_Gather(arr,xMax * rows_per_rank,MPI_INT,arrall,xMax * rows_per_rank,MPI_INT,0,MPI_COMM_WORLD);
share|improve this answer
    
thank you! what will be the size of output? will it be a 2D array ? – Max Jan 27 at 9:54
    
arrall will be filled with size * xMax elements. The "output" will match the data layout of the 2D array. – Zulan Jan 27 at 9:58
    
"You have to ensure that size == yMax" can you please help me to overcome this issue? I cannot give task to 1000 processes if yMax = 1000. Thanks – Max Jan 27 at 16:47
    
And I accepted your answer :) – Max Jan 27 at 16:49
    
If you want to have more than one row per rank, say rows_per_rank * rank == size, just replace the send/recv size parameters of MPI_Gather from xMax to xMax * rows_per_rank. – Zulan Jan 27 at 17:15

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.