How to import OpenMP and MPI to a large CLion CMake project?
Asked Answered
V

2

6

I am new to OpenMP and MPI, and I want to import OpenMP and MPI to my existing CMake project. Therefore --

First, I created a very simple MPI project.

main.cpp:

#include "mpi.h"
#include "iostream"

int main(int argc, char** argv){
    MPI_Init(NULL, NULL);

    int world_size;
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);

    int world_rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);

    char processor_name[MPI_MAX_PROCESSOR_NAME];
    int name_len;
    MPI_Get_processor_name(processor_name, &name_len);

    printf("Hello world from processor %s, rank %d out of %d processors\n",processor_name, world_rank, world_size);

    MPI_Finalize();
}

I can successfully compile and run the project using the command:

$ mpicxx main.cpp -o main.out
$ mpirun -np 2 main.out

Then I created and configurated a CMake project using CLion. I can also successfully compile and run it using CLion, but it only used one processor.

CMakeLists.txt:

cmake_minimum_required(VERSION 3.5)
project(Test)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

find_package(MPI)
include_directories(${MPI_INCLUDE_PATH})

SET(CMAKE_CXX_COMPILER mpicxx)
SET(CMAKE_C_COMPILER  mpicc)

set(SOURCE_FILES main.cpp)
add_executable(Test ${SOURCE_FILES})

Thus my first question is how can I use multiple processors using CLion?

Second, I created a simple OpenMP project and run successfully.

But my second question is how can I include both MPI and OpenMP? It seems that I cannot just merge the two CMakeLists.txt of the MPI project and OpenMP project. Because I got an error about the -fopenmp flag:

clang: error: unsupported option '-fopenmp'

CMakeLists.txt:

cmake_minimum_required(VERSION 3.12)
project(OpenMP_MPI)

set(CMAKE_CXX_STANDARD 14)

OPTION (USE_OpenMP "Use OpenMP to enamble <omp.h>" ON)

if(APPLE)
    set(CMAKE_C_COMPILER "/usr/local/Cellar/llvm/9.0.0_1/bin/clang")
    set(CMAKE_CXX_COMPILER "/usr/local/Cellar/llvm/9.0.0_1/bin/clang++")
    set(OPENMP_LIBRARIES "/usr/local/Cellar/llvm/9.0.0_1/lib")
    set(OPENMP_INCLUDES "/usr/local/Cellar/llvm/9.0.0_1/include")
    if(CMAKE_C_COMPILER_ID MATCHES "Clang")
        set(OpenMP_C "${CMAKE_C_COMPILER}")
        set(OpenMP_C_FLAGS "-fopenmp=libomp -Wno-unused-command-line-argument")
        set(OpenMP_C_LIB_NAMES "libomp" "libgomp" "libiomp5")
        set(OpenMP_libomp_LIBRARY ${OpenMP_C_LIB_NAMES})
        set(OpenMP_libgomp_LIBRARY ${OpenMP_C_LIB_NAMES})
        set(OpenMP_libiomp5_LIBRARY ${OpenMP_C_LIB_NAMES})
    endif()
    if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
        set(OpenMP_CXX "${CMAKE_CXX_COMPILER}")
        set(OpenMP_CXX_FLAGS "-fopenmp=libomp -Wno-unused-command-line-argument")
        set(OpenMP_CXX_LIB_NAMES "libomp" "libgomp" "libiomp5")
        set(OpenMP_libomp_LIBRARY ${OpenMP_CXX_LIB_NAMES})
        set(OpenMP_libgomp_LIBRARY ${OpenMP_CXX_LIB_NAMES})
        set(OpenMP_libiomp5_LIBRARY ${OpenMP_CXX_LIB_NAMES})
    endif()
endif()

find_package(OpenMP REQUIRED)
if (OPENMP_FOUND)
    if(APPLE)
        include_directories("${OPENMP_INCLUDES}")
        link_directories("${OPENMP_LIBRARIES}")
    endif()
    set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
    # set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
