如何将 MPE 用于 MPI c++ 项目?
How to use MPE for MPI c++ project?
MPE 对于可视化 MPI 程序非常有用,但它只为 C 和 Fortran 提供编译器包装器:分别为 mpecc
和 mpef77
。如果我的 MPI 项目是用 C++ 编写的并且通常使用 mpic++
而不是 mpicc
编译(因此它不能使用 mpecc
编译),我该如何使用它?
如何设置 (1) MPE 库本身和 (2) 我的 C++ 项目?
答案其实很简单,但我苦苦思索了好几天。
下面显示的步骤适用于 Linux (Ubuntu 18) 运行 上的 MPICH 3.3.2 和 WSL2 - 在不同的环境中可能需要进行一些调整。
C++ 的 MPE 库设置
您可以正常设置 MPE 库,就像设置 C 项目一样 - 必要的步骤是:
下载并解压最新的 MPE 存档(我用过 MPE 2-1.4.9 from here)
导航到提取的目录:
cd mpe2-2.4.9b
配置库的构建过程 - 在我的例子中,以下命令有效:
./configure MPI_CC=mpicc MPI_F77=mpif77 prefix=$HOME/installs/mpe2 MPI_CFLAGS=-pthread MPI_FFLAGS=-pthread
解释:
- MPE 是用 C 编写的,所以我们使用 mpicc 来编译它 - 我们(还)没有指定如何构建我们的项目,所以我们不使用 mpic++。如果我们将
mpic++
用作 MPI_CC
,MPE 库将无法编译。
- 指定 Fortran 标志并不是绝对必要的,但这样我们就可以避免编译输出中出现不必要的错误
- prefix(安装路径)是您选择的任意路径,请记住您在此处插入的内容,因为在后续步骤中将需要它
- 我必须提供 link
pthread
库的使用年限 - 这 may/may 不是必需的,具体取决于您的系统
编译 MPE 库:
make
安装编译好的库:
make install
在 C++ 项目中使用 MPE
由于我们不能使用预定义的编译器包装器 mpecc
来编译 c++,因此我们必须手动 link 必要的库,就像我们对任何其他库所做的那样。
假设我们有一个包含以下内容的文件 main.cpp
:
#include <mpi.h>
#include <mpe.h>
/* other necessary includes */
int main(int argc, char** argv) {
MPI_Init(&argc, &argv);
MPE_Init_log();
/* some MPI and MPE stuff */
MPE_Finish_log("test");
MPI_Finalize();
}
允许使用 MPI 和 MPE 调用构建 C++ 文件的特定命令是:
mpic++ main.cpp -o main -I/$HOME/installs/mpe2/include -L/$HOME/installs/mpe2/lib -lmpe -pthread
解释:
- 我们使用
mpic++
自动 link 所有 MPI 项目
$HOME/installs/mpe2
是你配置MPE库时指定的任意安装路径
-I
标志告诉编译器在哪里寻找头文件(我们 #include
)
-L
标志告诉编译器在哪里可以找到已编译的库项(包含头文件中定义的函数的实现)
-l
标志告诉编译器实际上 link 我们的可执行文件和特定的库(这要归功于我们使用 -L
标志指定搜索位置)
- 我必须手动 link
pthread
才能使 MPE 工作,但这可能取决于您的系统
如果您使用 cmake 构建项目,则以下 CMakeLists.txt 应该有效:
cmake_minimum_required(VERSION 3.5) # not necessarily 3.5, it;s just my setup
project(mpi_test) # arbitrary project name
find_package(MPI REQUIRED)
set(CMAKE_CXX_COMPILER mpic++)
include_directories($ENV{HOME}/installs/mpe2/include) # again, it's the MPE installation path
link_directories($ENV{HOME}/installs/mpe2/lib) # again, it's the MPE installation path
add_executable(main_exp src/main_exp.cpp)
target_link_libraries(main_exp mpe pthread) # again, pthread may/may not be neccessary
MPE 对于可视化 MPI 程序非常有用,但它只为 C 和 Fortran 提供编译器包装器:分别为 mpecc
和 mpef77
。如果我的 MPI 项目是用 C++ 编写的并且通常使用 mpic++
而不是 mpicc
编译(因此它不能使用 mpecc
编译),我该如何使用它?
如何设置 (1) MPE 库本身和 (2) 我的 C++ 项目?
答案其实很简单,但我苦苦思索了好几天。
下面显示的步骤适用于 Linux (Ubuntu 18) 运行 上的 MPICH 3.3.2 和 WSL2 - 在不同的环境中可能需要进行一些调整。
C++ 的 MPE 库设置
您可以正常设置 MPE 库,就像设置 C 项目一样 - 必要的步骤是:
下载并解压最新的 MPE 存档(我用过 MPE 2-1.4.9 from here)
导航到提取的目录:
cd mpe2-2.4.9b
配置库的构建过程 - 在我的例子中,以下命令有效:
./configure MPI_CC=mpicc MPI_F77=mpif77 prefix=$HOME/installs/mpe2 MPI_CFLAGS=-pthread MPI_FFLAGS=-pthread
解释:
- MPE 是用 C 编写的,所以我们使用 mpicc 来编译它 - 我们(还)没有指定如何构建我们的项目,所以我们不使用 mpic++。如果我们将
mpic++
用作MPI_CC
,MPE 库将无法编译。 - 指定 Fortran 标志并不是绝对必要的,但这样我们就可以避免编译输出中出现不必要的错误
- prefix(安装路径)是您选择的任意路径,请记住您在此处插入的内容,因为在后续步骤中将需要它
- 我必须提供 link
pthread
库的使用年限 - 这 may/may 不是必需的,具体取决于您的系统
- MPE 是用 C 编写的,所以我们使用 mpicc 来编译它 - 我们(还)没有指定如何构建我们的项目,所以我们不使用 mpic++。如果我们将
编译 MPE 库:
make
安装编译好的库:
make install
在 C++ 项目中使用 MPE
由于我们不能使用预定义的编译器包装器 mpecc
来编译 c++,因此我们必须手动 link 必要的库,就像我们对任何其他库所做的那样。
假设我们有一个包含以下内容的文件 main.cpp
:
#include <mpi.h>
#include <mpe.h>
/* other necessary includes */
int main(int argc, char** argv) {
MPI_Init(&argc, &argv);
MPE_Init_log();
/* some MPI and MPE stuff */
MPE_Finish_log("test");
MPI_Finalize();
}
允许使用 MPI 和 MPE 调用构建 C++ 文件的特定命令是:
mpic++ main.cpp -o main -I/$HOME/installs/mpe2/include -L/$HOME/installs/mpe2/lib -lmpe -pthread
解释:
- 我们使用
mpic++
自动 link 所有 MPI 项目 $HOME/installs/mpe2
是你配置MPE库时指定的任意安装路径-I
标志告诉编译器在哪里寻找头文件(我们#include
)-L
标志告诉编译器在哪里可以找到已编译的库项(包含头文件中定义的函数的实现)-l
标志告诉编译器实际上 link 我们的可执行文件和特定的库(这要归功于我们使用-L
标志指定搜索位置)- 我必须手动 link
pthread
才能使 MPE 工作,但这可能取决于您的系统
如果您使用 cmake 构建项目,则以下 CMakeLists.txt 应该有效:
cmake_minimum_required(VERSION 3.5) # not necessarily 3.5, it;s just my setup
project(mpi_test) # arbitrary project name
find_package(MPI REQUIRED)
set(CMAKE_CXX_COMPILER mpic++)
include_directories($ENV{HOME}/installs/mpe2/include) # again, it's the MPE installation path
link_directories($ENV{HOME}/installs/mpe2/lib) # again, it's the MPE installation path
add_executable(main_exp src/main_exp.cpp)
target_link_libraries(main_exp mpe pthread) # again, pthread may/may not be neccessary