在MPI中是否有一个方法就像MPI_Bcast一样,但是对于一个单独的进程,而不是在整个通信器上运行?

时间:2013-11-20 04:43:28

标签: c parallel-processing mpi

基本上我在这里寻找的是一个简单的MPI_SendRecv()例程,它允许我通过指定源处理器和目标处理器来同步相同的缓冲区。

在我看来,我的Ideal_MPI_SendRecv()函数的函数调用看起来与MPI_Bcast()完全相同,但是包含目标进程而不是Communicator。

可能会如下调用:

Ideal_MPI_SendRecv(&somebuffer, bufferlength, datatype, source_proc, destination_proc);

如果没有,有什么理由吗?看起来这种方法是在两个进程之间同步变量值的完美方法。

2 个答案:

答案 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_SendMPI_Recv的简单组合更昂贵。

答案 1 :(得分:0)

也许你想在一个进程(源进程,你想要的值)上调用MPI_Send,在另一个进程(最初没有你想要的值的进程)上调用MPI_Recv

如果没有,你能否澄清一下你想要完成的工作与简单的点对点信息的区别?