测试后无法取消 MPI 请求
Cannot cancel MPI requests after testing them
我正在尝试使用boost库创建模拟,但是我在进程的异步通信中遇到了问题。在我们的例子中,有 2 个进程相互发送/接收消息(使用 issend 和 ireceive 命令)。如果我等待所有发送/接收命令完成,那么一切都很好。所以,这是我的工作代码:
boost::mpi::communicator* comm;
// Initialize MPI and etc.
...
std::vector<boost::mpi::request> sendRequests;
std::vector<boost::mpi::request> receiveRequests;
for(int i=0; i< 10; i++){
receiveRequests.push_back(comm->irecv(0, 3000, receivedMessage));
sendRequests.push_back(comm->isend(1, 3000, sentMessage));
boost::mpi::wait_all(receiveRequests.begin(), receiveRequests.end());
receiveRequests.clear();
}
但是,如果花费太多时间,我想取消接收消息。因此,我尝试使用测试和取消功能测试通信是否完成。所以,我修改了我的代码,如下所示:
boost::mpi::communicator* comm;
// Initialize MPI and etc.
...
std::vector<boost::mpi::request> sendRequests;
std::vector<boost::mpi::request> receiveRequests;
for(int i=0; i< 10; i++){
receiveRequests.push_back(comm->irecv(0, 3000, receivedMessage));
sendRequests.push_back(comm->isend(1, 3000, sentMessage));
vector<boost::mpi::request>::iterator it = receiveRequests.begin();
while(it != receiveRequests.end()){
if(!((*it).test()))
(*it).cancel();
receiveRequests.erase(it);
}
}
现在,我的程序崩溃了,在循环的第一次迭代后出现此错误:
terminate called after throwing an instance of 'std::length_error'
what(): vector::_M_fill_insert
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::mpi::exception> >'
what(): MPI_Test: Message truncated, error stack:
PMPI_Test(168)....................: MPI_Test(request=0x13bba24, flag=0x7fff081a7bd4, status=0x7fff081a7ba0) failed
MPIR_Test_impl(63)................:
MPIDI_CH3U_Receive_data_found(129): Message from rank 0 and tag 3000 truncated; 670 bytes received but buffer size is 577
所以,我想知道如何解决此错误。
it
从何而来?无处可去
请注意,push_back可以重新分配,这会使任何挂起的迭代器失效。
另请注意,您需要有条件地递增it
以防您进行了删除。典型模式是
it = receiveRequests.erase(it);
更新我看到您已在问题中添加了信息。它可能应该是:
vector<boost::mpi::request>::iterator it = receiveRequests.begin();
while(it != receiveRequests.end()){
if(!((*it).test()))
(*it).cancel();
it = receiveRequests.erase(it);
}
我不确定为什么你总是删除每个接收请求。我假设这就是意图
终于,我想通了。这只是因为测试和取消方法之间的竞争条件。由于运行时有数百个消息请求,因此有时会发生这种情况。测试请求后,程序无法取消它,因为它刚刚完成(在测试方法之后,但在取消方法之前)。这就是为什么它不定期发生的原因。因此,我不得不改变我想做的事情并删除取消方法。
相关文章:
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 用MacOS Mojave编译C++:致命错误:mpi.h:没有这样的文件或目录
- 如何在boost beast http请求中设置http头
- 发送一个带有libcurl C++问题的帖子请求:s
- MPI突然停止了对多个核心的操作
- 在多个核心中处理一个HTTP请求
- 设置 Visual Studio for MPI: 找不到标识符错误
- 使用 make 编译 MPI,几个命名空间错误,例如"错误:未知类型名称'使用'?
- 如何使用 MPI 的远程内存访问 (RMA) 功能并行化数据聚合?
- 错误:请求非类类型为"MULTIMEDIA_FILME [500]"的成员|
- 使用 Winsock2.h C++向不和谐 API 发送 HTTP 请求时出现问题
- 每个服务器请求的内存预算
- 重载 MPI 中的运算符 ()
- std::getline没有在while循环中重新请求用户输入
- 如何释放提升::mpi::请求
- 我错过了boost :: mpi ::请求?测试似乎改变了状态
- 如果接收和发送匹配,MPI 请求是否完成
- 测试后无法取消 MPI 请求
- 提升 mpi 请求m_handler的目的是什么
- MPI 警告:程序退出并显示未完成的接收请求