我正在进行异步通信并计划实现以下例程:每个进程都拥有一个它必须与之通信的进程向量,按升序排列。它向所有较小的等级发布非阻塞接收,向所有较大的等级发送非阻塞发送。对于除进程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的Isend永远不会完成 - 我做错了什么?如果您需要更多信息来了解这个问题,请告诉我!我现在已经坚持了一个星期。
在发布了一些MPI_Irecv
s之后,recvRanks
重新分配push_back
,使指向已经作为缓冲区提供的元素的指针无效。首先使用reserve
来防止重新分配。