【问题标题】:boost test unit can not call mpi functionboost测试单元不能调用mpi函数
【发布时间】:2013-02-14 03:05:59
【问题描述】:

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

我编写了一个 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::InitMPI::Finalize,并且文件的其他函数不应该做任何与MPI 相关的事情。

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

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

感谢您的帮助

【问题讨论】:

  • 如果我在 BOOST_AUTO_TEST_CASE 中执行所有并行化而不是调用 parafunction ...,也会发生同样的事情

标签: c++ testing mpi boost-test


【解决方案1】:

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

int already_initialised;

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

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

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);
}

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

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

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

【讨论】:

    猜你喜欢
    • 2012-09-13
    • 1970-01-01
    • 2016-01-29
    • 1970-01-01
    • 2016-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    相关资源
    最近更新 更多