c++ - 根进程的 MPI_Isend 永远不会到达
问题描述
我正在研究异步通信并计划实现以下例程:每个进程都拥有一个它必须与之通信的进程向量,按升序排列。它向所有较小的等级发布非阻塞接收,向所有较大的等级发布非阻塞发送。对于除进程 0 之外的所有进程,这都有效。我的问题是什么?
我已经通过命令行输出检查了每个进程都应该按照正确的顺序和正确的信息发布接收和发送的数量。另外,使用 unistd.h,我调用了 sleep(5) 来检查一段时间后通信是否成功。我已经检查(使用 Probe 并阻止 MPI_Recv)消息实际上正在发送中 - 如果我使用 MPI_Irecv,它似乎永远不会到达。
理解代码:rank是当前进程的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
重新分配 on push_back
,使指向已作为缓冲区提供的元素的指针无效。首先使用reserve
以防止重新分配。
推荐阅读
- video-streaming - 在 RTSP 流中提供特殊字符密码
- android - 不推荐使用 setCellType(CellType.STRING)
- swift5.2 - 如何解决 Swift 5.2 中的“Inout 表达式创建临时指针”问题?
- android - 如何优化 Kotlin 中 Context、Fragment 和 Activity 的扩展功能代码?
- android - android firebase线程回调到另一个线程而不是main?
- node.js - 将完整填充对象添加到另一个 Schema 对象
- python-3.x - 如何使用 apply() 函数替换值。?
- android - Android Fragment 和 ViewModel 问题
- java - 单元测试 - AssertionFailedError - Java
- javascript - 使用 for 循环在 JS 数组中显示图像的缩略图