在我的 MPI 程序中,我想向相邻进程发送和接收信息。但是如果一个进程结束并且没有发送任何东西,它的邻居将永远等待。我该如何解决这个问题?这是我正在尝试做的事情:
if (rank == 0) {
// don't do anything until all slaves are done
} else {
while (condition) {
// send info to rank-1 and rank+1
// if can receive info from rank-1, receive it, store received info locally
// if cannot receive info from rank-1, use locally stored info
// do the same for process rank+1
// MPI_Barrier(slaves); (wait for other slaves to finish this iteration)
}
}
我当然要检查边界。当进程号为 1 时,我不会检查 rank-1,当进程是最后一个时,我不会检查 rank+1。但我怎样才能做到这一点?我应该再包一会儿吗?我很困惑。
最佳答案
首先我要说的是,MPI 最初设计时并未考虑到您的用例。通常,MPI 应用程序都一起开始,一起结束。不过,并非所有应用程序都适合此模型,所以不要失去希望!
有两种相对简单的方法可以做到这一点,而且可能有数千种困难的方法:
- 使用 RMA 为邻居设置标志。
正如评论中所指出的,您可以设置一个微小的 RMA 窗口,向每个邻居公开一个值。当一个进程完成工作时,它可以对每个邻居执行 MPI_Put
以指示它已完成,然后执行 MPI_Finalize
。在向邻居发送数据/从邻居接收数据之前,检查是否设置了标志。
- 检测关机时使用特殊标签。
标记值在发送和接收消息时经常被忽略,但这是使用它的好时机。您的应用程序中可以有两个标志。第一个(我们称它为 DATA
)只是表示此消息包含数据,您可以正常处理它。第二个 (DONE
) 表示进程已完成并正在离开应用程序。接收消息时,您必须将 tag
的值从您使用的任何值更改为 MPI_ANY_TAG
。然后,当收到消息时,检查它是哪个标签。如果它是 DONE
,则停止与该进程通信。
然而,您发布的伪代码还有另一个问题。如果您希望在每次迭代结束时执行 MPI_Barrier
,则不能让进程提前离开。发生这种情况时,MPI_Barrier
将挂起。不幸的是,您无能为力。但是,鉴于您发布的代码,我不确定是否真的有必要设置障碍。在我看来,唯一的循环间依赖是在相邻进程之间。如果是这种情况,那么发送和接收将完成所有必要的同步。
如果您仍然需要一种方法来跟踪所有等级何时完成,您可以让每个进程在它离开时提醒一个等级(比如等级 0)。当 rank 0 检测到每个人都完成时,它可以退出。或者,如果你想在其他一些进程完成后离开,你可以让等级 0 向所有其他等级发送一条消息,带有上面的特殊标签(但添加 MPI_ANY_SOURCE
这样你就可以接收从等级 0 开始)。
关于c++ - 检查相邻的从属进程是否在 MPI 中结束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34706087/