I am trying to apply openmp and mpi techniques to an open source C program which requires "cmake . && make" to be built. I already found at How to set linker flags for OpenMP in CMake's try_compile function how to include the -fopenmp flags but still confused about mpi. What can I do about that?
Asked
Active
Viewed 2.7k times
10
-
1OpenMP and MPI are two different concepts. OpenMP works with compiler directives, while MPI is merely a library to link against. However, to ease the linking there are typically compiler wrappers used, when compiling with MPI. Usually these are called mpicc or the like. Setting your CC to point to that wrapper might help. – haraldkl Apr 19 '14 at 03:26
3 Answers
22
OpenMP
Is this a question about OpenMP? Then all you have to do is compile with -fopenmp
which you can do by appending it to CMAKE_C_FLAGS
, for example:
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp)
MPI
For MPI, you have to find mpi first
find_package(MPI) #make it REQUIRED, if you want
then add it's header files to your search path
include_directories(SYSTEM ${MPI_INCLUDE_PATH})
and finally link your program(s) (which is my_mpi_target
in my case)
target_link_libraries(my_mpi_target ${MPI_C_LIBRARIES})

niklasfi
- 15,245
- 7
- 40
- 54
-
3Is this sufficient? What about `MPI_
_COMPILE_FLAGS` and `MPI_ – Zulan May 03 '16 at 16:55_LINK_FLAGS`? -
For OpenMP, if your are building a library, it was also necessary for me to add `target_link_libraries(target gomp)` – ThomasGuenet Jun 07 '18 at 14:10
19
In modern CMake 3.X which is target based, the CMakeLists.txt should look like this:
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})

Liu Hao Cheng
- 669
- 6
- 6
-
1What about `MPI_
_COMPILE/LINK_FLAGS`? also does C++ also link to C libraries? – dashesy May 10 '18 at 21:30 -
1@dashesy Yes, Modern CMake would find these variables for you(I verified it on my Ubuntu 16.04 + CMake 3.9 environment). See more variables and details in [FindMPI.cmake](https://gitlab.kitware.com/cmake/cmake/blob/master/Modules/FindMPI.cmake). That being said, it also depends on the CMake version you are using. Check the official doc for info about the version you are using. – Liu Hao Cheng May 11 '18 at 02:02
-
7In CMake 3.9 and up you can use this instead: `target_link_libraries(main PRIVATE MPI::MPI_C)`. Much nicer to use the imported target. – Levi Morrison Jul 20 '18 at 21:07
8
OpenMP and MPI together
For those who would like to use both OpenMP and MPI within a single CMake file:
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)
or even simpler:
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)
If you want to run your program directly from CLion (with a specified number of processes), check also this answer: https://stackoverflow.com/a/66992251/9723204

Hawklike
- 952
- 16
- 23
-
Please note the OP asked for 'C', not C++. But your answer helped me so +1 :) – StarShine Jul 11 '23 at 11:11