# FindMPI

Finds a Message Passing Interface (MPI) implementation:

    find_package(MPI [<version>] [COMPONENTS <langs>...] [...])

The Message Passing Interface (MPI) is a library used to write high-performance distributed-memory parallel applications, and is typically deployed on a cluster. MPI is a standard interface (defined by the MPI forum) for which many implementations are available.

Added in version 3.10: Major overhaul of the module: many new variables, per-language components, and support for a wider variety of runtimes.

## Components

This module supports optional components that can be specified with the `find_package()` command to control which MPI languages to search for:

    find_package(MPI [COMPONENTS <langs>...])

Supported components include:

`C`

  Added in version 3.10.

  Finds MPI C API.

`CXX`

  Added in version 3.10.

  Finds the MPI C API that is usable from C++.

`MPICXX`

  Added in version 3.10.

  Finds the MPI-2 C++ API that was removed in MPI-3.

`Fortran`

  Added in version 3.10.

  Finds the MPI Fortran API.

If no components are specified, module searches for the `C`, `CXX`, and `Fortran` components automatically, depending on which languages are enabled in the project.

## Imported Targets

This module provides the following Imported Targets:

`MPI::MPI_<lang>`

  Added in version 3.9.

  Target encapsulating usage requirements for using MPI from language `<lang>`, available if MPI is found. The `<lang>` is a specified component name as listed above.

## Result Variables

This module defines the following variables:

`MPI_FOUND`

  Boolean indicating that MPI settings for all requested components (languages) were found. If no components are specified, this variable is set to boolean true if MPI settings for all enabled languages were detected. Note that the `MPICXX` component does not affect this variable.

`MPI_VERSION`

  Minimal version of MPI detected among the requested languages, or all enabled languages if no components were specified.

This module will set the following variables per language in CMake project, where `<lang>` is one of C, CXX, or Fortran:

`MPI_<lang>_FOUND`

  Boolean indicating the MPI settings for `<lang>` were found and that simple MPI test programs compile with the provided settings.

`MPI_<lang>_COMPILER`

  MPI compiler for `<lang>` if such a program exists.

`MPI_<lang>_COMPILE_OPTIONS`

  Compilation options for MPI programs in `<lang>`, given as a semicolon-separated list.

`MPI_<lang>_COMPILE_DEFINITIONS`

  Compilation definitions for MPI programs in `<lang>`, given as a semicolon-separated list.

`MPI_<lang>_INCLUDE_DIRS`

  Include path(s) for MPI header.

`MPI_<lang>_LINK_FLAGS`

  Linker flags for MPI programs.

`MPI_<lang>_LIBRARIES`

  All libraries to link MPI programs against.

The following variables indicating which bindings are present will be defined:

`MPI_MPICXX_FOUND`

  Boolean indicating whether the MPI-2 C++ bindings are present (introduced in MPI-2, removed with MPI-3).

`MPI_Fortran_HAVE_F77_HEADER`

  True if the Fortran 77 header `<mpif.h>` is available.

`MPI_Fortran_HAVE_F90_MODULE`

  True if the Fortran 90 module `mpi` can be used for accessing MPI (MPI-2 and higher only).

`MPI_Fortran_HAVE_F08_MODULE`

  True if the Fortran 2008 `mpi_f08` is available to MPI programs (MPI-3 and higher only).

If possible, the MPI version will be determined by this module. The facilities to detect the MPI version were introduced with MPI-1.2, and therefore cannot be found for older MPI versions.

`MPI_<lang>_VERSION`

  MPI version implemented for `<lang>` by the MPI distribution.

`MPI_<lang>_VERSION_MAJOR`

  Major version of MPI implemented for `<lang>` by the MPI distribution.

`MPI_<lang>_VERSION_MINOR`

  Minor version of MPI implemented for `<lang>` by the MPI distribution.

Note that there's no variable for the C bindings being accessible through `<mpi.h>`, since the MPI standards always have required this binding to work in both C and C++ code.

For running MPI programs, the module sets the following variables:

`MPIEXEC_EXECUTABLE`

  Executable for running MPI programs, if such exists.

`MPIEXEC_NUMPROC_FLAG`

  Flag to pass to `mpiexec` before giving it the number of processors to run on.

`MPIEXEC_MAX_NUMPROCS`

  Number of MPI processors to utilize. Defaults to the number of processors detected on the host system.

