FindMPI

查找消息传递接口 (MPI) 实现。

消息传递接口 (MPI) 是一个用于编写高性能分布式内存并行应用程序的库,通常部署在集群上。MPI 是一个标准接口(由 MPI 论坛定义),有许多可用的实现。

3.10 版本新增: 模块大改版:许多新变量,按语言组件,支持更广泛的运行时。

用于 MPI 的变量

该模块公开了组件 CCXXMPICXXFortran。 这些组件分别控制要搜索的各种 MPI 语言。 CXXMPICXX 之间的区别在于 CXX 指的是可从 C++ 使用的 MPI C API,而 MPICXX 指的是在 MPI-3 中再次删除的 MPI-2 C++ API。

根据启用的组件,将设置以下变量

MPI_FOUND

变量指示是否已找到所有请求语言的 MPI 设置。 如果未指定任何组件,则如果检测到所有已启用语言的 MPI 设置,则为 true。 请注意,MPICXX 组件不影响此变量。

MPI_VERSION

在请求的语言中检测到的 MPI 的最低版本,如果未指定组件,则为所有已启用语言的 MPI 的最低版本。

此模块将在您的项目中为每种语言设置以下变量,其中 <lang> 是 C、CXX 或 Fortran 之一

MPI_<lang>_FOUND

变量指示是否已找到 <lang> 的 MPI 设置,并且简单的 MPI 测试程序可以使用提供的设置进行编译。

MPI_<lang>_COMPILER

如果存在,则为 <lang> 的 MPI 编译器。

MPI_<lang>_COMPILE_OPTIONS

;-list 形式给出的 <lang> 中 MPI 程序的编译选项。

MPI_<lang>_COMPILE_DEFINITIONS

;-list 形式给出的 <lang> 中 MPI 程序的编译定义。

MPI_<lang>_INCLUDE_DIRS

MPI 头文件的包含路径。

MPI_<lang>_LINK_FLAGS

MPI 程序的链接器标志。

MPI_<lang>_LIBRARIES

要链接 MPI 程序的所有库。

3.9 版本新增: 此外,定义了以下 IMPORTED 目标

MPI::MPI_<lang>

用于从 <lang> 使用 MPI 的目标。

将定义以下指示存在哪些绑定的变量

MPI_MPICXX_FOUND

变量指示 MPI-2 C++ 绑定是否存在(在 MPI-2 中引入,在 MPI-3 中删除)。

MPI_Fortran_HAVE_F77_HEADER

如果 Fortran 77 头文件 mpif.h 可用,则为 True。

MPI_Fortran_HAVE_F90_MODULE

如果 Fortran 90 模块 mpi 可用于访问 MPI(仅限 MPI-2 及更高版本),则为 True。

MPI_Fortran_HAVE_F08_MODULE

如果 Fortran 2008 mpi_f08 可用于 MPI 程序(仅限 MPI-3 及更高版本),则为 True。

如果可能,MPI 版本将由此模块确定。 检测 MPI 版本的工具是在 MPI-1.2 中引入的,因此对于较旧的 MPI 版本无法找到。

MPI_<lang>_VERSION_MAJOR

MPI 发行版为 <lang> 实现的 MPI 主要版本。

MPI_<lang>_VERSION_MINOR

MPI 发行版为 <lang> 实现的 MPI 次要版本。

MPI_<lang>_VERSION

MPI 发行版为 <lang> 实现的 MPI 版本。

请注意,由于 MPI 标准始终要求此绑定在 C 和 C++ 代码中都能工作,因此没有变量用于指示可以通过 mpi.h 访问 C 绑定。

对于运行 MPI 程序,该模块设置以下变量

MPIEXEC_EXECUTABLE

用于运行 MPI 程序的可执行文件(如果存在)。

MPIEXEC_NUMPROC_FLAG

在给出要运行的处理器数量之前传递给 mpiexec 的标志。

MPIEXEC_MAX_NUMPROCS

