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

Posted

技术标签:

【中文标题】我对 boost::mpi::request 缺少啥?测试似乎改变了状态【英文标题】:What am I missing about boost::mpi::request ? Testing seems to change state我对 boost::mpi::request 缺少什么?测试似乎改变了状态 【发布时间】:2017-09-30 01:42:46 【问题描述】:

所以我把这个简单的 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;
    

【问题讨论】:

【参考方案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。

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

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

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

【讨论】:

是的,这就是我最终要做的——只是记下我自己的布尔值。我没有考虑底层的 MPI_TEST - 谢谢【参考方案2】:

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

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

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

【讨论】:

以上是关于我对 boost::mpi::request 缺少啥?测试似乎改变了状态的主要内容,如果未能解决你的问题,请参考以下文章

为啥 boost::mpi::request.test() 返回无效的统计信息

我对数组的理解缺少啥?

我对 WCF 缺少啥?

我缺少哪些 Hibernate 注释?

缺少模板 - 模板缺失

我在 XMLHttpRequest 中缺少啥?