`MPIEXEC_PREFLAGS`

  Flags to pass to `mpiexec` directly before the executable to run.

`MPIEXEC_POSTFLAGS`

  Flags to pass to `mpiexec` after other flags.

## Variables for Locating MPI

This module performs a four-step search for an MPI implementation:

1. Searches for `MPIEXEC_EXECUTABLE` and, if found, uses its base directory.

2. Checks if the compiler has MPI support built-in. This is the case if the user passed a compiler wrapper as `CMAKE_<LANG>_COMPILER` or if they use Cray system compiler wrappers.

3. Attempts to find an MPI compiler wrapper and determines the compiler information from it.

4. Tries to find an MPI implementation that does not ship such a wrapper by guessing settings. Currently, only Microsoft MPI and MPICH2 on Windows are supported.

For controlling the `MPIEXEC_EXECUTABLE` step, the following variables may be set:

`MPIEXEC_EXECUTABLE`

  Manually specify the location of `mpiexec`.

`MPI_HOME`

  Specify the base directory of the MPI installation.

`ENV{MPI_HOME}`

  Environment variable to specify the base directory of the MPI installation.

`ENV{I_MPI_ROOT}`

  Environment variable to specify the base directory of the MPI installation.

For controlling the compiler wrapper step, the following variables may be set:

`MPI_<lang>_COMPILER`

  Search for the specified compiler wrapper and use it.

`MPI_<lang>_COMPILER_FLAGS`

  Flags to pass to the MPI compiler wrapper during interrogation. Some compiler wrappers support linking debug or tracing libraries if a specific flag is passed and this variable may be used to obtain them.

`MPI_COMPILER_FLAGS`

  Used to initialize `MPI_<lang>_COMPILER_FLAGS` if no language specific flag has been given. Empty by default.

`MPI_EXECUTABLE_SUFFIX`

  A suffix which is appended to all names that are being looked for. For instance, it may be set to `.mpich` or `.openmpi` to prefer the one or the other on Debian and its derivatives.

In order to control the guessing step, the following variable may be set:

`MPI_GUESS_LIBRARY_NAME`

  Valid values are `MSMPI` and `MPICH2`. If set, only the given library will be searched for. By default, `MSMPI` will be preferred over `MPICH2` if both are available. This also sets `MPI_SKIP_COMPILER_WRAPPER` variable to `true`, which may be overridden.

Each of the search steps may be skipped with the following control variables:

`MPI_ASSUME_NO_BUILTIN_MPI`

  If true, the module assumes that the compiler itself does not provide an MPI implementation and skips to step 2.

`MPI_SKIP_COMPILER_WRAPPER`

  If true, no compiler wrapper will be searched for.

`MPI_SKIP_GUESSING`

  If true, the guessing step will be skipped.

Additionally, the following control variable is available to change search behavior:

`MPI_CXX_SKIP_MPICXX`

  Add some definitions that will disable the MPI-2 C++ bindings. Currently supported are MPICH, Open MPI, Platform MPI and derivatives thereof, for example, MVAPICH or Intel MPI.

If the find procedure fails for the module's internal variable `MPI_<lang>_WORKS`, then the settings detected by or passed to the module did not work and even a simple MPI test program failed to compile.

If all of these parameters were not sufficient to find the right MPI implementation, a user may disable the entire autodetection process by specifying both a list of libraries in `MPI_<lang>_LIBRARIES` and a list of include directories in `MPI_<lang>_ADDITIONAL_INCLUDE_DIRS`. Any other variable may be set in addition to these two. The module will then validate the MPI settings and store the settings in the cache.

## Cache Variables

The variable `MPI_<lang>_INCLUDE_DIRS` will be assembled from the following variables.

For C and CXX:

`MPI_<lang>_HEADER_DIR`

  Location of the `<mpi.h>` header on disk.

For Fortran:

`MPI_Fortran_F77_HEADER_DIR`

  Location of the Fortran 77 header `<mpif.h>`, if it exists.

`MPI_Fortran_MODULE_DIR`

  Location of the `mpi` or `mpi_f08` modules, if available.

For all languages the following variables are additionally considered:

`MPI_<lang>_ADDITIONAL_INCLUDE_DIRS`

  A semicolon-separated list of paths needed in addition to the normal include directories.

`MPI_<include-name>_INCLUDE_DIR`

  Path variables for include folders referred to by `<include-name>`.

