开始使用 Boost.MPI 需要一个可用的 MPI 实现、一个新版本的 Boost 以及一些配置信息。
要开始使用 Boost.MPI,您首先需要一个可用的 MPI 实现。市面上有很多符合标准的 MPI 实现。Boost.MPI 应该能与任何一种实现配合使用,尽管它只在以下几种实现上进行了广泛的测试:
您可以使用以下简单的程序来测试您的实现,该程序将一个消息从一个处理器传递到另一个处理器。每个处理器都会向标准输出打印一条消息。
#include <mpi.h> #include <iostream> int main(int argc, char* argv[]) { MPI_Init(&argc, &argv); int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) { int value = 17; int result = MPI_Send(&value, 1, MPI_INT, 1, 0, MPI_COMM_WORLD); if (result == MPI_SUCCESS) std::cout << "Rank 0 OK!" << std::endl; } else if (rank == 1) { int value; int result = MPI_Recv(&value, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); if (result == MPI_SUCCESS && value == 17) std::cout << "Rank 1 OK!" << std::endl; } MPI_Finalize(); return 0; }
您应该在两个处理器上编译并运行此程序。要做到这一点,请查阅您的 MPI 实现的文档。例如,使用 OpenMPI,您可以使用 mpiCC
或 mpic++
编译器进行编译,启动 LAM/MPI 守护进程,并通过 mpirun
运行您的程序。例如,如果您的程序名为 mpi-test.cpp
,请使用以下命令:
mpiCC -o mpi-test mpi-test.cpp lamboot mpirun -np 2 ./mpi-test lamhalt
当您运行此程序时,您将看到 Rank 0 OK!
和 Rank 1 OK!
都被打印到屏幕上。但是,它们的打印顺序可能任意,甚至可能重叠。以下输出对于这个 MPI 程序是完全合法的:
Rank Rank 1 OK! 0 OK!
如果您的输出看起来与上述类似,那么您的 MPI 实现似乎能与 C++ 编译器配合使用,我们就可以继续了。
与 Boost 的其他部分一样,Boost.MPI 使用 Boost.Build 系统(版本 2)来配置和构建库二进制文件。
请参阅 Boost 的通用安装说明,了解 Unix Variants(包括 Unix、Linux 和 MacOS)或 Windows。简化的构建说明应该适用于大多数平台,但需要进行一些下面描述的具体修改。
如 Boost 安装说明中所述,从 Boost 根目录运行引导脚本(Unix Variants 为 ./bootstrap.sh
,Windows 为 bootstrap.bat
)将生成一个 `project-config.jam` 文件。您需要编辑该文件并添加以下行:
using mpi ;
或者,您可以显式提供要构建的 Boost 库列表。请参阅 `bootstrap` 脚本的 --help
选项。
首先,您需要扫描 `include/boost/mpi/config.hpp` 文件,并检查是否需要为您的 MPI 实现或偏好进行任何设置修改。
特别地,如果您计划在异构机器集上运行,您将需要注释掉 `BOOST_MPI_HOMOGENEOUS` 宏。请参阅下面的 优化 说明。
大多数 MPI 实现都需要特定的编译和链接选项。为了将这些细节对用户隐藏,大多数 MPI 实现都提供了包装器,这些包装器会默默地将这些选项传递给编译器。
根据您的 MPI 实现,可能需要一些工作来告诉 Boost 使用哪些特定的 MPI 选项。这通过 `project-config.jam` 文件中的 `using mpi ;` 指令来完成,其一般形式是(不要忘记在冒号 `:` 两侧以及分号 `;` 前留有空格):
using mpi : [<MPI compiler wrapper>] : [<compilation and link options>] : [<mpi runner>] ;
根据您的安装和 MPI 发行版,构建系统可能能够找到所有必要的信息,您只需要指定:
using mpi ;
大多数情况下,特别是在生产 HPC 集群上,需要做一些工作。
以下是最常见问题的列表以及如何解决它们的建议。
您需要通过第一个参数告诉构建系统如何调用它
using mpi : /opt/mpi/bullxmpi/1.2.8.3/bin/mpicc ;
![]() |
警告 |
---|---|
Boost.MPI 只使用 C 接口,因此指定 C 包装器应该足够了。但是,有些实现会坚持导入 C++ 绑定。 |
对于某些实现,或者某些特定的集成[9],您需要通过第二个参数使用 `jam` 指令提供编译和链接选项。以下类型配置曾经是某些特定 Intel MPI 实现所必需的(在这种情况下,包装器的名称可以留空):
using mpi : mpiicc : <library-path>/softs/intel/impi/5.0.1.035/intel64/lib <library-path>/softs/intel/impi/5.0.1.035/intel64/lib/release_mt <include>/softs/intel/impi/5.0.1.035/intel64/include <find-shared-library>mpifort <find-shared-library>mpi_mt <find-shared-library>mpigi <find-shared-library>dl <find-shared-library>rt ;
为了方便起见,MPI 包装器通常有一个提供所需信息的选项,该选项通常以 `--show` 开头。您可以使用这些选项来找出所需的 jam 指令。
$ mpiicc -show icc -I/softs/.../include ... -L/softs/.../lib ... -Xlinker -rpath -Xlinker /softs/.../lib .... -lmpi -ldl -lrt -lpthread $
$ mpicc --showme icc -I/opt/.../include -pthread -L/opt/.../lib -lmpi -ldl -lm -lnuma -Wl,--export-dynamic -lrt -lnsl -lutil -lm -ldl $ mpicc --showme:compile -I/opt/mpi/bullxmpi/1.2.8.3/include -pthread $ mpicc --showme:link -pthread -L/opt/.../lib -lmpi -ldl -lm -lnuma -Wl,--export-dynamic -lrt -lnsl -lutil -lm -ldl $
要查看 MPI 自动检测的结果,请在 bjam 命令行上传递 `--debug-configuration`。
![]() |
注意 |
---|---|
这仅在 运行测试 时使用。 |
如果您需要使用特殊命令来启动 MPI 程序,则需要通过 `using mpi` 指令的第三个参数进行指定。
因此,假设您使用以下方式启动 `all_gather_test` 程序:
$mpiexec.hydra -np 4 all_gather_test
该指令将如下所示:
using mpi : mpiicc : [<compilation and link options>] : mpiexec.hydra -n ;
构建整个 Boost 发行版
$cd <boost distribution> $./b2
构建 Boost.MPI 库及其依赖项
$cd <boost distribution>/lib/mpi/build $../../../b2
要构建基于 Boost.MPI 的应用程序,请像往常一样为 MPI 程序编译和链接它们,但请记住链接 `boost_mpi` 和 `boost_serialization` 库,例如:
mpic++ -I/path/to/boost/mpi my_application.cpp -Llibdir \ -lboost_mpi -lboost_serialization
如果您计划将 Boost.MPI 的 Python 绑定与 C++ Boost.MPI 结合使用,您还需要链接 `boost_mpi_python` 库,例如,通过将 `-lboost_mpi_python-gcc` 添加到您的链接命令中。只有当您打算在 Python 中 注册 C++ 类型或使用 骨架/内容机制 时,才需要此步骤。