amro_ghoneim
amro_ghoneim

Reputation: 535

mpi send and recv all processes to one another

I am trying to send data between all processes where I have an array on each process such as

int local_data[] = {0*rank,1*rank,2*rank,3*rank};

I have a corresponding flag array where each value in that array points to which process I should be sending this value, for example:

int part[] = {0,1,3,2};

so this means local_data[0] should go to process with rank 0 local_data[2] should go to process with rank 3 and so on. The values in the flag arr changes from one process to the other ( all within range 0-P-1 where P is the total number of processes available) .

Using this, What I am currently doing is :

for(int i=0; i<local_len; i++){
        if(part[i] != rank){
            MPI_Send(&local_data[i], 1,MPI_INT, part[i], 0, MPI_COMM_WORLD);
            MPI_Recv(&temp,1, MPI_INT, rank, 0, MPI_COMM_WORLD, &status );
            recvbuf[j] = temp;
            j++;
        }
        else{
            recvbuf[j] = local_data[i];
            j++;
        }
    }

where I am only sending and receiving data if the part[i] != rank, to avoid sending and receiving from the same process

recvbuf is the array I receive the values in for each process. It can be longer than the initial local_data length.

I also tried

MPI_Sendrecv(&local_data[i], 1,MPI_INT, part[i], 0, &temp, 1, MPI_INT, rank, 0, MPI_COMM_WORLD, &status);

the program gets stuck for both ways

How do I go about solving this?

Is the All-to-All collective the way to go here?

Upvotes: 0

Views: 1989

Answers (2)

amro_ghoneim
amro_ghoneim

Reputation: 535

Following @GillesGouaillardet advice, I used MPI_AlltoAllv

to solve this problem.

Upvotes: 0

Victor Eijkhout
Victor Eijkhout

Reputation: 5820

Your basic problem is that your send call goes to a dynamically determined target, but there is no corresponding logic to determine which processes need to do a receive at all, and if so, from where.

If the logic of your application implies that everyone will send to everyone, then you can use MPI_Alltoall.

If everyone sends to some, but you know that you will receive exactly four messages, then you can combine MPI_Isend for the sends and MPI_Recv from ANY_SOURCE. Note that you need Isend because your code will deadlock, strictly speaking. It may work if your MPI has a "eager mode" for small messages.

If the number of sends and the targets are entirely random, then you need something like MPI_Ibarrier to detect that all is over and done.

But I suspect you're leaving out major information here. Why is the length of local_data 4? Is the part array a permutation? Et cetera.

Upvotes: 1

Related Questions