MPI.NET:运行多个连续会话

时间:2017-10-26 10:00:38

标签: c# .net mpi message-passing

我一直在玩MPI.NET,我遇到了一个似乎无法解决的问题。

为运行MPI.NET的代码创建测试时,我有两个由MSTest顺序运行的单元测试,每个单元测试创​​建一个通信器并进行处理。
执行此操作时,最终会出现通信器初始化并在第二次测试中处置的情况(静态变量是此处的原因)。

我不打算从测试角度解决这个问题(以不同的方式运行测试并解决问题)。 我只是简单地向您展示这种情况,以便轻松演示问题。

我希望有一种合理的方式来初始化MPI.NET,或以某种方式回收它?

我确实与该项目的作者取得了联系,他建议我在这里发布更熟悉MPI本身的人可以提供帮助。

public static void RunMPIAction(Action<Intracommunicator> action)
{
    string[] args = null;
    using (var env = new Environment(ref args))
    {
        action(Communicator.world);
    }
}

MPI.Environment.RunMPIAction(comm =>
{
    this.Run(comm, logger, parameters);
}

MPI.Environment.RunMPIAction(comm => { int rank = comm.Rank; }, false);

1 个答案:

答案 0 :(得分:1)

MPI的设计并非如此。创建新的环境调用MPI_Init_thread,其中声明:

  

此函数只能由一个线程调用。该线程将是   称为“主线程”,必须与调用相同的线程   MPI_Finalize。

尝试从多个线程或多个线程多次调用它将失败。

处理Environment来电MPI_Finalize,其中声明:

  

MPI_Finalize函数清除与MPI相关的所有状态。一旦它   被调用,不能调用其他MPI函数,包括MPI_Init   和MPI_Init_thread。

由此可以清楚地表明,每个进程只需要一个Environment,并且一旦处理就无法重新创建它。

因此,您必须重构代码才能将此考虑在内。如果你有一些可重复使用的库 - 不要在那里初始化MPI(只是检查它是否已经初始化,如果没有,则抛出)并且不在那里完成 - 只有&#34;顶级&#34;该库的用户应该这样做。如果您没有引用已创建的Environment实例但需要完成环境,则可以这样做:

if (!MPI.Environment.Finalized)
    Unsafe.MPI_Finalize();

这样做是可以的,因为Environment在语义上是一个单例并且可能是一个静态类,但由于方便的using语句是非静态的(只有实例成员是Dispose功能)。