2016-11-20 66 views
1

假设你做了两个MPI_Sends和两个MPI_Recvs,你可以指定哪个缓冲区的内容将会到达MPI_Send,如果你有两个不同的缓冲区可用,并且每个MPI_Recvs都从每个缓冲区接收?你能指定在MPI中发送哪个缓冲区吗?

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。我想获得所有等级'sum s和sum2 s的总和。有没有更好的办法?例如,通过指定要发送的缓冲区sumsum2,下面的代码是否可以被压缩?

+0

对于关于改进或压缩代码的问题,我会在[Code Review](http://codereview.stackexchange.com/)Stack Exchange上提出这类问题。如果你把它放在那里而不是在这里,你会得到更好,更精确的答案。 – esote

+1

是否有任何理由避免使用减少操作? – Angelos

+0

@Impmpence谢谢,我会试试 – FullMetalScientist

回答

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,其中指出从task1到task2的两条消息的接收顺序与它们发送的顺序相同(如果它们可以通过相同的接收接收) - 这可以确保接收进程可以区分发送的第一条消息第二个。

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

+0

谢谢,这些方法真的很有帮助 – FullMetalScientist

+0

此外,为了回应您对类似问题的答案 - 如果您在函数中进行缩小并且想要返回所有级别总和(即globalsum)的总和,这怎么可能?看起来你只能使用MASTER排名中的globalsum。 – FullMetalScientist

+0

@FullMetalScientist - 如果您希望所有的等级都能得到最终答案,您可以使用'MPI_Allreduce' - 参见http://mpitutorial.com/tutorials/mpi-reduce-and-allreduce –