如何释放 boost::mpi::request?

Posted

技术标签:

【中文标题】如何释放 boost::mpi::request?【英文标题】:How do I free a boost::mpi::request? 【发布时间】:2017-10-20 02:33:23 【问题描述】:

我正试图让 MPI 断开一个通信器,这是一个易怒的业务 - 我在下面整理了一个演示。我有两个版本的相同想法,监听一个 int,一个使用 MPI_IRecv,一个使用 boost::mpi::request。

您会注意到,在此程序上使用 mpiexec -n 2 时,版本 A 会愉快地断开连接并退出,但版本 B 不会。 MPI_Request_free-ing 一个 boost::mpi::request 有什么技巧吗?这似乎就是这里的区别。如果重要的话,我正在使用 MSVC 和 MSMPI,以及 Boost 1.62。

#include "boost/mpi.hpp"
#include "mpi.h"

int main()

    MPI_Init(NULL, NULL);
    MPI_Comm regional;
    MPI_Comm_dup(MPI_COMM_WORLD, &regional);
    boost::mpi::communicator comm = boost::mpi::communicator(regional, boost::mpi::comm_attach);
    if (comm.rank() == 1)
    
        int q;

        //VERSION A:
//      MPI_Request n;
//      int j = MPI_Irecv(&q, 1, MPI_INT, 1, 0, regional, &n);
//      MPI_Cancel(&n);
//      MPI_Request_free(&n);

        //VERSION B:

//      boost::mpi::request z = comm.irecv<int>(1, 0, q);
//      z.cancel();

    
    MPI_Comm_disconnect(&regional);
    MPI_Finalize();
    return 0;

我发现错误了吗?我怀疑我对代码很深。

【问题讨论】:

comm_duplicate 大大改善了这种情况,但您仍然应该能够做到这一点。 版本 B 在 Linux 和 boost 1.61 上返回没有问题。 @Shibli 很可能依赖于 MPI 实现。对于 OpenMPI 1.10,示例代码不会在此处阻塞。但是从 boost 源/MPI 标准很容易看出它是不正确的。 【参考方案1】:

好吧,如果它被记录在案,它猜这不是一个错误:MPI_Request_free is unsupported by Boost.MPI。

现在回到 MPI 本身:

调用MPI_CANCEL 标记取消挂起的非阻塞通信操作(发送或接收)。取消呼叫是本地的。它会立即返回,可能在实际取消通信之前。仍然需要调用MPI_REQUEST_FREEMPI_WAITMPI_TEST(或任何派生操作)并将取消的请求作为 调用MPI_CANCEL 后的参数。 如果一个通信被标记为取消,那么该通信的 MPI_WAIT 调用保证返回,而不管其他进程的活动(即,MPI_WAIT 表现为本地函数);

也就是说,只是:

z.cancel();
z.wait();

你应该没事的。

现在,恕我直言,这是 Boost.MPI 对适当 RAII 的严重浪费。

【讨论】:

啊,明白了。这没有任何意义,但没关系。 如果有任何和解 - Boost.MPI 经常以愚蠢的大小问题和破坏正常 MPI 工作正常的东西让我感到惊讶。或者您认为该标准是否存在不合理的方面? 不,我知道正常的 MPI 正在做什么,整个取消和等待的事情有点令人惊讶。 Boost MPI 很可爱,但有时会唤醒你。

以上是关于如何释放 boost::mpi::request?的主要内容,如果未能解决你的问题,请参考以下文章

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

如何找到带有自动释放消息的对象?

如何手动释放Linux内存?

如何释放/释放 IntPtr 到函数指针?

如何强制释放 UITableViewCell

C#如何释放线程