`MPI_<lang>_ADDITIONAL_INCLUDE_VARS`

  A semicolon-separated list of `<include-name>` that will be added to the include locations of `<lang>`.

The variable `MPI_<lang>_LIBRARIES` will be assembled from the following variables:

`MPI_<lib-name>_LIBRARY`

  The location of a library called `<lib-name>` for use with MPI.

`MPI_<lang>_LIB_NAMES`

  A semicolon-separated list of `<lib-name>` that will be added to the include locations of `<lang>`.

## Advanced Variables for Using MPI

The module can perform some advanced feature detections upon explicit request.

Note

The following checks cannot be performed without executing an MPI test program. Consider the special considerations for the behavior of `try_run()` during cross compilation. Moreover, running an MPI program can cause additional issues, like a firewall notification on some systems. These detections should be only enabled if information is absolutely needed.

If the following variables are set to true, the respective search will be performed:

`MPI_DETERMINE_Fortran_CAPABILITIES`

  Determine for all available Fortran bindings what the values of `MPI_SUBARRAYS_SUPPORTED` and `MPI_ASYNC_PROTECTS_NONBLOCKING` are and make their values available as `MPI_Fortran_<binding>_SUBARRAYS` and `MPI_Fortran_<binding>_ASYNCPROT`, where `<binding>` is one of `F77_HEADER`, `F90_MODULE` and `F08_MODULE`.

`MPI_DETERMINE_LIBRARY_VERSION`

  For each language, find the output of `MPI_Get_library_version` and make it available as `MPI_<lang>_LIBRARY_VERSION_STRING`. This information is usually tied to the runtime component of an MPI implementation and might differ depending on `<lang>`. Note that the return value is entirely implementation defined. This information might be used to identify the MPI vendor and for example pick the correct one of multiple third party binaries that matches the MPI vendor.

## Deprecated Variables

The following variables are provided for backward compatibility:

`MPI_COMPILER`

  Deprecated since version 2.8.5: Use the `MPI_<lang>_COMPILER` instead.

`MPI_LIBRARY`

  Deprecated since version 2.8.5: Use the `MPI_<lang>_LIBRARIES` instead.

`MPI_EXTRA_LIBRARY`

  Deprecated since version 2.8.5: Use the `MPI_<lang>_LIBRARIES` instead.

`MPI_COMPILE_FLAGS`

  Deprecated since version 2.8.5: Use `MPI_<lang>_COMPILE_OPTIONS` and `MPI_<lang>_COMPILE_DEFINITIONS` instead.

`MPI_INCLUDE_PATH`

  Deprecated since version 2.8.5: Use the `MPI_<lang>_INCLUDE_DIRS` instead.

`MPI_LINK_FLAGS`

  Deprecated since version 2.8.5: Use the `MPI_<lang>_LINK_FLAGS` instead.

`MPI_LIBRARIES`

  Deprecated since version 2.8.5: Use the `MPI_<lang>_LIBRARIES` instead.

`MPI_<lang>_COMPILE_FLAGS`

  Deprecated since version 3.10: Use the `MPI_<lang>_COMPILE_OPTIONS` and `MPI_<lang>_COMPILE_DEFINITIONS` instead.

`MPI_<lang>_INCLUDE_PATH`

  Deprecated since version 3.10: For consumption use `MPI_<lang>_INCLUDE_DIRS` and for specifying folders use `MPI_<lang>_ADDITIONAL_INCLUDE_DIRS` instead.

`MPIEXEC`

  Deprecated since version 3.10: Use `MPIEXEC_EXECUTABLE` instead.

## Examples

### Example: Basic Usage

Finding MPI and linking imported target to project target:

    find_package(MPI)
    target_link_libraries(example PRIVATE MPI::MPI_C)

### Example: Usage of mpiexec

When using `MPIEXEC_EXECUTABLE` to execute MPI applications, typically all of the `MPIEXEC_EXECUTABLE` flags should be used as follows.

In the following example, the command is executed in a process. `<executable>` should be replaced with the MPI program, and `<args>` with the arguments to pass to the MPI program.

    find_package(MPI)

    if(MPI_FOUND)
      execute_process(
        COMMAND
          ${MPIEXEC_EXECUTABLE}
          ${MPIEXEC_NUMPROC_FLAG}
          ${MPIEXEC_MAX_NUMPROCS}
          ${MPIEXEC_PREFLAGS}
          <executable>
          ${MPIEXEC_POSTFLAGS}
          <args>
      )
    endif()