要使用的 MPI 处理器数量。 默认为在主机系统上检测到的处理器数量。

MPIEXEC_PREFLAGS

直接在要运行的可执行文件之前传递给 mpiexec 的标志。

MPIEXEC_POSTFLAGS

在其他标志之后传递给 mpiexec 的标志。

用于定位 MPI 的变量

此模块执行四个步骤来搜索 MPI 实现

  1. 搜索 MPIEXEC_EXECUTABLE,如果找到,则使用其基本目录。

  2. 检查编译器是否内置了 MPI 支持。 如果用户将编译器包装器作为 CMAKE_<LANG>_COMPILER 传递,或者他们使用 Cray 系统编译器包装器,则属于这种情况。

  3. 尝试查找 MPI 编译器包装器并从中确定编译器信息。

  4. 尝试查找不附带此类包装器的 MPI 实现,方法是猜测设置。 目前,仅支持 Windows 上的 Microsoft MPI 和 MPICH2。

为了控制 MPIEXEC_EXECUTABLE 步骤,可以设置以下变量

MPIEXEC_EXECUTABLE

手动指定 mpiexec 的位置。

MPI_HOME

指定 MPI 安装的基本目录。

ENV{MPI_HOME}

用于指定 MPI 安装基本目录的环境变量。

ENV{I_MPI_ROOT}

用于指定 MPI 安装基本目录的环境变量。

为了控制编译器包装器步骤,可以设置以下变量

MPI_<lang>_COMPILER

搜索指定的编译器包装器并使用它。

MPI_<lang>_COMPILER_FLAGS

在询问期间传递给 MPI 编译器包装器的标志。 如果传递了特定标志,某些编译器包装器支持链接调试或跟踪库,并且可以使用此变量来获取它们。

MPI_COMPILER_FLAGS

如果未给出特定于语言的标志,则用于初始化 MPI_<lang>_COMPILER_FLAGS。 默认情况下为空。

MPI_EXECUTABLE_SUFFIX

附加到正在查找的所有名称的后缀。 例如,您可以将其设置为 .mpich.openmpi,以便在 Debian 及其衍生版本上优先选择其中一个。

为了控制猜测步骤,可以设置以下变量

MPI_GUESS_LIBRARY_NAME

有效值为 MSMPIMPICH2。 如果设置,则仅搜索给定的库。 默认情况下,如果 MSMPIMPICH2 都可用,则优先选择 MSMPI。 这也会将 MPI_SKIP_COMPILER_WRAPPER 设置为 true,这可能会被覆盖。

可以使用以下控制变量跳过每个搜索步骤

MPI_ASSUME_NO_BUILTIN_MPI

如果为 true,则模块假定编译器本身不提供 MPI 实现,并跳至步骤 2。

MPI_SKIP_COMPILER_WRAPPER

如果为 true,则不会搜索编译器包装器。

MPI_SKIP_GUESSING

如果为 true,则将跳过猜测步骤。

此外,以下控制变量可用于更改搜索行为

MPI_CXX_SKIP_MPICXX

添加一些将禁用 MPI-2 C++ 绑定的定义。 当前支持 MPICH、Open MPI、Platform MPI 及其衍生版本,例如 MVAPICH 或 Intel MPI。

如果变量 MPI_<lang>_WORKS 的查找过程失败,则表示模块检测到或传递给模块的设置不起作用,甚至简单的 MPI 测试程序也无法编译。

如果所有这些参数都不足以找到正确的 MPI 实现,则用户可以通过在 MPI_<lang>_LIBRARIES 中指定库列表并在 MPI_<lang>_ADDITIONAL_INCLUDE_DIRS 中指定包含目录列表来禁用整个自动检测过程。 除了这两个变量之外,还可以设置任何其他变量。 然后,模块将验证 MPI 设置并将设置存储在缓存中。

MPI 的缓存变量

