你能指定在MPI中发送哪个缓冲区吗?

时间:2016-11-20 17:11:27

标签: buffer mpi openmpi

说,如果你做了两个MPI_Sends和两个MPI_Recvs,你可以指定MPI_Send的内容将去哪个缓冲区,如果你有两个不同的缓冲区可用,每个MPI_Recvs从每个缓冲区接收到什么?

if(rank == MASTER) {
   for(kk=1; kk < size; kk++) { 
      MPI_Recv(printbuf, numcols, MPI_DOUBLE, kk, tag, MPI_COMM_WORLD, &status); 
      sum = sum + printbuf[kk-1];
    }
 }
 else {
   MPI_Send(sum, local_ncols + 2, MPI_DOUBLE, MASTER, tag, MPI_COMM_WORLD);
 }
 if(rank == MASTER) {
   for(kk=1; kk < size; kk++) {   
     MPI_Recv(secondbuf, numcols, MPI_DOUBLE, kk, tag, MPI_COMM_WORLD, &status); 
     sum2 = sum2 + secondbuf[kk-1];
   }
 }
 else {
   MPI_Send(sum2, local_ncols + 2, MPI_DOUBLE, MASTER, tag, MPI_COMM_WORLD);
 }

这是OpenMPI。每个排名都会计算sumsum2。我想获得所有等级'sumsum2的总和。有没有更好的办法?例如,通过指定要发送的sumsum2缓冲区,可以压缩以下代码吗?

1 个答案:

答案 0 :(得分:4)

Angelos的评论是正确的:如果您尝试对所有流程的结果进行求和,MPI_Reduce (e.g., this Q/Aamongst others)就可以了。

回答提出的一般性问题:当您发送消息时,您无法控制接收过程对其执行的操作 - 您所做的就是发送消息。但是,您可以控制一个元数据,然后将其发送到的任务:标签。接收过程可以根据标记决定接收哪个缓冲区:

if (rank != MASTER) {
    // worker process
    MPI_Send(sum1, local_ncols + 2, MPI_DOUBLE, MASTER, tag1, MPI_COMM_WORLD);
    MPI_Send(sum2, local_ncols + 2, MPI_DOUBLE, MASTER, tag2, MPI_COMM_WORLD);
} else {
    // master process
    MPI_Recv(printbuf, numcols, MPI_DOUBLE, kk, tag1, MPI_COMM_WORLD, &status); 
    MPI_Recv(secondbuf, numcols, MPI_DOUBLE, kk, tag2, MPI_COMM_WORLD, &status); 
}

您还可以采取其他方法。您可以使用MPI的non-overtaking guarantee,它指出从任务1到任务2的两条消息的接收顺序与它们发送的顺序相同,如果它们可以被同一接收方接收 - 这可以确保接收进程可以区分从第二个消息发送的第一个消息。

另一种可以在某些情况下工作的方法是将它们打包到同一个消息中(这对短消息有用,以减少延迟)并在接收端解压缩它们;这是确保您知道哪个数据块进入哪个缓冲区的另一种方法。