11

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?

1
  • 1
    OpenMP 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. Commented Apr 19, 2014 at 3:26

3 Answers 3

25

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})
Sign up to request clarification or add additional context in comments.

2 Comments

Is this sufficient? What about MPI_<lang>_COMPILE_FLAGS and MPI_<lang>_LINK_FLAGS?
For OpenMP, if your are building a library, it was also necessary for me to add target_link_libraries(target gomp)
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}) 

3 Comments

What about MPI_<lang>_COMPILE/LINK_FLAGS? also does C++ also link to C libraries?
@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. 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.
In 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.
10

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

1 Comment

Please note the OP asked for 'C', not C++. But your answer helped me so +1 :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.