【问题标题】:How to compile an MPI included c program using cmake如何使用 cmake 编译包含 MPI 的 c 程序
【发布时间】:2014-06-03 11:48:10
【问题描述】:

我正在尝试将 openmp 和 mpi 技术应用于需要构建“cmake . && make”的开源 C 程序。我已经在How to set linker flags for OpenMP in CMake's try_compile function 找到了如何包含 -fopenmp 标志但仍然对 mpi 感到困惑。我该怎么办?

【问题讨论】:

  • OpenMP 和 MPI 是两个不同的概念。 OpenMP 与编译器指令一起工作,而 MPI 只是一个链接库。但是,为了简化链接,在使用 MPI 进行编译时,通常会使用编译器包装器。通常这些被称为 mpicc 等。将您的 CC 设置为指向该包装器可能会有所帮助。

标签: c cmake mpi


【解决方案1】:

OpenMP

这是关于 OpenMP 的问题吗?然后你所要做的就是用-fopenmp 编译,你可以通过将它附加到CMAKE_C_FLAGS 来完成,例如:

SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp)

MPI

对于MPI,必须先找到mpi

find_package(MPI) #make it REQUIRED, if you want

然后将其头文件添加到您的搜索路径

include_directories(SYSTEM ${MPI_INCLUDE_PATH})

最后链接你的程序(在我的例子中是my_mpi_target)

 target_link_libraries(my_mpi_target ${MPI_C_LIBRARIES})

【讨论】:

  • 这就够了吗? MPI_<lang>_COMPILE_FLAGS 和 MPI_<lang>_LINK_FLAGS 呢?
  • 对于OpenMP,如果你正在构建一个库,我也需要添加target_link_libraries(target gomp)
【解决方案2】:

在基于目标的现代 CMake 3.X 中,CMakeLists.txt 应如下所示:

cmake_minimum_required(VERSION 3.0)

project(main)

find_package(MPI REQUIRED)
# add this line only when you are using openmpi which has a different c++ bindings
add_definitions(-DOMPI_SKIP_MPICXX)

# Use imported targets would make things much eazier. Thanks Levi for pointing it out.
add_executable(main main.cpp)
target_link_libraries(main
  PRIVATE
  MPI_C)

# Old way.
#target_link_libraries(main
# PRIVATE
# ${MPI_C_LIBRARIES})

#target_include_directories(main
# PRIVATE
# ${MPI_C_INCLUDE_PATH}) 

【讨论】:

  • MPI_<lang>_COMPILE/LINK_FLAGS 怎么样? C++ 是否也链接到 C 库?
  • @dashesy 是的,Modern CMake 会为你找到这些变量(我在我的 Ubuntu 16.04 + CMake 3.9 环境中验证了它)。在FindMPI.cmake 中查看更多变量和详细信息。话虽如此,它还取决于您使用的 CMake 版本。查看官方文档以获取有关您正在使用的版本的信息。
  • 在 CMake 3.9 及更高版本中,您可以改用它:target_link_libraries(main PRIVATE MPI::MPI_C)。使用导入的目标要好得多。
【解决方案3】:

OpenMP 和 MPI 一起使用

对于希望在单个 CMake 文件中同时使用 OpenMP 和 MPI 的用户:

cmake_minimum_required(VERSION 3.9.1)
project(parallel_task)

set(CMAKE_CXX_STANDARD 14)
set(GCC_COVERAGE_COMPILE_FLAGS "-Wall -pedantic -lm -O3 -funroll-loops")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}")

add_executable(parallel_task example.cpp example.h)

# OpenMP
find_package(OpenMP)
if(OpenMP_CXX_FOUND)
    target_link_libraries(parallel_task PUBLIC OpenMP::OpenMP_CXX)
endif()

# MPI
find_package(MPI REQUIRED)
target_link_libraries(parallel_task PUBLIC MPI::MPI_CXX)

甚至更简单:

cmake_minimum_required(VERSION 3.9.1)
project(parallel_task)

set(CMAKE_CXX_STANDARD 14)

# -fopenmp flag (enables OpenMP)
set(GCC_COVERAGE_COMPILE_FLAGS "-Wall -pedantic -lm -O3 -funroll-loops -fopenmp")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}")

add_executable(parallel_task example.cpp example.h)

# MPI
find_package(MPI REQUIRED)
target_link_libraries(parallel_task PUBLIC MPI::MPI_CXX)

如果您想直接从 CLion 运行您的程序(具有指定数量的进程),请查看此答案:https://stackoverflow.com/a/66992251/9723204

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-23
    • 2016-10-30
    • 1970-01-01
    • 1970-01-01
    • 2012-03-07
    • 2021-12-23
    • 1970-01-01
    • 2014-11-15
    相关资源
    最近更新 更多