Using CMake, Microsoft MPI and Visual Studio 2017

2019-09-19 09:22发布

问题:

This question already has an answer here:

  • How to compile an MPI included c program using cmake 2 answers

I am trying to find/develop a very simple example of how to use CMake with Microsoft MPI with Visual Studio. I have CMake working well and generally understand it how to create CMake projects. I also have MS MPI working with Visual Studio and have confirmed I can create an MPI project following this example: https://blogs.technet.microsoft.com/windowshpc/2015/02/02/how-to-compile-and-run-a-simple-ms-mpi-program/

I just have not been able to get them working together. Specifically, I am looking for the CMake commands to put into my CMakeLists.txt file that enables MS MPI builds in Visual Studio 17. I created a CMake project (found here: https://github.com/PSUCompBio/cmake-visualstudio-msmpi) that compiles and runs fine without the inclusion of:

#include "mpi.h"

The steps I take to build the project are: 1. use the Cmake-GUI application to configure and generate the makefile 2. Use the open project button in the CMake-GUI to launch Visual Studio 2017. 3. Set the HelloWorld solution as the startup project. 4. Build (Got to top menu bar, then Build->Build Solution)

However, with the mpi.h included:

#include <stdio.h>

#include "mpi.h"

int main()
{
   // printf() displays the string inside quotation
   printf("Hello, World!!\n");
   return 0;
}

the mpi.h is not found:
visual studio error from build

My top level CmakeLists.txt file is pretty simple and does find MSMPI fine:

cmake_minimum_required(VERSION 3.0)
PROJECT (hellocmake)
ADD_SUBDIRECTORY (src)
option(ENABLE_MPI "Enable MPI parallelization" OFF)
if(ENABLE_MPI)
    if(WIN32)
        find_package(MPI REQUIRED)
        if(MPI_FOUND)
            message("Using MPI")
        endif(MPI_FOUND)
    endif(WIN32)
endif(ENABLE_MPI)

And the structure of my project is:

-CMakeLists.txt
-src
----test.cpp
----CMakeLists.txt

My primary question is why is the mpi.h not being found? I can see that the MS MPI include directory is located by CMake-GUI (see following image): CMake-GUI configure showing MS MPI include path

Is there another CMake command I need to place in my top level CMakeLists.txt file?

Below I show a portion of the CMakeCache.txt that deals with MPI options:

//Enable MPI parallelization
ENABLE_MPI:BOOL=ON

//Executable for running MPI programs.
MPIEXEC_EXECUTABLE:FILEPATH=C:/Program Files/Microsoft MPI/Bin/mpiexec.exe

//Maximum number of processors available to run MPI applications.
MPIEXEC_MAX_NUMPROCS:STRING=2

//Flag used by MPI to specify the number of processes for mpiexec;
// the next option will be the number of processes.
MPIEXEC_NUMPROC_FLAG:STRING=-n

//These flags will be placed after all flags passed to mpiexec.
MPIEXEC_POSTFLAGS:STRING=

//These flags will be directly before the executable that is being
// run by mpiexec.
MPIEXEC_PREFLAGS:STRING=

//MPI CXX additional include directories
MPI_CXX_ADDITIONAL_INCLUDE_DIRS:STRING=

//MPI compiler for CXX
MPI_CXX_COMPILER:FILEPATH=MPI_CXX_COMPILER-NOTFOUND

//MPI CXX compilation definitions
MPI_CXX_COMPILE_DEFINITIONS:STRING=

//MPI CXX compilation flags
MPI_CXX_COMPILE_OPTIONS:STRING=

//Path to a file.
MPI_CXX_HEADER_DIR:PATH=C:/Program Files (x86)/Microsoft SDKs/MPI/Include

//MPI CXX libraries to link against
MPI_CXX_LIB_NAMES:STRING=msmpi

//MPI CXX linker flags
MPI_CXX_LINK_FLAGS:STRING=

//If true, the MPI-2 C++ bindings are disabled using definitions.
MPI_CXX_SKIP_MPICXX:BOOL=OFF

//MPI C additional include directories
MPI_C_ADDITIONAL_INCLUDE_DIRS:STRING=

//MPI compiler for C
MPI_C_COMPILER:FILEPATH=MPI_C_COMPILER-NOTFOUND

//MPI C compilation definitions
MPI_C_COMPILE_DEFINITIONS:STRING=

//MPI C compilation flags
MPI_C_COMPILE_OPTIONS:STRING=

//Path to a file.
MPI_C_HEADER_DIR:PATH=C:/Program Files (x86)/Microsoft SDKs/MPI/Include

//MPI C libraries to link against
MPI_C_LIB_NAMES:STRING=msmpi

//MPI C linker flags
MPI_C_LINK_FLAGS:STRING=

//Location of the msmpi library for Microsoft MPI
MPI_msmpi_LIBRARY:FILEPATH=C:/Program Files (x86)/Microsoft SDKs/MPI/Lib/x86/msmpi.lib

//Value Computed by CMake
hellocmake_BINARY_DIR:STATIC=C:/Users/rhk12/code/cmake-visualstudio-msmpi/build

//Value Computed by CMake
hellocmake_SOURCE_DIR:STATIC=C:/Users/rhk12/code/cmake-visualstudio-msmpi

Thank you for any suggestions you might have.

回答1:

I was able to get this working by using the following CMakeLists.txt.

In top-level directory, CMakeLists.txt

cmake_minimum_required(VERSION 3.0)

PROJECT (hellocmake)

option(ENABLE_MPI "Enable MPI parallelization" OFF)

if(ENABLE_MPI)
    find_package(MPI REQUIRED)
    include_directories(${MPI_INCLUDE_PATH})
    set(CMAKE_C_FLAGS "${CMAKE_FLAGS} ${MPI_FLAGS}")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MPI_CXX_FLAGS}")
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MPI_EXE_LINKER_FLAGS}")
endif(ENABLE_MPI)

ADD_SUBDIRECTORY (src)

Then in the src directory CMakeLists.txt

ADD_EXECUTABLE(hellocmake test.cpp)

if(ENABLE_MPI)
    target_link_libraries(hellocmake ${MPI_LIBRARIES})
endif(ENABLE_MPI)

Once I did this I went back to CMake-GUI and configured and generated Makefile, then selected open project which opened Visual Studio. When I build and run I get this:

Hello, World!!
Hello world from processor MNE-REKR02.engr.psu.edu, rank 0 out of 1 processors

C:\Users\rhk12\code\cmake-visualstudio-msmpi\build\src\Debug\hellocmake.exe (process 18728) exited with code 0.
Press any key to close this window . . .

I am not sure how to specify the number of processors in visual studio. The CMake configuration found 2, but that is a different question.