首页 > 解决方案 > MPI_Scatter 是否影响 MPI_Bcast?

问题描述

我正在发送一个通过 MPI_Bcast 触发终止的整数。根将一个名为“running”的变量设置为零并发送 BCast。Bcast 似乎已完成,但我看不到该值已发送到其他进程。其他进程似乎正在等待 MPI_Scatter 完成。他们甚至不应该到达这里。

我对 MPI_Bcast 做了很多研究,据我了解它应该是阻塞的。这让我感到困惑,因为即使我找不到其他进程的匹配(接收)MPI_Bcast,来自根的 MPI_Bcast 似乎也已完成。我已经用 printfs 包围了我所有的 MPI_Bcast,并且这些 printfs 的输出 1)打印和 2)从根目录打印正确的值。

根看起来如下:

while (running || ...) {
    /*Do stuff*/
    if (...) {
        running = 0;
        printf("Running = %d and Bcast from root\n", running);
        MPI_Bcast(&running, 1, MPI_INT, 0, MPI_COMM_WORLD);
        printf("Root 0 Bcast complete. Running %d\n", running);
        /* Do some more stuff and eventually reach Finalize */
        printf("Root is Finalizing\n");
        MPI_Finalize();
    }
}

其他进程具有以下代码:

while (running) {
    doThisFunction(rank);
    printf("Waiting on BCast from root with myRank: %d\n", rank);
    MPI_Bcast(&running, 1, MPI_INT, 0, MPI_COMM_WORLD);
    printf("P%d received running = %d\n", rank, running);
    if (running == 0) { // just to make sure.
        break;
    }
}
MPI_Finalize();

我在函数“doThisFunction()”中也有以下内容。这是进程似乎正在等待进程 0 的地方:

int doThisFunction(...) {
    /*Do stuff*/
    printf("P%d waiting on Scatter\n", rank);
    MPI_Scatter(buffer, 130, MPI_BYTE, encoded, 130, MPI_BYTE, 0, MPI_COMM_WORLD);
    printf("P%d done with Scatter\n", rank);
    /*Do stuff*/
    printf("P%d waiting on gather\n", rank);
    MPI_Gather(encoded, 1, MPI_INT, buffer, 1, MPI_INT, 0, MPI_COMM_WORLD);
    printf("P%d done with gater\n", rank);
    /*Do Stuff*/
    return aValue;
}

命令行中的输出如下所示:

P0 waiting on Scatter
P0 done with Scatter
P0 waiting on gather
P0 done with gather
Waiting on BCast from root with myRank: 1
P1 received running = 1
P1 waiting on Scatter
P0 waiting on Scatter
P0 done with Scatter
P0 waiting on gather
P0 done with gather
P1 done with Scatter
P1 waiting on gather
P1 done with gather
Waiting on BCast from root with myRank: 1
P1 received running = 1
P1 waiting on Scatter
Running = 0 and Bcast from root
Root 0 Bcast complete. Running 0
/* Why does it say the Bcast is complete 
/* even though P1 didn't output that it received it?
Root is Finalizing
/* Deadlocked...

我期望 P1 接收运行为零,然后进入 MPI_Finalize() 而是卡在散点处,已经尝试完成的根无法访问该散点。

实际上,程序处于死锁状态,不会终止 MPI。

我怀疑问题在于分散是否接受 Bcast 值,因为这甚至没有意义,因为根不调用分散。

有没有人有任何关于如何解决这个问题的提示?

非常感谢您的帮助。

标签: parallel-processingmpi

解决方案


为什么即使 P1 没有输出它接收到它,它也说 Bcast 已完成?

请注意MPI 标准中的以下定义:

一旦调用者参与集体通信完成,集体操作就可以(但不是必须)完成。...集体操作的完成表明调用者可以自由地修改通信缓冲区中的位置它并不表示组中的其他进程已经完成甚至开始了该操作(除非操作描述中另有暗示)。因此,集体通信操作可能会或可能不会具有同步所有调用进程的效果。当然,该语句不包括屏障操作。

根据这个定义,MPI_Bcast即使没有MPI_Bcast从站调用,您的根进程也可以完成。

(对于点对点操作,我们有不同的通信模式,例如同步模式,来解决这些问题。不幸的是,集体没有同步模式。)


您的代码中的操作顺序似乎存在一些问题。根调用MPI_Bcast了 ,但进程 #1 没有调用,并且MPI_Scatter正如您的日志输出所示正在等待。


推荐阅读