0
votes

I'm beginner in MPI coding, I tried to pass message using simple two dimensional array, dividing process in two process elements...but code get stucks in message passing...the code is as follows...I'd edited as sending and receiving order

#include<stdio.h>
#include<mpi.h>

double a[15][15];

int main(int argc, char **argv)
{
    int process_id,nprocess;
    int i,j;
    int Nxl=5,Nx=10,Ny=10;
    MPI_Status status;
    MPI_Datatype line;
    MPI_Init(&argc,&argv);
    MPI_Comm_size(MPI_COMM_WORLD,&nprocess);
    MPI_Comm_rank(MPI_COMM_WORLD,&process_id);
    //Nxl=((Nx-2)/nprocess)+2;
    //printf("NXL=%d\n",Nxl);
    //  printf("process_id=%d\n",process_id);
    if(process_id==0)
    {
        for(i=1;i<=5;i++)
        {
            for(j=1;j<=Ny;j++)
            {
                a[i][j]=3*2*i;
                MPI_Send(&a[Nxl-1][j],1,MPI_DOUBLE,0,1,MPI_COMM_WORLD);
            }
        }
        for(i=1;i<=5;i++)
        {
            for(j=1;j<=Ny;j++)
            {
                printf("matrices=%f\n",a[i][j]);
                MPI_Recv(&a[1][j],1,MPI_DOUBLE,1,1,MPI_COMM_WORLD,&status);
                printf("PROCESS_ID=%d\n",process_id);
            }
        }
    }
    if(process_id==1)
    {
        for(i=6;i<=10;i++)
        {
            for(j=1;j<Ny;j++)
            {
                a[i][j]=4*2;
                MPI_Send(&a[2][j],1,MPI_DOUBLE,1,2,MPI_COMM_WORLD);
            }
        }
        for(i=6;i<=10;i++)
        {
            for(j=1;j<Ny;j++)
            {
                MPI_Recv(&a[Nxl][j],1,MPI_DOUBLE,0,1,MPI_COMM_WORLD,&status);
                printf("PROCESS_ID=%d\n",process_id);
            }
        }
    }
    MPI_Finalize();
}
2
MPI_Sendrecv is your best friend in that case.Hristo Iliev

2 Answers

2
votes

You are making both participants in the conversation speak, then listen. You need to make it so one speaks and the other listens, followed by the opposite.

1
votes

(I'm going to write this answer as if you have more than two process to be more general for posterity, but you can reinterpret it to mean just two.)

Hristo and John are right. The problem is that all of your processes are sending a message before anyone receives it. This means that the sends may never return. Somehow you need to make sure that the receives are also available. You can do this in one of two ways:

Convert blocking calls to non-blocking

If you convert your blocking (MPI_SEND/MPI_RECV) calls to non-blocking calls and add an MPI_WAITALL at the end of your code, that would allow all of the processes to simultaneously send and receive the messages. Then after the waitall, you can do whatever you want to do with the data that you've received.

Convert MPI_SEND/MPI_RECV to MPI_SENDRECV

This option has essentially the same result in that you will do the sends and receives simultaneously, but you still need to be careful to ensure that everyone is entering exchanges with the same processes. For instance, if you had everyone trying to do a communication in a ring, you'd need to make sure that they all send to the right and receive from the left (or vice versa) rather than do both the send and receive to the right (which would still be a deadlock).