c++ - 在新的 MPI_Isend 之前使用 MPI_Wait
问题描述
我正在尝试使用 MPI_Wait 阻止以前可能调用过或未调用过的 MPI_Isend,但它似乎并没有阻止下一个 MPI_Isend。
基本上,如果之前调用过 MPI_Isend 并且没有收到,那么我想等到它收到。然后调用一个新的 MPI_Isend。每个进程都应该始终探测传入的消息并动态接收它们。
for (time_stamp=0; time_stamp<time_max; time_stamp++) { // for each time stamp
// Probe for incoming particles from any process
MPI_Iprobe(MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &flag, &statRec);
// Receive particles from a process
if(flag){
std::cout << "Recieved from rank: " << statRec.MPI_SOURCE << "\n";
int recCount{};
MPI_Get_count(&statRec, MPI_Particle, &recCount);
Particle *recbuf = new Particle[recCount];
MPI_Recv(recbuf, recCount, MPI_Particle, statRec.MPI_SOURCE, statRec.MPI_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
for(int i=0; i<recCount; i++)
Particles.emplace_back(recbuf[i]);
delete[] recbuf;
}
int n = (int)Particles.size(), totalp = 0;
MPI_Reduce(&n, &totalp, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
if(rank == root)
std::cout << "Total particles " << totalp << "\n";
/* Do particle operations, put them in sendlists
and delete them from this ranks own particle list.... */
// Send to another process
if(!sendParticles.empty()) {
MPI_Wait(&req, MPI_STATUS_IGNORE);
std::cout << "Sending from rank " << rank << "... \n" ;
delete[] sendBuf;
sendcount = static_cast<int>(sendParticles.size());
sendBuf = new Particle[sendcount];
for(int i=0; i<sendParticles.size(); i++)
sendBup[i] = sendParticles[i];
MPI_Isend(sendBuf, sendcount, MPI_Particle, some_other_rank, 0, MPI_COMM_WORLD, &req);
}
}
输出:
总粒子 1000
从等级 1
发送...从等级 0 发送...
总粒子 998
从等级 1
发送...从等级 0 发送...
从等级接收:1
总粒子 994
从等级 1 发送.. .
从等级接收:0从等级 0
发送......
从等级接收:1
总粒子 993
从等级 0 发送......
从等级接收:1
总粒子 993
从等级 1
发送......从等级 0 发送......
如您所见,它尝试为两个进程连续发送 2 次,忽略 MPI_Wait。它似乎也一直减少到粒子总数,我猜有些会丢失,因为它会覆盖发送缓冲区,因为它不等待。
(对代码进行了一些编辑以使其更具可读性)
解决方案
如果您调用MPI_Wait()
来自 previous 的请求MPI_ISend()
,那么它将阻塞,直到可以重用发送缓冲区。
从非常实际的角度来看,如果消息足够短,它将立即返回,否则会挂起,直到发布匹配的接收。(足够短取决于您的 MPI 库、您的互连和其他因素。请注意,您永远不要想当然地认为它MPI_Wait()
会立即返回小消息)。
您的描述表明您需要替换MPI_Isend()
为MPI_Issend()
.
请注意,该标准仅要求MPI_Wait()
在发布匹配的接收时返回,因此严格来说,它可能会在远程对等方完全接收到消息之前返回。
推荐阅读
- javascript - 如何将 Underscore 模板翻译成 Handlebars 模板?
- python - 从文件中读取多种类型
- flutter - Flutter BLoC `buildWhen` 属性
- c++ - BST中只有一个子节点时如何删除根节点?
- python - 如何在给定百分比的情况下将数据框熊猫中的行拆分为新行
- html - Bootstrap 导航栏在使用底栏时不会展开
- automation - 打包程序错误 - sudo:不存在 tty 且未指定 askpass 程序
- azure-sql-database - 删除数据库同步代理失败
- c# - DropDownListFor 未绑定到模型列表中的值
- sql-server - 如何从具有相似行的四个表中选择并通过存储过程使用 SQL Server 插入到 1 个表中?