我一直在玩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);
答案 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
功能)。