基本上我在这里寻找的是一个简单的MPI_SendRecv()例程,它允许我通过指定源处理器和目标处理器来同步相同的缓冲区。
在我看来,我的Ideal_MPI_SendRecv()函数的函数调用看起来与MPI_Bcast()完全相同,但是包含目标进程而不是Communicator。
可能会如下调用:
Ideal_MPI_SendRecv(&somebuffer, bufferlength, datatype, source_proc, destination_proc);
如果没有,有什么理由吗?看起来这种方法是在两个进程之间同步变量值的完美方法。
答案 0 :(得分:2)
不,MPI中没有这样的调用,因为使用点对点通信实现它是微不足道的。当然,你可以编写一个(例如,对错误处理有一些基本的支持):
// Just a random tag that is unlikely to be used by the rest of the program
#define TAG_IDEAL_SNDRCV 11223
int Ideal_MPI_SendRecv(void *buf, int count, MPI_Datatype datatype,
int source, int dest, MPI_Comm comm)
{
int rank;
int err;
if (source == dest)
return MPI_SUCCESS;
err = MPI_Comm_rank(comm, &rank);
if (err != MPI_SUCCESS)
return err;
if (rank == source)
err = MPI_Send(buf, count, datatype, dest, TAG_IDEAL_SNDRCV, comm);
else if (rank == dest)
err = MPI_Recv(buf, count, datatype, source, TAG_IDEAL_SNDRCV, comm,
MPI_STATUS_IGNORE);
return err;
}
// Example: transfer 'int buf[10]' from rank 0 to rank 2
Ideal_MPI_SendRecv(buf, 10, MPI_INT, 0, 2, MPI_COMM_WORLD);
您还可以添加另一个类型为MPI_Status *
的输出参数,并将MPI_Recv
的状态存储在那里。如果两个进程具有不同的缓冲区大小,则可能很有用。
另一种选择是,如果你必须在一组固定的等级中多次这样做,例如总是从0级到2级,你可以简单地创建一个新的沟通者并在其中广播:
int rank;
MPI_Comm buddycomm;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_split(MPI_COMM_WORLD, (!rank || rank == 2) ? 0 : MPI_UNDEFINED, rank,
&buddycomm);
// Transfer 'int buf[10]' from rank 0 to rank 2
MPI_Bcast(buf, 10, MPI_INT, 0, buddycomm);
这当然是一种矫枉过正,因为广播比MPI_Send
和MPI_Recv
的简单组合更昂贵。
答案 1 :(得分:0)
也许你想在一个进程(源进程,你想要的值)上调用MPI_Send
,在另一个进程(最初没有你想要的值的进程)上调用MPI_Recv
?
如果没有,你能否澄清一下你想要完成的工作与简单的点对点信息的区别?