变量 MPI_<lang>_INCLUDE_DIRS 将从以下变量组装而成。 对于 C 和 CXX

MPI_<lang>_HEADER_DIR

磁盘上 mpi.h 头文件的位置。

对于 Fortran

MPI_Fortran_F77_HEADER_DIR

Fortran 77 头文件 mpif.h 的位置(如果存在)。

MPI_Fortran_MODULE_DIR

mpimpi_f08 模块的位置(如果可用)。

对于所有语言,还会考虑以下变量

MPI_<lang>_ADDITIONAL_INCLUDE_DIRS

除了普通包含目录之外,还需要的路径的 ;-list

MPI_<include_name>_INCLUDE_DIR

<include_name> 引用的包含文件夹的路径变量。

MPI_<lang>_ADDITIONAL_INCLUDE_VARS

<include_name>;-list,它将添加到 <lang> 的包含位置。

变量 MPI_<lang>_LIBRARIES 将从以下变量组装而成

MPI_<lib_name>_LIBRARY

名为 <lib_name> 的库的位置,用于 MPI。

MPI_<lang>_LIB_NAMES

<lib_name>;-list,它将添加到 <lang> 的包含位置。

mpiexec 的用法

当使用 MPIEXEC_EXECUTABLE 执行 MPI 应用程序时,您通常应按如下方式使用所有 MPIEXEC_EXECUTABLE 标志

${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS}
  ${MPIEXEC_PREFLAGS} EXECUTABLE ${MPIEXEC_POSTFLAGS} ARGS

其中 EXECUTABLE 是 MPI 程序,ARGS 是要传递给 MPI 程序的参数。

用于 MPI 的高级变量

该模块可以根据显式请求执行一些高级功能检测。

重要提示: 以下检查无法在不执行 MPI 测试程序的情况下执行。 考虑在交叉编译期间 try_run() 行为的特殊注意事项。 此外,运行 MPI 程序可能会导致其他问题,例如某些系统上的防火墙通知。 仅当您绝对需要信息时才应启用这些检测。

如果以下变量设置为 true,则将执行相应的搜索

MPI_DETERMINE_Fortran_CAPABILITIES

确定所有可用的 Fortran 绑定的 MPI_SUBARRAYS_SUPPORTEDMPI_ASYNC_PROTECTS_NONBLOCKING 的值,并使其值作为 MPI_Fortran_<binding>_SUBARRAYSMPI_Fortran_<binding>_ASYNCPROT 可用,其中 <binding>F77_HEADERF90_MODULEF08_MODULE 之一。

MPI_DETERMINE_LIBRARY_VERSION

对于每种语言,查找 MPI_Get_library_version 的输出,并使其作为 MPI_<lang>_LIBRARY_VERSION_STRING 可用。 此信息通常与 MPI 实现的运行时组件相关联,并且可能因 <lang> 而异。 请注意,返回值完全由实现定义。 此信息可能用于识别 MPI 供应商,例如选择与 MPI 供应商匹配的多个第三方二进制文件中的正确一个。

向后兼容性

自 3.10 版本起已弃用。

为了向后兼容旧版本的 FindMPI,设置了这些变量

MPI_COMPILER        MPI_LIBRARY        MPI_EXTRA_LIBRARY
MPI_COMPILE_FLAGS   MPI_INCLUDE_PATH   MPI_LINK_FLAGS
MPI_LIBRARIES

在新项目中,请使用 MPI_<lang>_XXX 等效项。 此外,以下变量已弃用

MPI_<lang>_COMPILE_FLAGS

请改用 MPI_<lang>_COMPILE_OPTIONSMPI_<lang>_COMPILE_DEFINITIONS

MPI_<lang>_INCLUDE_PATH

对于使用,请使用 MPI_<lang>_INCLUDE_DIRS,对于指定文件夹,请改用 MPI_<lang>_ADDITIONAL_INCLUDE_DIRS

MPIEXEC

请改用 MPIEXEC_EXECUTABLE