检查相邻的从属进程是否在 MPI 中结束

Check if adjacent slave process is ended in MPI

在我的 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 应用程序都一起开始,一起结束。不过,并非所有应用程序都适合此模型,所以不要失去希望!

有两种相对简单的方法可以做到这一点,而且可能有数千种困难的方法:

  1. 使用 RMA 在邻居上设置标志。

正如评论中所指出的,您可以设置一个微型 RMA window,向每个邻居公开一个值。当一个进程完成工作时,它可以对每个邻居执行 MPI_Put 以指示它已完成,然后 MPI_Finalize。在 sending/receiving 数据 to/from 邻居之前,检查是否设置了标志。

  1. 检测关机时使用特殊标签。

标签值在发送和接收消息时经常被忽略,但这是使用它的好时机。您的应用程序中可以有两个标志。第一个(我们称它为 DATA)仅表示此消息包含数据,您可以正常处理它。第二个 (DONE) 表示进程已完成并正在离开应用程序。接收消息时,您必须将 tag 的值从您使用的任何值更改为 MPI_ANY_TAG。然后,当收到消息时,检查它是哪个标签。如果是 DONE,则停止与该进程通信。


不过,您发布的 pseudo-code 存在另一个问题。如果您希望在每次迭代结束时执行 MPI_Barrier,则不能让进程提前离开。发生这种情况时,MPI_Barrier 将挂起。不幸的是,您无能为力。但是,鉴于您发布的代码,我不确定是否真的有必要设置障碍。在我看来,唯一的 inter-loop 依赖关系是在相邻进程之间。如果是这样,那么发送和接收将完成所有必要的同步。

如果您仍然需要一种方法来跟踪所有等级何时完成,您可以让每个进程在它离开时提醒一个等级(比如等级 0)。当 rank 0 检测到每个人都完成时,它可以退出。或者,如果你想在其他一些进程完成后离开,你可以让等级 0 向所有其他等级发送一条消息,带有上面的特殊标签(但添加 MPI_ANY_SOURCE 这样你就可以从等级 0 接收).