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

Check if adjacent slave process is ended in MPI

本文关键字:MPI 结束 是否 进程 检查      更新时间:2023-10-16

在我的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时,我不会检查秩-1,当进程为最后一个时,我也不会检查秩+1。但是我怎样才能做到这一点呢?我应该再包一段时间吗?我很困惑。

我首先要说的是,MPI最初的设计并没有考虑到您的用例。通常,MPI应用程序都是一起开始的,也都是一起结束的。但并不是所有的应用程序都适合这个模型,所以不要失去希望!

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

  1. 使用RMA设置邻居的标志

正如评论中所指出的,您可以设置一个小的RMA窗口,向每个邻居公开一个值。当一个进程完成工作时,它可以对每个邻居执行MPI_Put,以指示它已经完成,然后执行MPI_Finalize。在向邻居发送/从邻居接收数据之前,请检查是否设置了标志。

  1. 在检测到停机时使用特殊标签

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


然而,您发布的伪代码还有另一个问题。如果您希望在每次迭代结束时执行MPI_Barrier,则不能让流程提前离开。当这种情况发生时,MPI_Barrier将挂起。不幸的是,你无法避免这种情况。然而,考虑到你发布的代码,我不确定这个屏障是否真的有必要。在我看来,唯一的循环间依赖关系是在相邻进程之间。如果是这种情况,那么发送和接收将完成所有必要的同步。

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