【发布时间】:2021-07-25 19:15:35
【问题描述】:
我想用Boost.Test 对一个使用Boost.MPI 的并行程序进行单元测试。这些库的官方文档没有提供有关如何执行此操作的说明(或者我找不到它们)。问题是 MPI 代码需要只完成一次的初始化和终结,Boost.MPI 封装在environment(在某种程度上在communicator)对象中,RAII 样式。所以Boost.MPI 程序通常看起来像这样:
#include <boost/mpi/environment.hpp>
#include <boost/mpi/communicator.hpp>
int main(int argc, char *argv[]) {
boost::mpi::environment env(argc, argv);
boost::mpi::communicator world{};
// ... parallel code here ...
}
但是,Boost.Test 在幕后提供了自己的 main() 函数。我可以通过定义#define BOOST_TEST_NO_MAIN 来覆盖这一点,然后自己编写main(),按照上面的草图。
但是问题开始了。如何告诉Boost.Test 在 MPI 下运行测试用例?应该像往常一样将它们定义为BOOST_AUTO_TEST_CASE(...) 宏还是有其他方法?又如何将communicator 对象(world)“传递”给测试用例?它应该设置在全局夹具中吗?如果是,那么全局固定装置如何与用户提供的main 一起工作?
我做了很多实验,用 Google 搜索了更多,但没有发现任何可用的东西。有没有人知道如何一起使用这两个 Boost 库?如果是,那么工作示例将不胜感激。谢谢。
编辑 SebastianH-s 的建议很快被拍了拍:
#define BOOST_TEST_MODULE mpitest
#define BOOST_TEST_NO_MAIN
#include <boost/mpi/environment.hpp>
#include <boost/mpi/communicator.hpp>
#include <iostream>
namespace bmpi = boost::mpi;
// Fixture
struct Fix {
Fix(): env{}, world{} {}
bmpi::environment env;
bmpi::communicator world;
};
BOOST_FIXTURE_TEST_CASE(check_mpi, Fix) {
if (world.rank() == 0) {
std::cout << "MPI thread level: " <<
bmpi::environment::thread_level() << std::endl;
}
std::cout << "I am process " << world.rank() << " of " << world.size()
<< "." << std::endl;
}
int main(int argc, char *argv[]) {
// This runs the test cases.
int retval = boost::unit_test::unit_test_main([](){ return true; }, argc, argv );
}
在 Ubuntu 下使用 g++ 9.3 和 Boost 1.71 编译。但是当我运行它时:
Running 1 test case...
*** The MPI_Comm_set_errhandler() function was called before MPI_INIT was invoked.
*** This is disallowed by the MPI standard.
*** Your MPI job will now abort.
看,这就是问题所在:MPI 未正确初始化。
【问题讨论】:
-
@SebastianH 您如何将
argc和argv放入夹具中以初始化boost::mpi::environment?我根据您的建议快速整理了一些东西(请参阅问题中的编辑),它不会按书面方式运行。欢迎具体改进。
标签: c++ unit-testing boost mpi