MPI_Isend根进程永远不会到达

时间:2019-03-23 15:20:02

标签: c++ mpi mpich

我正在从事异步通信,并计划实现以下例程:每个进程都拥有一个必须与之通信的进程的向量(按升序排列)。它向所有较小等级发送非阻塞接收,向所有较大等级发送非阻塞发送。对于除进程0以外的所有进程,此方法均适用。我怎么了?

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

理解代码:rank是当前进程的等级,commRanks是要与之通信的进程的向量。 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的发行从未完成-我做错了什么?如果您需要更多信息来理解这个问题,请告诉我!我在这一点上已经停留了一个星期。

1 个答案:

答案 0 :(得分:0)

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