【问题标题】:Check if adjacent slave process is ended in MPI检查相邻的从进程是否在 MPI 中结束
【发布时间】:2016-01-21 00:52:17
【问题描述】:

在我的 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_Set()),当您的循环完成时,使用您拥有的任何值(如果它已被修改与否)。
  • @Gilles 我认为如果代码保持原样会更容易,除了使用 MPI 单向通信来编辑两个布尔值:prevNeighborDonenextNeighborDone。当你完成你的循环时,你会在你的两个邻居身上使用单方面的通讯,让他们知道你已经完成了。他们所要做的就是检查他们的布尔值的个人副本,看看他们是否应该收到。

标签: c++ parallel-processing synchronization mpi


【解决方案1】:

我首先要说 MPI 最初设计时并未考虑到您的用例。一般来说,MPI 应用程序都一起开始,也一起结束。但并非所有应用程序都适合此模型,所以不要失去希望!

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

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

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

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

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


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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-08
    • 1970-01-01
    • 2017-04-05
    相关资源
    最近更新 更多