1

我已经仔细查看过,但找不到任何关于这个问题的参考。

我编写了一个 c++ 程序,我正在使用 boost/unit 进行测试。串行版本工作正常,单元测试工作正常。
现在,我通过一个函数使程序并行化,该函数与 MPI 进行了令人尴尬的并行工作。如果写下我自己的调用并行函数的测试——让我们称之为 parafunction——它运行良好,MPI 运行正常。
编译是用 mpic++ 完成的,我使用 mpixec 来运行程序。

但是,如果我在 boost 测试用例中调用 parafunction,MPI 就会出错,测试会被多次启动,并且在多次MPI::Init调用时进程会崩溃。这是我得到的错误示例:

在调用 MPI_FINALIZE 之后调用 MPI_comm_size() 函数。

MPI 标准不允许这样做。

您的 MPI 作业现在将中止。

我的测试用例在 test_unit 上,由 master_test_suite 自动处理。正如我所说,没有并行化它工作得很好。

辅助函数调用MPI::Initand MPI::Finalize,并且文件的其他函数不应该做任何与 MPI 相关的事情。

有没有人遇到过类似的问题?

我的测试运行时间很长,因此我真的可以使用我的程序的并行版本!

谢谢你的帮助

4

1 回答 1

2

一个既初始化又完成的函数只能被调用一次,因为 MPI 在程序的生命周期内只能被初始化一次,并且只能被完成一次。为防止多次初始化调用,请将调用置于MPI_Init()MPI_Init_thread()条件中:

int already_initialised;

MPI_Initialized(&already_initialised);
if (!already_initialised)
   MPI_Init(NULL, NULL);

至于最终确定,它应该移到你的函数之外,atexit(3)如果你不想用 MPI 调用污染外部范围,可能在处理程序中。例如:

void finalise_mpi(void)
{
   int already_finalised;

   MPI_Finalized(&already_finalised);
   if (!already_finalised)
      MPI_Finalize();
}

...
atexit(finalise_mpi);
...

atexit()调用可能是初始化代码的一部分,例如:

int already_initialised;

MPI_Initialized(&already_initialised);
if (!already_initialised)
{
   MPI_Init(NULL, NULL);
   atexit(finalise_mpi);
}

atexit(3)如果 MPI 已经初始化,这将不会安装处理程序。基本思想是,如果 MPI 在进入函数时被初始化,那么这将意味着它MPI_Init()在外部范围内被调用,并且人们通常会期望它MPI_Finalize()也在那里被调用。

如果我是你,我会将 MPI 初始化和终结移出并行处理功能。正确的调用顺序是初始化 MPI,运行测试,然后完成 MPI。

我在上面的文本中使用了 C 绑定,因为 C++ 绑定在 MPI-2.2 中被弃用,然后在 MPI-3.0 中被删除。

于 2013-02-28T09:43:17.720 回答