gpt4 book ai didi

c++ - boost::mpi 的 irecv() 返回未初始化的状态对象

转载 作者:行者123 更新时间:2023-11-30 05:22:36 31 4
gpt4 key购买 nike

我正在收到 boost::mpi使用 irecv() 的消息功能。我有一个等待循环,调用 test()requestirecv 返回的对象并且,如果请求完成,则执行某些操作。然而,试图找出发件人的等级,我得到一个异常(exception):

boost::optional<T>::reference_type boost::optional<T>::get() [with T = boost::mpi::status; boost::optional<T>::reference_type = boost::mpi::status&]: Assertion `this->is_initialized()' failed.

这是我的代码片段:

mpi::request inc = world.irecv(mpi::any_source, MpiHandler::MPI_RESULT, pxl_results);
do {
if(inc.test()) {
// fails here, as the optional<status> returned by inc.test() is not initialized.
world.send(inc.test().get().source(), MpiHandler::MPI_WORK, package);
...
}
} while(...);

如果我检查 inc.test().is_initialized() ,我发现 optional<status>确实是未初始化的。这里发生了什么,为什么我找不到关于我的 MPI 发送器的任何信息?可能是mpi::any_source吗?这与 irecv 不兼容?


补充一下:通常,可以从请求对象中找到 MPI 消息的发送者和标记,如 this answer 中所述。 .

最佳答案

我很高兴你解决了这个问题,但也许这会进一步解释它。

问题正在调用 req.test()在成功调用 req.test() 后再次调用. MPI - 完整引用:第 1 卷,MPI 核心:

A request object is deallocated automatically by a successful call to MPI_WAIT or MPI_TEST.

此外,来自 boost mpi 文档:

optional< status > test(); Determine whether the communication associated with this request has completed successfully. If so, returns the status object describing the communication. Otherwise, returns an empty optional<> to indicate that the communication has not completed yet. Note that once test() returns a status object, the request has completed and wait() should not be called.

因此,在if(req.test())之后成功返回 boost::optional<mpi::status>随后调用 req.test()可能会返回一个空的 optional<>导致你的异常。

为了看到这一点,我们首先从链接答案中的 Jonathan Dursi 的 hello world 示例中创建一个示例:

#include <boost/mpi.hpp>
#include <iostream>
#include <string>
#include <boost/serialization/string.hpp>
namespace mpi = boost::mpi;

int main()
{
mpi::environment env;
mpi::communicator world;

if (world.rank() == 0) {
std::string msg, out_msg = "Hello from rank 0.";
world.send(1, 17, out_msg);
} else {
mpi::request req;
std::string rmsg;

req = world.irecv(mpi::any_source, mpi::any_tag, rmsg);
do {
if(req.test()) {
// fails here, as the optional<status> returned by inc.test() is not initialized.
std::cout << "From " << req.test().get().source() << std::endl;
std::cout << "Got " << rmsg << std::endl;
break;
}
} while(1);
}

return 0;
}

构建并运行它会导致预期的异常:

[ronin:~/Documents/CPP] aichao% mpirun --hostfile hostfile -np 2 ./test_mpi_request
From Assertion failed: (this->is_initialized()), function get, file /Users/Shared/Tools/boost_1_53_0/boost/optional/optional.hpp, line 631.

解决这个问题:

  1. 调用req.test()返回 boost::optional<mpi::status>对象。
  2. 测试 boost::optional反对看是否req.test()成功返回,如果成功,使用返回的 mpi::status .

代码:

#include <boost/mpi.hpp>
#include <iostream>
#include <string>
#include <boost/serialization/string.hpp>
namespace mpi = boost::mpi;

int main()
{
mpi::environment env;
mpi::communicator world;

if (world.rank() == 0) {
std::string msg, out_msg = "Hello from rank 0.";
world.send(1, 17, out_msg);
} else {
mpi::request req;
std::string rmsg;

req = world.irecv(mpi::any_source, mpi::any_tag, rmsg);
do {
boost::optional<mpi::status> stat = req.test();
if (stat) {
std::cout << "From " << stat->source() << std::endl;
std::cout << "Got " << rmsg << std::endl;
std::cout << "Tagged " << stat->tag() << std::endl;
break;
}
} while(1);
}

return 0;
}

现在,我们成功了:

[ronin:~/Documents/CPP] aichao% mpirun --hostfile hostfile -np 2 ./test_mpi_request
From 0
Got Hello from rank 0.
Tagged 17

关于c++ - boost::mpi 的 irecv() 返回未初始化的状态对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39546941/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com