MPI_Scatter是否会影响MPI_Bcast?

时间:2019-05-03 11:31:43

标签: parallel-processing mpi

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

我对MPI_Bcast进行了大量研究,据我了解,它应该被阻止。这使我感到困惑,因为即使找不到其他进程的匹配(接收)MPI_Bcasts,从根目录开始的MPI_Bcast似乎也已完成。我已经用printfs包围了所有MPI_Bcast,并且这些printfs的输出是1)print和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值,因为这根本没有意义,因为根目录不调用散点。

请问有人对如何解决此问题有任何提示吗?

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

  

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

请注意MPI Standard中的以下定义:

  

只要呼叫者参与集体交流的参与完成,集体操作就可以(但不是必须)完成。 ...集体操作的完成表明呼叫者可以自由修改通信缓冲区中的位置这并不表示该组中的其他进程已经完成或什至开始了该操作(除非操作说明另有暗示)。因此,集体通信操作可以具有或可以不具有使所有呼叫过程同步的效果。当然,此声明不包括屏障操作。

根据此定义,即使没有从属调用MPI_Bcast,您在根进程上的MPI_Bcast也可以完成。

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


在您的代码中,操作顺序似乎存在一些问题。根名为MPI_Bcast,但是进程#1却没有,并且正在MPI_Scatter上等待日志输出指示。