我对boost :: mpi :: request缺少什么?测试似乎改变了状态

时间:2017-05-02 13:42:44

标签: c++ boost mpi

所以我把这个简单的MPI示例放在了一起。我在测试boost :: mpi :: request时遇到了一些奇怪的行为,我无法解释。具体来说,如果您删除第二个循环上的注释,它将永远旋转。对boost :: mpi :: request的测试只返回true一次吗?如果是这样,有什么状态正在更新?我已经通过Boost的MPI和可选代码进行了调查,但我无法解释我所看到的内容。

(当然,对于初学者来说,你需要使用带有两个节点的mpiexec来自己运行。)

# include "stdafx.h"
# include <boost/serialization/string.hpp>
# include <boost/mpi.hpp>
# include <windows.h>
# include <iostream>
# include <boost/mpi.hpp>
# include <boost/optional.hpp>

int main(int argc, char *argv[]);

int main(int argc, char *argv[])

{
    boost::mpi::environment m_env;
    boost::mpi::communicator m_world;

    if (m_world.rank() == 0)
    {
        m_world.send(1,0, std::string("hi!"));
    }
    else
    {

        std::shared_ptr<std::string> rcv = std::shared_ptr<std::string>(new std::string());
        boost::mpi::request x = m_world.irecv(0, 0, *rcv);
        while (!x.test())
        {
            Sleep(10);
        }
        //while (!x.test())
        //{
        //  Sleep(10);
        //}
        std::cout << *rcv;
    }
}

2 个答案:

答案 0 :(得分:1)

这与MPI标准一致。当MPI_TEST表示操作已完成时,返回的状态对象将包含有关已完成操作的信息,操作对象本身将标记为非活动或取消分配(以适用者为准)。再次在该操作对象上调用MPI_TEST将返回空状态。

(最新版本)MPI标准提供了一种以非破坏性方式访问状态的方法:MPI_REQUEST_GET_STATUS

我不知道在boost中执行此操作,但您可以只存储返回的status对象,稍后再参考,而不是再次调用test

答案 1 :(得分:1)

答案在文档中,有点像:

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

然后查看docs for the underlying MPI_Test function

  

如果请求标识的操作完成,则对MPI_TEST的调用将返回flag = true。在这种情况下,状态对象被设置为包含关于完成的操作的信息;如果通信对象是由非阻塞发送或接收创建的,则将其解除分配并将请求句柄设置为MPI_REQUEST_NULL。

     

允许一个用空或非活动请求参数调用MPI_TEST。在这种情况下,操作返回flag = true和空状态。

所以我们看到Boost MPI的test()方法返回optional<status>,而MPI_Test()只返回一次状态(之后,请求被销毁) 。重复调用的MPI_Test()会返回flag = true,但这不是您正在检查的内容。如果你真的需要这种模式,你可以自己调用MPI_Test()并使用返回的标志而不是状态。或者只是在您的应用程序中进行簿记,并且不要在同一请求上拨打boost::mpi::request::test()两次。

另一种查看此问题的方法是,您在布尔上下文中使用test()的结果,您希望它在flag的{​​{1}}中工作,但实际上它就像MPI_Test()一样,它的布尔性质只是一种幻觉。