c++ - 其他进程在 MPI_Sendrecv 之后挂起

标签 c++ openmpi

我想使用 MPI_Sendrecv

MPI_Sendrecv(&ballPos, 2, MPI_INT, FIELD, NEW_BALL_POS_TAG, &ballPos, 2, MPI_INT, winner, NEW_BALL_POS_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);

但我只注意到根(接收方继续运行?)。在 Sendrecv 之前和之后都有 cout 产生:

0 b4 sendrecv
2 b4 sendrecv
4 b4 sendrecv
1 b4 sendrecv
3 b4 sendrecv
5 b4 sendrecv
0 after sendrecv

在 sendrecv 之前所有进程都正常,但之后只有 root 解锁。

Full source : 见第 147 行

更新

结果应该类似于下面的内容

if (rank == winner) {
    ballPos[0] = rand() % 128;
    ballPos[1] = rand() % 64;
    cout << "new ball pos: " << ballPos[0] << " " << ballPos[1] << endl;
    MPI_Send(&ballPos, 2, MPI_INT, FIELD, NEW_BALL_POS_TAG, MPI_COMM_WORLD);
} else if (rank == FIELD) {
    MPI_Recv(&ballPos, 2, MPI_INT, winner, NEW_BALL_POS_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}

最佳答案

发布的发送数应该等于发布的接收数。在你的情况下,所有排名都发送到排名 FIELD 并从排名 winner 接收,包括 FIELDwinner:

Rank       Sends to  Receives from
----------------------------------
0 (FIELD)  FIELD     winner
1          FIELD     winner
2          FIELD     winner
...        ...       ...
winner     FIELD     winner
...        ...       ...
numprocs-1 FIELD     winner

(这样的表格有时可能非常有用)

因此 FIELD 应该接收 numprocs 消息,但它只执行一次 MPI_Sendrecv,因此 numprocs-1 调用MPI_Sendrecv 将无法完成发送。 获胜者 也是如此。它应该发送 numprocs 消息,但由于它只执行一次 MPI_Sendrecv,因此只发送一条消息,因此 numprocs-1 调用 MPI_Sendrecv 将无法完成接收。

还有一个错误。 MPI 标准要求发送和接收缓冲区不相交(即它们不应重叠),但您的代码并非如此。您的发送和接收缓冲区不仅重叠,而且它们是同一个缓冲区。如果你想在同一个缓冲区中执行交换,MPI 提供了 MPI_Sendrecv_replace 操作。

我不确定你想用这个 MPI_Sendrecv 语句实现什么,但我强烈怀疑你需要把它放在 if 语句中。

关于c++ - 其他进程在 MPI_Sendrecv 之后挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13306867/

相关文章:

c - 强制 MPI_Send 使用 eager 或 rendezvouz 协议(protocol)

ssh - 使用 MPI 后端时,分布式 PyTorch 代码在多个节点上停止

c++ - OSX "error: cannot convert ' const std::__cxx11::basic_string<char>"是什么意思?

c++ - 将指向 null 的指针设置为分配的内存吗?

c++ - C++ 中的快速排序很慢

c++ - 如何在 go 中使用 .lib 和 .dll 文件调用预构建的 API?

c++ - 修改 cin 以也返回换行符

c++ - Eclipse 中的源代码外构建

c - 2 个静态进程的问题,它使用打开的 mpi 创建 2 个动态进程

c - MPI - C 语言中的列类型问题