c++ - 根进程的 MPI_Isend 永远不会到达

标签 c++ mpi mpich

我正在研究异步通信并计划实现以下例程:每个进程都拥有一个必须与之通信的进程 vector ,按升序排列。它向所有较小的 rank 发送非阻塞接收,向所有较大的 rank 发送非阻塞发送。对于除进程 0 之外的所有进程,这都有效。我的问题是什么?

我已经通过命令行输出检查过每个进程以正确的顺序和正确的信息发布接收和发送的数量。此外,使用 unistd.h,我调用了 sleep(5) 来检查一段时间后通信是否成功。我已经检查(使用 Probe 并阻止 MPI_Recv)消息确实在途中 - 如果我使用 MPI_Irecv,它似乎永远不会到达。

理解代码:rank是当前进程的rank,commRanks是要与之通信的进程的 vector 。 recvRanks 是存储消息内容的地方。 reqsArray 是一个请求数组,它的大小与 commRanks 相同。 rankIndex 和 index 分别从 commRanks.begin() 迭代到 commRanks.end() 和从 0 迭代到 commRanks.size()。


std::vector<int> recvRanks;

for ( rankIndex = commRanks.begin(); *rankIndex < rank && rankIndex != domain->commRanks.end() ; rankIndex++ ) {
  //initialize recv buffer to -1 to see if communication works:
  recvRanks.push_back(-1);
  MPI_Irecv(&recvRanks.at(index),1,DT_RANK_MPI,*rankIndex,1,MPI_COMM_WORLD,&reqsArray[index]);
  index++;
}

if (*rankIndex == rank) {
  *rankIndex++;
  index++;
}

for ( ; rankIndex != domain->commRanks.end() ; rankIndex++ ) {
  MPI_Isend(&rank,1,DT_RANK_MPI,*rankIndex,1,MPI_COMM_WORLD,&reqsArray[index]);
  index++;
}

sleep(5);

//check if communication was successful:
printf("process 0: [ ");
for (unsigned int i = 0; i < recvRanks.size(); i++){
 printf("%d ", recvRanks.at(i));
}
printf("]\n");

我希望输出是:

进程 0:[ ]

进程 1:[ 0 ]

进程 2:[ 0 1 ]

进程 3:[ 0 1 2 ]

...

实际结果:

进程 0:[ ]

进程 1:[-1]

进程 2:[ -1 1 ]

过程 3:[ -1 1 2 ]

...

所以进程 0 的 Isend 永远不会完成 - 我做错了什么?如果您需要更多信息来理解问题,请告诉我!我已经在这一点上停留了一个星期了。

最佳答案

在发布您的一些 MPI_Irecv 之后,recvRankspush_back 上重新分配,使指向其元素的指针已经作为缓冲区提供。首先使用 reserve 来防止重新分配。

关于c++ - 根进程的 MPI_Isend 永远不会到达,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55315251/

相关文章:

c - 庆典 :/usr/bin/hydra_pmi_proxy: No such file or directory

c++ - MPI:更改 CMakelist 中的处理器数量

c++ - 如何在 Windows 不分配盘符的情况下创建分区?

c - MPI:程序工作取决于进程数

c++ - 如何在 Windows 上的 Qt 上设置 MPI

openmpi - mpi4py irecv 导致段错误

c++ - 如何在 Opengl Windows 上使用 Cairo 加速绘图?

c++ - 当我运行C++程序时,它返回某种数字

c++ - Char* 没有在我的类中保留文本 - 初始化构造函数问题?

c - 在 MPI 中发送/接收 3D 数组