4.8. 必需的支撑库
虽然Open MPI可以构建支持多种系统,但在任何环境中构建Open MPI都需要一小部分必需的支持库。其中几个软件包既是Open MPI运行的基础,又并非在所有环境中普遍可用。因此,这些"基础"软件包既被嵌入到Open MPI的分发包中,又直接整合到Open MPI的配置、构建和安装流程中。
参见下方了解 Open MPI如何选择使用这些软件包的嵌入式版本 还是系统已安装的版本。
-
此库为必需项;若无此库,Open MPI将无法构建。
最低要求版本: 1.11.0
注意
虽然最低版本的Hwloc可以运行,但与后续版本相比,它可能存在缺陷和/或功能较少。
除了关于v3.0.0及更高版本的Hwloc限制(见下文),Open MPI社区通常建议使用最新可用的Hwloc版本,除非有特定原因不这样做。
Open MPI 发行版中嵌入的版本: 2.7.1
危险
截至v5.0.x版本,Open MPI尚未支持Hwloc v3.x系列(在Open MPI v5.0.x发布时该版本可能尚未推出)。与Hwloc v2.x系列相比,预计Hwloc v3.x会破坏API和/或ABI兼容性。
如果发现系统中已安装的外部Hwloc版本≥v3.0.0,Open MPI将拒绝构建。这是基于其他HPC应用程序和/或库可能正在使用该版本的假设。此类配置可能导致Open MPI应用程序出现难以排查且可能令人困惑的运行时故障。
如果Open MPI的
configure脚本因检测到Hwloc安装版本≥v3.0.0而中止,您可以通过以下两种方式解决:确保Open MPI找到LD_LIBRARY_PATH中的路径顺序),或强制使用Open MPI捆绑的Hwloc: shell$ ./configure --with-hwloc=internal ...
无论如何,至关重要的一点是,如果MPI应用程序或其任何依赖项使用了Hwloc,那么它必须使用与编译Open MPI时相同的Hwloc版本。
-
此库为必需项;没有它,Open MPI将无法构建。
最低版本要求: 2.0.21
Open MPI发行版中嵌入的版本: 2.1.12
注意
Open MPI社区已对Libevent 2.1.12进行了大量测试。其他版本应该可以工作,但——与Hwloc、OpenPMIx和PRRTE不同——没有太多理由升级使用更高版本的Libevent。
-
该库是必需的;没有它,Open MPI将无法构建。
在不使用PRRTE构建时所需的最低版本: 4.2.0
注意
虽然最低版本的OpenPMIx可以运行,但相比后续版本可能存在更多缺陷和/或功能较少。
Open MPI社区通常建议使用最新可用的OpenPMIx版本,除非有特殊原因不能使用。
使用PRRTE构建时的最低版本要求: 参见PRRTE项目文档。
Open MPI 发行版中嵌入的版本: v5.0.8a1
-
在某些环境中,此库是可选的。请参阅下文。
最低要求版本: 3.0.0
注意
虽然PRRTE的最低版本可以运行,但与后续版本相比,它可能仍存在缺陷和/或功能较少。例如,如果您使用3.0.0版本构建和运行,将无法获得完整的
mpirun(1)手册页。Open MPI社区通常建议使用PRRTE的最新可用版本,除非有特殊原因不能使用。
Open MPI 发行版中嵌入的版本: v3.0.11a1
PRRTE 提供了 Open MPI 功能齐全的
mpirun/mpiexecMPI 应用程序启动器(这两个命令是相同的;它们是同一可执行文件的符号链接)。警告
如果您正在构建嵌入在Open MPI v5.0.x发行版中的PRRTE:
如果您同时也在构建嵌入在Open MPI v5.0.x发行版中的PMIx,这种软件包组合是受支持的。
如果您正在针对外部PMIx安装进行构建(即非嵌入在Open MPI v5.0.x发行版中的PMIx版本),您应查阅PRRTE项目文档以了解所需的最低PMIx版本。
如果您的环境使用其他MPI应用程序启动器(例如,Slurm用户可以使用
srun启动器来"直接启动"Open MPI应用程序),那么使用PRRTE是可选的。如果您的环境中没有其他MPI应用程序启动器,那么您需要安装PRRTE并构建支持PRRTE的Open MPI。
Open MPI可以使用其源代码树中嵌入的PRRTE副本,也可以针对外部PRRTE安装进行编译/链接。有关如何指定每种方法的详细信息,请参阅本节。
注意
一般来说,Open MPI社区建议同时使用最新版本的必需支持库和所有其他可选支持库。这是因为较新版本通常包含错误修复,有时会影响Open MPI的功能。具体来说,在配备英特尔Ponte Vecchio加速器的系统上,使用早于v2.8.0版本的硬件位置感知库存在已知问题。若在此类系统上运行Open MPI,必须使用Hwloc v2.8.0或更新版本,否则可能出现未定义行为。这种现象并非硬件位置感知库独有,因此Open MPI社区建议尽可能使用所有支持库的最新版本。
4.8.1. 库依赖项
这些支持库彼此之间存在依赖关系:
Open MPI所需的支持库依赖关系图。
上层模块依赖于下层模块。具体来说:
Open MPI依赖于PRRTE、PMIx、Hwloc和Libevent(即所有组件)。
PRRTE依赖于PMIx、Hwloc和Libevent(即除Open MPI之外的所有组件)。
PMIx 依赖于 Hwloc 和 Libevent。
Hwloc 不依赖任何其他组件。
Libevent 不依赖任何其他组件。
在运行时,关键的是运行时链接器必须加载这些库中的每一个的精确一份副本。
注意
所需的支持库可能还有其他依赖项,但为了简洁以及与构建Open MPI的相关性,此处不讨论其他依赖项。
4.8.2. 潜在问题
如果单个进程中加载了上述共享库的多个不同副本,可能会(将会)出现问题。例如,考虑以下情况:
加载Open MPI共享库会导致加载Libevent共享库vA.B.C.
但随后加载PMIx共享库会导致加载Libevent共享库vX.Y.Z。
由于现在同一个进程中加载了两个不同版本的Libevent共享库(是的,这种情况确实会发生!),可能会出现(必将出现)不可预测的行为。
这种基本错误场景可能存在许多变体。它们都很糟糕,且可能极难诊断。
4.8.3. 避免问题
避免这些问题的一个简单方法是配置您的系统,使其仅保留每个必需支持库的一个副本。
重要
如果可能,在调用Open MPI的configure脚本之前,请尽量使用操作系统/环境中的包管理器安装这些支持库(包括它们的开发头文件)。
并非所有的包管理器都提供所有必需的支撑库。但即使您的包管理器仅安装了——例如——Libevent和Hwloc,这也在一定程度上简化了最终的Open MPI配置,从而避免了一些潜在的配置错误。
4.8.4. configure如何查找所需的库
为了在最终用户便利性和灵活性之间取得平衡,Open MPI在其官方发布包中捆绑了这四个必需的支持库。
通常情况下,如果Open MPI无法找到所需的支持库,它会作为主Open MPI配置、构建和安装流程的一部分,自动配置、构建、安装并使用其捆绑版本。
换句话说:Open MPI的configure脚本会检查构建机器,查看是否能找到每个所需的支持头文件和库。如果找不到,它将尝试回退并使用对应的捆绑支持库。
重要
请注意,configure足够智能,能够理解所需支持库之间的依赖关系。
具体来说:如果configure检测到系统中已安装某个支持库的开发头文件和库文件,那么它将忽略对应的捆绑支持库,同时也会忽略依赖关系图中位于该库下方的所有其他捆绑支持库。
4.8.4.1. 构建示例1
configure 在 /usr/local 目录中找到 PRRTE 的开发头文件和库文件。这将导致以下情况发生:
configure将忽略Open MPI源代码树中捆绑的PRRTE库,转而使用已安装在/usr/local中的PRRTE。configure也会忽略 Open MPI 源代码树中捆绑的 PMIx、Hwloc 和 Libevent 库。如果
configure在构建机器上无法找到PMIx、Hwloc和Libevent的头文件和库(即假设与/usr/local中PRRTE使用的PMIx、Hwloc和Libevent相同),这将导致错误:configure会中止,因此拒绝构建Open MPI。
4.8.4.2. 构建示例 2
configure 在构建机器上没有找到PRRTE,但确实
在/opt/local中找到了PMIx的开发头文件和库。这将导致以下情况发生:
configure将配置构建捆绑在Open MPI源代码树中的PRRTE库。configure将忽略 Open MPI 源代码树中捆绑的 PMIx 库,转而使用已安装在/opt/local中的 PMIx。configure也会忽略 Open MPI 源代码树中捆绑的 Hwloc 和 Libevent 库。如果
configure无法在构建机器的其他位置找到Hwloc和Libevent的头文件和库(即假设与/opt/local中PMIx使用的Hwloc和Libevent相同),这将导致错误:configure会中止,因此拒绝构建Open MPI。
4.8.4.3. 构建示例3
configure 仅能在构建机器上找到 Libevent 的开发头文件和库文件。这将导致以下情况发生:
configure将配置用于构建捆绑在Open MPI源代码树中的PRRTE、PMIx和Hwloc库。configure将忽略Open MPI源代码树中捆绑的Libevent库,转而使用已安装的Libevent版本。
4.8.5. C与Fortran的难点
有时在尝试构建Open MPI时,您可能会看到类似以下的错误:
...
PPFC profile/pwin_unlock_f08.lo
PPFC profile/pwin_unlock_all_f08.lo
PPFC profile/pwin_wait_f08.lo
FCLD libmpi_usempif08.la
ld: library not found for -lhwloc
collect2: error: ld returned 1 exit status
make``2``: *** ``libmpi_usempif08.la`` Error 1
当多种因素同时出现时,可能会发生此错误:
如果Open MPI的
configure脚本选择使用"外部"安装的hwloc和/或Libevent(即位于Open MPI源代码树之外)。如果Open MPI的
configure脚本选择了来自不同套件/安装的C和Fortran编译器。
简而言之:如果C和Fortran编译器套件的默认搜索库路径不同,C链接器可能会找到系统安装的libhwloc和/或libevent,但Fortran链接器可能找不到。
从Open MPI v4.0.0版本开始,在Mac OS系统上这种情况可能会更频繁地发生,原因是:
在v4.0.0版本中,Open MPI的
configure脚本被修改为"优先"使用系统安装的hwloc和Libevent版本(而不是优先使用Open MPI发行版tarball中捆绑的hwloc和Libevent)。
例如,截至2019年7月,Homebrew:
在
/usr/local目录下安装 hwloc v2.0.4在
/usr/local目录下安装Gnu C和Fortran编译器套件v9.1.0。但需要注意的是,C编译器可执行文件名为gcc-9(而非gcc!),而Fortran编译器可执行文件名为gfortran。
综合考虑这些因素后,Open MPI的configure脚本会做出以下决定:
C编译器是
gcc(这是MacOS系统自带的C编译器)。Fortran编译器是
gfortran(这是通过Homebrew安装的Fortran编译器)。在
/usr/local目录中存在一个合适的系统安装的hwloc,C编译器/链接器无需指定任何额外的链接器搜索路径即可找到它。
细心的读者会发现,C和Fortran编译器来自两个完全不同的安装环境。实际上,它们的默认库搜索路径也不同:
MacOS系统安装的
gcc默认会搜索/usr/local/lib目录。通过Homebrew安装的
gfortran默认情况下不会搜索/usr/local/lib目录。
因此,由于Open MPI的大部分源代码库是用C语言编写的,它能够成功编译/链接hwloc。但当编译和链接Open MPI的Fortran代码(针对mpi_f08模块)时,通过Homebrew安装的gfortran——默认情况下不会搜索/usr/local/lib目录——无法找到libhwloc库,导致链接失败。
针对这个问题,有几种可能的解决方案:
最佳解决方案是始终确保Open MPI使用来自同一套件/安装的C和Fortran编译器。这将确保两个编译器/链接器使用相同的默认库搜索路径,所有行为应保持一致。例如,以下命令指示Open MPI的
configure脚本使用gcc-9作为C编译器(截至2019年7月,这是Homebrew安装的C编译器的可执行文件名):shell$ ./configure CC=gcc-9 ... # 您可以精确指定C编译器的绝对路径,和/或同时指定Fortran编译器: shell$ ./configure CC=/usr/local/bin/gcc-9 FC=/usr/local/bin/gfortran ...
请注意,这可能会导致
configure无法找到Homebrew安装的hwloc,转而使用Open MPI源代码树中捆绑的hwloc。或者,您可以强制
configure选择捆绑版本的hwloc和libevent,从而完全避免此问题:shell$ ./configure --with-hwloc=internal --with-libevent=internal ...
最后,你可以明确告诉
configure在哪里查找外部hwloc库。不过这样做可能会产生一些意外后果,因为它会将C和Fortran链接器的默认搜索路径前缀都设置为/usr/local/lib:shell$ ./configure --with-hwloc-libdir=/usr/local/lib ...
4.8.6. 覆盖configure行为
如果configure的默认搜索行为不能满足您的环境需求,您可以使用命令行选项来覆盖其默认行为。
例如,如果PMIx和/或PRRTE的安装位置不在默认头文件与链接器搜索路径范围内,您可以通过命令行选项告知Open MPI的configure脚本搜索位置。以下示例展示了当PMIx和PRRTE都安装在/opt/open-mpi-stuff目录时的configure调用方式:
./configure --prefix=$HOME/openmpi-install \
--with-pmix=/opt/open-mpi-stuff \
--with-prrte=/opt/open-mpi-stuff ...
再举一个例子,如果您没有root权限使用操作系统/环境包管理器,并且您的MPI应用程序较为简单(例如没有外部库依赖),您可能希望这样配置Open MPI:
./configure --prefix=$HOME/openmpi-install \
--with-libevent=internal --with-hwloc=internal \
--with-pmix=internal --with-prrte=internal ...
internal 关键字强制 configure 使用所有四个捆绑版本的必需库。
危险
在覆盖configure对这些库的默认搜索行为时,务必非常非常小心。请牢记关键要求:Open MPI基础设施和应用程序必须加载每个支持库的唯一副本。为简单起见,最好确保使用与Open MPI编译构建时完全相同的支持库。
例如,使用上述示例configure命令安装的Open MPI时,您可能需要在运行时链接器搜索路径(如Linux上的LD_LIBRARY_PATH)前添加$HOME/openmpi-install/lib。这将确保链接器能够找到您Open MPI安装目录中的四个支持库,即使系统中其他地方存在相同支持库的其他副本。
4.8.7. 给打包者的(强烈)建议
如果您是Open MPI的打包人员,我们强烈建议您的Open MPI软件包不应包含Hwloc、Libevent、PMIx或PRRTE。相反,它应该依赖于这些软件包的外部独立构建版本。
更多详情请参阅打包者建议部分