diff --git a/cmake/FindMPI.cmake b/cmake/FindMPI.cmake
index b1bcb97..2244878 100644
--- a/cmake/FindMPI.cmake
+++ b/cmake/FindMPI.cmake
@@ -4,7 +4,7 @@
#------------------------------------------------------------------------------#
# This module is already included in new versions of CMake
-if(CMAKE_VERSION VERSION_LESS 4.0)
+if(CMAKE_VERSION VERSION_LESS 3.15.1)
include(${CMAKE_CURRENT_LIST_DIR}/upstream/FindMPI.cmake)
else()
include(${CMAKE_ROOT}/Modules/FindMPI.cmake)
diff --git a/cmake/upstream/FindMPI.cmake b/cmake/upstream/FindMPI.cmake
index 6a874b3..8551821 100644
--- a/cmake/upstream/FindMPI.cmake
+++ b/cmake/upstream/FindMPI.cmake
@@ -1,252 +1,263 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
-#.rst:
-# FindMPI
-# -------
-#
-# Find a Message Passing Interface (MPI) implementation.
-#
-# 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.
-#
-# Variables for using MPI
-# ^^^^^^^^^^^^^^^^^^^^^^^
-#
-# The module exposes the components ``C``, ``CXX``, ``MPICXX`` and ``Fortran``.
-# Each of these controls the various MPI languages to search for.
-# The difference between ``CXX`` and ``MPICXX`` is that ``CXX`` refers to the
-# MPI C API being usable from C++, whereas ``MPICXX`` refers to the MPI-2 C++ API
-# that was removed again in MPI-3.
-#
-# Depending on the enabled components the following variables will be set:
-#
-# ``MPI_FOUND``
-# Variable indicating that MPI settings for all requested languages have been found.
-# If no components are specified, this is 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 your
-# project, where ``<lang>`` is one of C, CXX, or Fortran:
-#
-# ``MPI_<lang>_FOUND``
-# Variable 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 :ref:`;-list <CMake Language Lists>`.
-# ``MPI_<lang>_COMPILE_DEFINITIONS``
-# Compilation definitions for MPI programs in ``<lang>``, given as a :ref:`;-list <CMake Language Lists>`.
-# ``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.
-#
-# Additionally, the following :prop_tgt:`IMPORTED` targets are defined:
-#
-# ``MPI::MPI_<lang>``
-# Target for using MPI from ``<lang>``.
-#
-# The following variables indicating which bindings are present will be defined:
-#
-# ``MPI_MPICXX_FOUND``
-# Variable 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_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.
-# ``MPI_<lang>_VERSION``
-# MPI version 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 three step search for an MPI implementation:
-#
-# 1. Check 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're on a Cray system.
-# 2. Attempt to find an MPI compiler wrapper and determine the compiler information from it.
-# 3. Try 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 second 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 you may set this
-# 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`` 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 a 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 for MPI
-# ^^^^^^^^^^^^^^^^^^^^^^^
-#
-# 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 :ref:`;-list <CMake Language Lists>` 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 :ref:`;-list <CMake Language Lists>` 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 :ref:`;-list <CMake Language Lists>` of ``<lib_name>`` that will be added to the include locations of ``<lang>``.
-#
-# Usage of mpiexec
-# ^^^^^^^^^^^^^^^^
-#
-# When using ``MPIEXEC_EXECUTABLE`` to execute MPI applications, you should typically
-# use all of the ``MPIEXEC_EXECUTABLE`` flags as follows:
-#
-# ::
-#
-# ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS}
-# ${MPIEXEC_PREFLAGS} EXECUTABLE ${MPIEXEC_POSTFLAGS} ARGS
-#
-# where ``EXECUTABLE`` is the MPI program, and ``ARGS`` are the arguments to
-# pass to the MPI program.
-#
-# Advanced variables for using MPI
-# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-#
-# The module can perform some advanced feature detections upon explicit request.
-#
-# **Important notice:** The following checks cannot be performed without *executing* an MPI test program.
-# Consider the special considerations for the behavior of :command:`try_run` during cross compilation.
-# Moreover, running an MPI program can cause additional issues, like a firewall notification on some systems.
-# You should only enable these detections if you absolutely need the information.
-#
-# 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``.
-# 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.
-#
-# Backward Compatibility
-# ^^^^^^^^^^^^^^^^^^^^^^
-#
-# For backward compatibility with older versions of FindMPI, these
-# variables are set, but deprecated:
-#
-# ::
-#
-# MPI_COMPILER MPI_LIBRARY MPI_EXTRA_LIBRARY
-# MPI_COMPILE_FLAGS MPI_INCLUDE_PATH MPI_LINK_FLAGS
-# MPI_LIBRARIES
-#
-# In new projects, please use the ``MPI_<lang>_XXX`` equivalents.
-# Additionally, the following variables are deprecated:
-#
-# ``MPI_<lang>_COMPILE_FLAGS``
-# Use ``MPI_<lang>_COMPILE_OPTIONS`` and ``MPI_<lang>_COMPILE_DEFINITIONS`` instead.
-# ``MPI_<lang>_INCLUDE_PATH``
-# For consumption use ``MPI_<lang>_INCLUDE_DIRS`` and for specifying folders use ``MPI_<lang>_ADDITIONAL_INCLUDE_DIRS`` instead.
-# ``MPIEXEC``
-# Use ``MPIEXEC_EXECUTABLE`` instead.
+#[=======================================================================[.rst:
+FindMPI
+-------
+
+Find a Message Passing Interface (MPI) implementation.
+
+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.
+
+Variables for using MPI
+^^^^^^^^^^^^^^^^^^^^^^^
+
+The module exposes the components ``C``, ``CXX``, ``MPICXX`` and ``Fortran``.
+Each of these controls the various MPI languages to search for.
+The difference between ``CXX`` and ``MPICXX`` is that ``CXX`` refers to the
+MPI C API being usable from C++, whereas ``MPICXX`` refers to the MPI-2 C++ API
+that was removed again in MPI-3.
+
+Depending on the enabled components the following variables will be set:
+
+``MPI_FOUND``
+ Variable indicating that MPI settings for all requested languages have been found.
+ If no components are specified, this is 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 your
+project, where ``<lang>`` is one of C, CXX, or Fortran:
+
+``MPI_<lang>_FOUND``
+ Variable 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 :ref:`;-list <CMake Language Lists>`.
+``MPI_<lang>_COMPILE_DEFINITIONS``
+ Compilation definitions for MPI programs in ``<lang>``, given as a :ref:`;-list <CMake Language Lists>`.
+``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.
+
+Additionally, the following :prop_tgt:`IMPORTED` targets are defined:
+
+``MPI::MPI_<lang>``
+ Target for using MPI from ``<lang>``.
+
+The following variables indicating which bindings are present will be defined:
+
+``MPI_MPICXX_FOUND``
+ Variable 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_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.
+``MPI_<lang>_VERSION``
+ MPI version 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 three step search for an MPI implementation:
+
+1. Check 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're on a Cray system.
+2. Attempt to find an MPI compiler wrapper and determine the compiler information from it.
+3. Try 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 second 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 you may set this
+ 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`` 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 a 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 for MPI
+^^^^^^^^^^^^^^^^^^^^^^^
+
+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 :ref:`;-list <CMake Language Lists>` 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 :ref:`;-list <CMake Language Lists>` 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 :ref:`;-list <CMake Language Lists>` of ``<lib_name>`` that will be added to the include locations of ``<lang>``.
+
+Usage of mpiexec
+^^^^^^^^^^^^^^^^
+
+When using ``MPIEXEC_EXECUTABLE`` to execute MPI applications, you should typically
+use all of the ``MPIEXEC_EXECUTABLE`` flags as follows:
+
+::
+
+ ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS}
+ ${MPIEXEC_PREFLAGS} EXECUTABLE ${MPIEXEC_POSTFLAGS} ARGS
+
+where ``EXECUTABLE`` is the MPI program, and ``ARGS`` are the arguments to
+pass to the MPI program.
+
+Advanced variables for using MPI
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The module can perform some advanced feature detections upon explicit request.
+
+**Important notice:** The following checks cannot be performed without *executing* an MPI test program.
+Consider the special considerations for the behavior of :command:`try_run` during cross compilation.
+Moreover, running an MPI program can cause additional issues, like a firewall notification on some systems.
+You should only enable these detections if you absolutely need the information.
+
+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.
+
+Backward Compatibility
+^^^^^^^^^^^^^^^^^^^^^^
+
+For backward compatibility with older versions of FindMPI, these
+variables are set, but deprecated:
+
+::
+
+ MPI_COMPILER MPI_LIBRARY MPI_EXTRA_LIBRARY
+ MPI_COMPILE_FLAGS MPI_INCLUDE_PATH MPI_LINK_FLAGS
+ MPI_LIBRARIES
+
+In new projects, please use the ``MPI_<lang>_XXX`` equivalents.
+Additionally, the following variables are deprecated:
+
+``MPI_<lang>_COMPILE_FLAGS``
+ Use ``MPI_<lang>_COMPILE_OPTIONS`` and ``MPI_<lang>_COMPILE_DEFINITIONS`` instead.
+``MPI_<lang>_INCLUDE_PATH``
+ For consumption use ``MPI_<lang>_INCLUDE_DIRS`` and for specifying folders use ``MPI_<lang>_ADDITIONAL_INCLUDE_DIRS`` instead.
+``MPIEXEC``
+ Use ``MPIEXEC_EXECUTABLE`` instead.
+#]=======================================================================]
cmake_policy(PUSH)
cmake_policy(SET CMP0057 NEW) # if IN_LIST
-include(FindPackageHandleStandardArgs)
+include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
+
+if(CMAKE_VERISON VERSION_LESS 3.9)
+ if(WIN32)
+ set(_sep_args_type WINDOWS_COMMAND)
+ else()
+ set(_sep_args_type UNIX_COMMAND)
+ endif()
+else()
+ set(_sep_args_type NATIVE_COMMAND)
+endif()
# Generic compiler names
set(_MPI_C_GENERIC_COMPILER_NAMES mpicc mpcc mpicc_r mpcc_r)
@@ -331,16 +342,10 @@ endforeach()
unset(_MPIEXEC_NAMES_BASE)
function (_MPI_check_compiler LANG QUERY_FLAG OUTPUT_VARIABLE RESULT_VARIABLE)
- # Helper variable for command seperation
- if(WIN32)
- set(_MPI_COMMAND_TYPE WINDOWS_COMMAND)
- else()
- set(_MPI_COMMAND_TYPE UNIX_COMMAND)
- endif()
if(DEFINED MPI_${LANG}_COMPILER_FLAGS)
- separate_arguments(_MPI_COMPILER_WRAPPER_OPTIONS ${_MPI_COMMAND_TYPE} "${MPI_${LANG}_COMPILER_FLAGS}")
+ separate_arguments(_MPI_COMPILER_WRAPPER_OPTIONS ${_sep_args_type} "${MPI_${LANG}_COMPILER_FLAGS}")
else()
- separate_arguments(_MPI_COMPILER_WRAPPER_OPTIONS ${_MPI_COMMAND_TYPE} "${MPI_COMPILER_FLAGS}")
+ separate_arguments(_MPI_COMPILER_WRAPPER_OPTIONS ${_sep_args_type} "${MPI_COMPILER_FLAGS}")
endif()
execute_process(
COMMAND ${MPI_${LANG}_COMPILER} ${_MPI_COMPILER_WRAPPER_OPTIONS} ${QUERY_FLAG}
@@ -628,7 +633,7 @@ function (_MPI_interrogate_compiler LANG)
if (NOT MPI_ALL_INCLUDE_PATHS)
_MPI_check_compiler(${LANG} "-showme:incdirs" MPI_INCDIRS_CMDLINE MPI_INCDIRS_COMPILER_RETURN)
if(MPI_INCDIRS_COMPILER_RETURN)
- separate_arguments(MPI_ALL_INCLUDE_PATHS NATIVE_COMMAND "${MPI_INCDIRS_CMDLINE}")
+ separate_arguments(MPI_ALL_INCLUDE_PATHS ${_sep_args_type} "${MPI_INCDIRS_CMDLINE}")
endif()
endif()
@@ -696,7 +701,7 @@ function (_MPI_interrogate_compiler LANG)
if (NOT MPI_ALL_LINK_PATHS)
_MPI_check_compiler(${LANG} "-showme:libdirs" MPI_LIBDIRS_CMDLINE MPI_LIBDIRS_COMPILER_RETURN)
if(MPI_LIBDIRS_COMPILER_RETURN)
- separate_arguments(MPI_ALL_LINK_PATHS NATIVE_COMMAND "${MPI_LIBDIRS_CMDLINE}")
+ separate_arguments(MPI_ALL_LINK_PATHS ${_sep_args_type} "${MPI_LIBDIRS_CMDLINE}")
endif()
endif()
@@ -775,18 +780,20 @@ function (_MPI_interrogate_compiler LANG)
endforeach()
# Add the link directories given explicitly that we haven't used back as linker directories.
- foreach(_MPI_LINK_DIRECTORY IN LISTS MPI_LINK_DIRECTORIES_LEFTOVER)
- file(TO_NATIVE_PATH "${_MPI_LINK_DIRECTORY}" _MPI_LINK_DIRECTORY_ACTUAL)
- string(FIND "${_MPI_LINK_DIRECTORY_ACTUAL}" " " _MPI_LINK_DIRECTORY_CONTAINS_SPACE)
- if(NOT _MPI_LINK_DIRECTORY_CONTAINS_SPACE EQUAL -1)
- set(_MPI_LINK_DIRECTORY_ACTUAL "\"${_MPI_LINK_DIRECTORY_ACTUAL}\"")
- endif()
- if(MPI_LINK_FLAGS_WORK)
- string(APPEND MPI_LINK_FLAGS_WORK " ${CMAKE_LIBRARY_PATH_FLAG}${_MPI_LINK_DIRECTORY_ACTUAL}")
- else()
- set(MPI_LINK_FLAGS_WORK "${CMAKE_LIBRARY_PATH_FLAG}${_MPI_LINK_DIRECTORY_ACTUAL}")
- endif()
- endforeach()
+ if(NOT WIN32)
+ foreach(_MPI_LINK_DIRECTORY IN LISTS MPI_LINK_DIRECTORIES_LEFTOVER)
+ file(TO_NATIVE_PATH "${_MPI_LINK_DIRECTORY}" _MPI_LINK_DIRECTORY_ACTUAL)
+ string(FIND "${_MPI_LINK_DIRECTORY_ACTUAL}" " " _MPI_LINK_DIRECTORY_CONTAINS_SPACE)
+ if(NOT _MPI_LINK_DIRECTORY_CONTAINS_SPACE EQUAL -1)
+ set(_MPI_LINK_DIRECTORY_ACTUAL "\"${_MPI_LINK_DIRECTORY_ACTUAL}\"")
+ endif()
+ if(MPI_LINK_FLAGS_WORK)
+ string(APPEND MPI_LINK_FLAGS_WORK " ${CMAKE_LIBRARY_PATH_FLAG}${_MPI_LINK_DIRECTORY_ACTUAL}")
+ else()
+ set(MPI_LINK_FLAGS_WORK "${CMAKE_LIBRARY_PATH_FLAG}${_MPI_LINK_DIRECTORY_ACTUAL}")
+ endif()
+ endforeach()
+ endif()
# Deal with the libraries given with full path next
unset(MPI_DIRECT_LIB_NAMES_WORK)
@@ -1137,23 +1144,29 @@ macro(_MPI_create_imported_target LANG)
add_library(MPI::MPI_${LANG} INTERFACE IMPORTED)
endif()
- set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_COMPILE_OPTIONS "${MPI_${LANG}_COMPILE_OPTIONS}")
+ if(NOT CMAKE_VERSION VERSION_LESS 3.12)
+ # When this is consumed for compiling CUDA, use '-Xcompiler' to wrap '-pthread'.
+ string(REPLACE "-pthread" "$<$<COMPILE_LANGUAGE:CUDA>:SHELL:-Xcompiler >-pthread"
+ _MPI_${LANG}_COMPILE_OPTIONS "${MPI_${LANG}_COMPILE_OPTIONS}")
+ endif()
+ set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_COMPILE_OPTIONS "${_MPI_${LANG}_COMPILE_OPTIONS}")
+ unset(_MPI_${LANG}_COMPILE_OPTIONS)
+
set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_COMPILE_DEFINITIONS "${MPI_${LANG}_COMPILE_DEFINITIONS}")
- set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_LINK_LIBRARIES "")
if(MPI_${LANG}_LINK_FLAGS)
- set_property(TARGET MPI::MPI_${LANG} APPEND PROPERTY INTERFACE_LINK_LIBRARIES "${MPI_${LANG}_LINK_FLAGS}")
+ set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_LINK_OPTIONS "SHELL:${MPI_${LANG}_LINK_FLAGS}")
endif()
# If the compiler links MPI implicitly, no libraries will be found as they're contained within
# CMAKE_<LANG>_IMPLICIT_LINK_LIBRARIES already.
if(MPI_${LANG}_LIBRARIES)
- set_property(TARGET MPI::MPI_${LANG} APPEND PROPERTY INTERFACE_LINK_LIBRARIES "${MPI_${LANG}_LIBRARIES}")
+ set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_LINK_LIBRARIES "${MPI_${LANG}_LIBRARIES}")
endif()
# Given the new design of FindMPI, INCLUDE_DIRS will always be located, even under implicit linking.
set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${MPI_${LANG}_INCLUDE_DIRS}")
endmacro()
-function(_MPI_try_staged_settings LANG MPI_TEST_FILE_NAME MODE RUN_BINARY)
+function(_MPI_try_staged_settings LANG MPI_TEST_FILE_NAME MODE RUN_BINARY SUPPRESS_ERRORS)
set(WORK_DIR "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindMPI")
set(SRC_DIR "${CMAKE_CURRENT_LIST_DIR}/FindMPI")
set(BIN_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindMPI/${MPI_TEST_FILE_NAME}_${LANG}.bin")
@@ -1182,18 +1195,29 @@ function(_MPI_try_staged_settings LANG MPI_TEST_FILE_NAME MODE RUN_BINARY)
"${CMAKE_BINARY_DIR}" SOURCES "${MPI_TEST_SOURCE_FILE}"
COMPILE_DEFINITIONS ${MPI_TEST_COMPILE_DEFINITIONS}
LINK_LIBRARIES MPI::MPI_${LANG}
- RUN_OUTPUT_VARIABLE MPI_RUN_OUTPUT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE})
+ RUN_OUTPUT_VARIABLE MPI_RUN_OUTPUT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE}
+ COMPILE_OUTPUT_VARIABLE _MPI_TRY_${MPI_TEST_FILE_NAME}_${MODE}_OUTPUT)
set(MPI_RUN_OUTPUT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE} "${MPI_RUN_OUTPUT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE}}" PARENT_SCOPE)
else()
try_compile(MPI_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE}
"${CMAKE_BINARY_DIR}" SOURCES "${MPI_TEST_SOURCE_FILE}"
COMPILE_DEFINITIONS ${MPI_TEST_COMPILE_DEFINITIONS}
LINK_LIBRARIES MPI::MPI_${LANG}
- COPY_FILE "${BIN_FILE}")
+ COPY_FILE "${BIN_FILE}"
+ OUTPUT_VARIABLE _MPI_TRY_${MPI_TEST_FILE_NAME}_${MODE}_OUTPUT)
+ endif()
+ if(NOT SUPPRESS_ERRORS)
+ if(NOT MPI_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE})
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "The MPI test ${MPI_TEST_FILE_NAME} for ${LANG} in mode ${MODE} failed to compile with the following output:\n${_MPI_TRY_${MPI_TEST_FILE_NAME}_${MODE}_OUTPUT}\n\n")
+ elseif(DEFINED MPI_RUN_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE} AND MPI_RUN_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE})
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "The MPI test ${MPI_TEST_FILE_NAME} for ${LANG} in mode ${MODE} failed to run with the following output:\n${MPI_RUN_OUTPUT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE}}\n\n")
+ endif()
endif()
endfunction()
-macro(_MPI_check_lang_works LANG)
+macro(_MPI_check_lang_works LANG SUPPRESS_ERRORS)
# For Fortran we may have by the MPI-3 standard an implementation that provides:
# - the mpi_f08 module
# - *both*, the mpi module and 'mpif.h'
@@ -1201,9 +1225,9 @@ macro(_MPI_check_lang_works LANG)
if( NOT MPI_${LANG}_WORKS )
if("${LANG}" STREQUAL "Fortran")
set(MPI_Fortran_INTEGER_LINE "(kind=MPI_INTEGER_KIND)")
- _MPI_try_staged_settings(${LANG} test_mpi F77_HEADER FALSE)
- _MPI_try_staged_settings(${LANG} test_mpi F90_MODULE FALSE)
- _MPI_try_staged_settings(${LANG} test_mpi F08_MODULE FALSE)
+ _MPI_try_staged_settings(${LANG} test_mpi F77_HEADER FALSE ${SUPPRESS_ERRORS})
+ _MPI_try_staged_settings(${LANG} test_mpi F90_MODULE FALSE ${SUPPRESS_ERRORS})
+ _MPI_try_staged_settings(${LANG} test_mpi F08_MODULE FALSE ${SUPPRESS_ERRORS})
set(MPI_${LANG}_WORKS FALSE)
@@ -1219,14 +1243,14 @@ macro(_MPI_check_lang_works LANG)
# However, MPI-1 also did not define the Fortran 90 and 08 modules, so we only try the F77 header.
unset(MPI_Fortran_INTEGER_LINE)
if(NOT MPI_${LANG}_WORKS)
- _MPI_try_staged_settings(${LANG} test_mpi F77_HEADER_NOKIND FALSE)
+ _MPI_try_staged_settings(${LANG} test_mpi F77_HEADER_NOKIND FALSE ${SUPPRESS_ERRORS})
if(MPI_RESULT_${LANG}_test_mpi_F77_HEADER_NOKIND)
set(MPI_${LANG}_WORKS TRUE)
set(MPI_${LANG}_HAVE_F77_HEADER TRUE)
endif()
endif()
else()
- _MPI_try_staged_settings(${LANG} test_mpi normal FALSE)
+ _MPI_try_staged_settings(${LANG} test_mpi normal FALSE ${SUPPRESS_ERRORS})
# If 'test_mpi' built correctly, we've found valid MPI settings. There might not be MPI-2 C++ support, but there can't
# be MPI-2 C++ support without the C bindings being present, so checking for them is sufficient.
set(MPI_${LANG}_WORKS "${MPI_RESULT_${LANG}_test_mpi_normal}")
@@ -1388,7 +1412,7 @@ foreach(LANG IN ITEMS C CXX Fortran)
# Should the imported targets be empty, we effectively try whether the compiler supports MPI on its own, which is the case on e.g.
# Cray PrgEnv.
_MPI_create_imported_target(${LANG})
- _MPI_check_lang_works(${LANG})
+ _MPI_check_lang_works(${LANG} TRUE)
# If the compiler can build MPI code on its own, it functions as an MPI compiler and we'll set the variable to point to it.
if(MPI_${LANG}_WORKS)
@@ -1440,7 +1464,7 @@ foreach(LANG IN ITEMS C CXX Fortran)
# If we haven't made the implicit compiler test yet, perform it now.
if(NOT MPI_${LANG}_TRIED_IMPLICIT)
_MPI_create_imported_target(${LANG})
- _MPI_check_lang_works(${LANG})
+ _MPI_check_lang_works(${LANG} TRUE)
endif()
# Should the MPI compiler not work implicitly for MPI, still interrogate it.
@@ -1486,7 +1510,7 @@ foreach(LANG IN ITEMS C CXX Fortran)
_MPI_create_imported_target(${LANG})
if(NOT MPI_${LANG}_WORKS)
- _MPI_check_lang_works(${LANG})
+ _MPI_check_lang_works(${LANG} FALSE)
endif()
# Next, we'll initialize the MPI variables that have not been previously set.
@@ -1505,7 +1529,7 @@ foreach(LANG IN ITEMS C CXX Fortran)
if(MPI_${LANG}_WORKS)
if("${LANG}" STREQUAL "CXX" AND NOT DEFINED MPI_MPICXX_FOUND)
if(NOT MPI_CXX_SKIP_MPICXX AND NOT MPI_CXX_VALIDATE_SKIP_MPICXX)
- _MPI_try_staged_settings(${LANG} test_mpi MPICXX FALSE)
+ _MPI_try_staged_settings(${LANG} test_mpi MPICXX FALSE FALSE)
if(MPI_RESULT_${LANG}_test_mpi_MPICXX)
set(MPI_MPICXX_FOUND TRUE)
else()
@@ -1540,7 +1564,7 @@ foreach(LANG IN ITEMS C CXX Fortran)
# and MPI_SUBVERSION are provided. These defines did not exist in MPI 1.0 and 1.1 and therefore might not
# exist. For C/C++, test_mpi.c will handle the MPI_VERSION extraction, but for Fortran, we need mpiver.f90.
if(NOT DEFINED MPI_${LANG}_VERSION)
- _MPI_try_staged_settings(${LANG} mpiver ${MPI_${LANG}_HIGHEST_METHOD} FALSE)
+ _MPI_try_staged_settings(${LANG} mpiver ${MPI_${LANG}_HIGHEST_METHOD} FALSE FALSE)
if(MPI_RESULT_${LANG}_mpiver_${MPI_${LANG}_HIGHEST_METHOD})
file(STRINGS ${MPI_BIN_FOLDER}/mpiver_${LANG}.bin _MPI_VERSION_STRING LIMIT_COUNT 1 REGEX "INFO:MPI-VER")
if("${_MPI_VERSION_STRING}" MATCHES ".*INFO:MPI-VER\\[([0-9]+)\\.([0-9]+)\\].*")
@@ -1559,7 +1583,7 @@ foreach(LANG IN ITEMS C CXX Fortran)
if(MPI_${LANG}_HAVE_${mpimethod})
set(MPI_${LANG}_${mpimethod}_SUBARRAYS FALSE)
set(MPI_${LANG}_${mpimethod}_ASYNCPROT FALSE)
- _MPI_try_staged_settings(${LANG} fortranparam_mpi ${mpimethod} TRUE)
+ _MPI_try_staged_settings(${LANG} fortranparam_mpi ${mpimethod} TRUE FALSE)
if(MPI_RESULT_${LANG}_fortranparam_mpi_${mpimethod} AND
NOT "${MPI_RUN_RESULT_${LANG}_fortranparam_mpi_${mpimethod}}" STREQUAL "FAILED_TO_RUN")
if("${MPI_RUN_OUTPUT_${LANG}_fortranparam_mpi_${mpimethod}}" MATCHES
@@ -1600,7 +1624,7 @@ foreach(LANG IN ITEMS C CXX Fortran)
# It's also worth noting that the installed version string can depend on the language, or on the system the binary
# runs on if MPI is not statically linked.
if(MPI_DETERMINE_LIBRARY_VERSION AND NOT MPI_${LANG}_LIBRARY_VERSION_STRING)
- _MPI_try_staged_settings(${LANG} libver_mpi ${MPI_${LANG}_HIGHEST_METHOD} TRUE)
+ _MPI_try_staged_settings(${LANG} libver_mpi ${MPI_${LANG}_HIGHEST_METHOD} TRUE FALSE)
if(MPI_RESULT_${LANG}_libver_mpi_${MPI_${LANG}_HIGHEST_METHOD} AND
"${MPI_RUN_RESULT_${LANG}_libver_mpi_${MPI_${LANG}_HIGHEST_METHOD}}" EQUAL "0")
string(STRIP "${MPI_RUN_OUTPUT_${LANG}_libver_mpi_${MPI_${LANG}_HIGHEST_METHOD}}"
@@ -1686,7 +1710,10 @@ foreach(LANG IN ITEMS C CXX Fortran)
set(MPI_${LANG}_INCLUDE_PATH "${MPI_${LANG}_INCLUDE_DIRS}")
unset(MPI_${LANG}_COMPILE_FLAGS)
if(MPI_${LANG}_COMPILE_OPTIONS)
- set(MPI_${LANG}_COMPILE_FLAGS "${MPI_${LANG}_COMPILE_OPTIONS}")
+ set(MPI_${LANG}_COMPILE_OPTIONS)
+ foreach(flag IN LISTS MPI_${LANG}_COMPILE_FLAGS)
+ string(APPEND MPI_${LANG}_COMPILE_OPTIONS " ${flag}")
+ endforeach()
endif()
if(MPI_${LANG}_COMPILE_DEFINITIONS)
foreach(_MPI_DEF IN LISTS MPI_${LANG}_COMPILE_DEFINITIONS)
diff --git a/cmake/upstream/FindMPI/libver_mpi.c b/cmake/upstream/FindMPI/libver_mpi.c
index be9d19d..d89328a 100644
--- a/cmake/upstream/FindMPI/libver_mpi.c
+++ b/cmake/upstream/FindMPI/libver_mpi.c
@@ -1,9 +1,9 @@
#include <mpi.h>
#ifdef __cplusplus
-#include <cstdio>
+# include <cstdio>
#else
-#include <stdio.h>
+# include <stdio.h>
#endif
int main(int argc, char* argv[])
@@ -16,4 +16,5 @@ int main(int argc, char* argv[])
#else
puts(mpilibver_str);
#endif
+ return 0;
}
diff --git a/cmake/upstream/FindMPI/test_mpi.c b/cmake/upstream/FindMPI/test_mpi.c
index b8a308a..7c96d54 100644
--- a/cmake/upstream/FindMPI/test_mpi.c
+++ b/cmake/upstream/FindMPI/test_mpi.c
@@ -1,9 +1,9 @@
#include <mpi.h>
#ifdef __cplusplus
-#include <cstdio>
+# include <cstdio>
#else
-#include <stdio.h>
+# include <stdio.h>
#endif
#if defined(MPI_VERSION) && defined(MPI_SUBVERSION)
@@ -21,11 +21,11 @@ const char mpiver_str[] = { 'I', 'N',
int main(int argc, char* argv[])
{
#if defined(MPI_VERSION) && defined(MPI_SUBVERSION)
-#ifdef __cplusplus
+# ifdef __cplusplus
std::puts(mpiver_str);
-#else
+# else
puts(mpiver_str);
-#endif
+# endif
#endif
#ifdef TEST_MPI_MPICXX
MPI::MPI_Init(&argc, &argv);
@@ -34,4 +34,5 @@ int main(int argc, char* argv[])
MPI_Init(&argc, &argv);
MPI_Finalize();
#endif
+ return 0;
}
diff --git a/testing/adios2/engine/staging-common/TestCommonReadShared.cpp b/testing/adios2/engine/staging-common/TestCommonReadShared.cpp
index 72199b5..e2a73f3 100644
--- a/testing/adios2/engine/staging-common/TestCommonReadShared.cpp
+++ b/testing/adios2/engine/staging-common/TestCommonReadShared.cpp
@@ -79,7 +79,6 @@ TEST_F(CommonReadTest, ADIOS2CommonRead1D8)
{
size_t writerSize;
-
auto var1 = io1.InquireVariable<double>(varname1);
auto var2 = io2.InquireVariable<double>(varname2);