MPI - indefinite send and recv
If I am using blocking send and recv (MPI_send()
, MPI_recv()
), how to make theese two operation indefinite? Like they are repeating all over again?
Sample code:
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD,&numtasks);
MPI_Comm_rank (MPI_COMM_WORLD,&rank);
if(rank==0){
rc=MPI_Send(msg,1,MPI_CHAR,1,1,MPI_COM开发者_开发技巧M_WORLD);
rc=MPI_Recv(msg,1,MPI_CHAR,1,1,MPI_COMM_WORLD,&status);
}else{
rc=MPI_Recv(msg,1,MPI_CHAR,0,0,MPI_COMM_WORLD,&status);
rc=MPI_Send(msg,1,MPI_CHAR,0,0,MPI_COMM_WORLD);
}
I have tried to put before if(rank==0) -> while(1)
and it did the job, but I see there are several sends, then several recieves and I want it like - send(0), receive(1), send(1), recieve(0).
You can code a ring of send-receive operations easily by using MPI_Sendrecv:
int MPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
int dest, int sendtag, void *recvbuf, int recvcount,
MPI_Datatype recvtype, int source, int recvtag,
MPI_Comm comm, MPI_Status *status)
As you can see it's only a condensed version of a MPI_Send and a MPI_Recv, but it comes handy when all the process needs either to send and receive something.
The following code works for any number of processes (you can adapt it to your needs):
CODE UPDATE #1 (Using MPI_Sendrecv)
#include <stdio.h>
#include <unistd.h>
#include <mpi.h>
int main (int argc, char *argv[])
{
int size, rank, value, next, prev, sendval, recval;
double t0, t;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
value = 5;
if (size > 1)
{
next = (rank + 1)% size;
prev = (size+rank - 1)% size;
sendval = value + rank;
for (;;)
{
t0 = MPI_Wtime();
MPI_Sendrecv(&sendval, 1, MPI_INT, next, 1, &recval, 1, MPI_INT, prev, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
t = MPI_Wtime();
fprintf(stdout, "[%d of %d]: Sended %d to process %d, Received %d from process %d (MPI_SendRecv Time: %f)\n",rank, size-1, sendval, next, recval, prev, (t - t0));
}
}
MPI_Finalize();
return 0;
}
CODE UPDATE #2 (Using separate MPI_Send/MPI_Recv)
#include <stdio.h>
#include <unistd.h>
#include <mpi.h>
int main (int argc, char *argv[])
{
int size, rank, value, next, prev, sendval, recval;
double s0, s, r, r0;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
value = 5;
if (size > 1)
{
next = (rank + 1)% size;
prev = (size+rank - 1)% size;
sendval = value + rank;
for (;;)
{
s0 = MPI_Wtime();
MPI_Send(&sendval, 1, MPI_INT, next, 1, MPI_COMM_WORLD);
s = MPI_Wtime();
fprintf(stdout, "[%d of %d]: Sended %d to process %d (MPI_Send Time: %f)\n", rank, size-1, sendval, next, s-s0);
r0 = MPI_Wtime();
MPI_Recv(&recval, 1, MPI_INT, prev, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
r = MPI_Wtime();
fprintf(stdout, "[%d of %d]: Received %d from process %d (MPI_Recv Time: %f)\n", rank, size-1, recval, prev, r-r0);
}
}
MPI_Finalize();
return 0;
}
Running Example
mpicc -o sendrecv sendrecv.c
mpirun -n 2 sendrecv
[0 of 1]: Sended 5 to process 1, Received 6 from process 1 (MPI_SendRecv Time: 0.000121)
[1 of 1]: Sended 6 to process 0, Received 5 from process 0 (MPI_SendRecv Time: 0.000068)
...
It is impossible to give an accurate answer to that without seeing at least the basic layout of your code. Generally, you would place the Send and Receive operations inside an infinite loop. Or, if you're hard pressed for optimal communication costs (or simply feeling adventurous), you could use persistent Send and Receive.
精彩评论