MPI_ERR_TRUNCATE:在广播中发生截断错误

6

我有一个 int 值,我打算从根节点广播它(rank==(FIELD=0))。

int winner

if (rank == FIELD) {
    winner = something;
}

MPI_Barrier(MPI_COMM_WORLD);
MPI_Bcast(&winner, 1, MPI_INT, FIELD, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
if (rank != FIELD) {
    cout << rank << " informed that winner is " << winner << endl;
}

但是看起来我得到了。
[JM:6892] *** An error occurred in MPI_Bcast
[JM:6892] *** on communicator MPI_COMM_WORLD
[JM:6892] *** MPI_ERR_TRUNCATE: message truncated
[JM:6892] *** MPI_ERRORS_ARE_FATAL: your MPI job will now abort

我发现可以在 Bcast 中增加缓冲区大小。

MPI_Bcast(&winner, NUMPROCS, MPI_INT, FIELD, MPI_COMM_WORLD);

其中NUMPROCS是正在运行的进程数(实际上似乎只需要为2)。然后程序运行,但输出结果与预期不符...

1 informed that winner is 103
2 informed that winner is 103
3 informed that winner is 103
5 informed that winner is 103
4 informed that winner is 103

当我使用cout打印winner时,它应该是-1


我对代码本身没有任何问题;你如何定义FIELD?你能发布更多的代码吗?你确定是这个广播导致了问题吗? - Jonathan Dursi
@JonathanDursi, 这是地址 https://gist.github.com/4039617 - Jiew Meng
1
希望经过我三次编辑后,你的问题的根本原因现在已经变得清晰易懂了 :) - Hristo Iliev
1个回答

11

你的代码中有一个错误:

if (rank == FIELD) {
   // randomly place ball, then broadcast to players
   ballPos[0] = rand() % 128;
   ballPos[1] = rand() % 64;
   MPI_Bcast(ballPos, 2, MPI_INT, FIELD, MPI_COMM_WORLD);
}

这是一个非常常见的错误。 MPI_Bcast 是一种集体操作,必须由所有进程调用才能完成。在你的情况下,这个广播操作没有在所有进程中被调用到 MPI_COMM_WORLD(只有根进程),因此干扰了循环内的下一个广播操作。第二个广播操作实际上将第一个广播发送的消息(两个int元素)接收到一个只有一个int的缓冲区中,导致截断错误信息。在Open MPI中,每个广播使用相同的消息标签值,因此不按顺序发出的不同广播可能会相互干扰。这符合(旧的)MPI标准 - 在MPI-2.2中不能有多个未完成的集体操作(在MPI-3.0中可以有几个未完成的非阻塞集体操作)。你应该将代码改写为:

if (rank == FIELD) {
   // randomly place ball, then broadcast to players
   ballPos[0] = rand() % 128;
   ballPos[1] = rand() % 64;
}
MPI_Bcast(ballPos, 2, MPI_INT, FIELD, MPI_COMM_WORLD);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接