endif(OPENMP_FOUND)

find_package(MPI REQUIRED)
include_directories(${MPI_INCLUDE_PATH})

SET(CMAKE_CXX_COMPILER mpicxx)
SET(CMAKE_C_COMPILER  mpicc)

add_executable(OpenMP_MPI main.cpp)
Velure answered 13/1, 2020 at 8:54 Comment(2)
I have solved the first problem. I can now compile and run my MPI project using multiple processors through mkdir build && cd build && cmake .. && make && mpirun -np 4 ./Test. And I have updated the CMakeLists.txt by adding target_link_libraries(Test ${MPI_C_LIBRARIES}), and removing SET(CMAKE_CXX_COMPILER mpicxx) and SET(CMAKE_C_COMPILER mpicc)Velure
jetbrains.com/help/clion/openmpi.html Clion has a good documentation on it now.Sepulchre
W
1

The CMakeLists.txt should not be so complicated. It should be like this:

cmake_minimum_required(VERSION 3.12)
project(OpenMP_MPI)

set(CMAKE_CXX_STANDARD 14)

find_package(MPI REQUIRED)
include_directories(SYSTEM ${MPI_INCLUDE_PATH})

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")

add_executable(OpenMP_MPI main.cpp)

target_link_libraries(OpenMP_MPI ${MPI_C_LIBRARIES})

For linux, you should use the following command to build and run.

mkdir build && cd build && cmake .. && make && mpirun -n 2 ./OpenMP_MPI

For MacOS, just change the command to

mkdir build && cd build && cmake -DCMAKE_CXX_COMPILER=g++-9 .. && make && mpirun -n 2 ./OpenMP_MPI

It should work. (You can go to /usr/local/bin to check whether your compiler is g++-9.)

Win answered 7/8, 2021 at 8:11 Comment(0)
A
2

Thus my first question is how can I use multiple processors, just like using "mpirun -np 4 xxxx" from terminal?

When you compile an MPI program, the number of processes does not affect your compilation options. So, your sample code will work on multiple processes as mentioned by yourself:

$ mpirun -np 4 xxxx

To do that in CLion, go to Run/Debug configurations, and add mpirun as your executable, and -np 4 xxxx as your program arguments, as shown here.

But there will be some errors about -fopenmp flag:

I know that compiling an openmp program on Mac using clang is not that straightforward. You may take a look at this answer for more information.

About answered 13/1, 2020 at 9:21 Comment(2)
Thanks. About the first question, I want to know how can I run the MPI program using CLion rather than terminal?Velure
About the second question, thanks for your suggestions, I can now compile the MPI+OpenMP project via terminal using the command mpicxx -Xpreprocessor -fopenmp -I/usr/local/include -L/usr/local/lib -lomp main.cpp -o main. However, I still don't know how to contain the '-Xpreprocessor' option in the CMakeLists.txt.Velure
W
1

The CMakeLists.txt should not be so complicated. It should be like this:

cmake_minimum_required(VERSION 3.12)
project(OpenMP_MPI)

set(CMAKE_CXX_STANDARD 14)

find_package(MPI REQUIRED)
include_directories(SYSTEM ${MPI_INCLUDE_PATH})

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")

add_executable(OpenMP_MPI main.cpp)

target_link_libraries(OpenMP_MPI ${MPI_C_LIBRARIES})

For linux, you should use the following command to build and run.

mkdir build && cd build && cmake .. && make && mpirun -n 2 ./OpenMP_MPI

For MacOS, just change the command to

mkdir build && cd build && cmake -DCMAKE_CXX_COMPILER=g++-9 .. && make && mpirun -n 2 ./OpenMP_MPI

It should work. (You can go to /usr/local/bin to check whether your compiler is g++-9.)

Win answered 7/8, 2021 at 8:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.