When composing the CMakeLists.txt file, we will reuse some of the building blocks we encountered in Chapter 3, Detecting External Libraries and Programs, Recipe 6, Detecting the MPI parallel environment:
- We declare a C++11 project:
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
project(recipe-09 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
- Then, we introduce an option, USE_MPI, to select MPI parallelization and set it ON by default. If it is ON, we use find_package to locate the MPI environment:
option(USE_MPI "Use MPI parallelization" ON)
if(USE_MPI)
find_package(MPI REQUIRED)
endif()
- We then define the executable target and conditionally set the corresponding library dependency (MPI::MPI_CXX) and preprocessor definition (HAVE_MPI), which we will explain in a moment:
add_executable(example example.cpp)
target_link_libraries(example
PUBLIC
$<$<BOOL:${MPI_FOUND}>:MPI::MPI_CXX>
)
target_compile_definitions(example
PRIVATE
$<$<BOOL:${MPI_FOUND}>:HAVE_MPI>
)
- If MPI is found, we also print the INTERFACE_LINK_LIBRARIES exported by FindMPI.cmake to demonstrate the very handy cmake_print_properties() function:
if(MPI_FOUND)
include(CMakePrintHelpers)
cmake_print_properties(
TARGETS MPI::MPI_CXX
PROPERTIES INTERFACE_LINK_LIBRARIES
)
endif()
- Let us first configure the code with the default MPI paralellization switched ON. Observe the output from cmake_print_properties():
$ mkdir -p build_mpi
$ cd build_mpi
$ cmake ..
-- ...
--
Properties for TARGET MPI::MPI_CXX:
MPI::MPI_CXX.INTERFACE_LINK_LIBRARIES = "-Wl,-rpath -Wl,/usr/lib/openmpi -Wl,--enable-new-dtags -pthread;/usr/lib/openmpi/libmpi_cxx.so;/usr/lib/openmpi/libmpi.so"
- We compile and run the parallel example:
$ cmake --build .
$ mpirun -np 2 ./example
hello from rank 0
hello from rank 1
- Now, let us step one directory up, create a new build directory, and this time build the sequential version:
$ mkdir -p build_seq
$ cd build_seq
$ cmake -D USE_MPI=OFF ..
$ cmake --build .
$ ./example
hello from a sequential binary