3.4. 编译器说明

  • Open MPI 需要使用支持C99标准的编译器进行构建。

  • 在非x86-64、AArc64(64位ARM)和PPC平台上,Open MPI需要编译器支持C11原子操作或GCC的__atomic原子操作(例如GCC版本≥4.8.x)。

  • 32位平台仅支持支持C11原子操作的较新编译器。这包括GCC 4.9.x及以上版本(建议使用GCC 6.x或更新版本)、Intel编译器套件16以及clang 3.1。

  • 在构建Open MPI时混合使用不同厂商的编译器(例如使用一个厂商的C/C++编译器搭配另一个厂商的Fortran编译器),部分Open MPI用户已成功实践(Open MPI用户邮件列表中讨论过),但此类配置未经测试且无官方文档支持。例如,这类配置可能需要额外的编译器/链接器标志才能使Open MPI正确构建。

    这种情况在MacOS系统上并不罕见:使用系统默认的GCC编译器(即/usr/bin/gcc)搭配第三方gfortran(如通过Homebrew安装在/usr/local/bin/gfortran的版本)。由于这些编译器来自不同组织,它们的默认搜索路径也不同。例如,若Homebrew同时安装了Libevent(Open MPI依赖的第三方库),MacOS默认的gcc链接器无需额外命令行标志即可找到该库,但Homebrew提供的gfortran链接器则无法自动定位。此时可能需要在配置命令行中添加:

    shell$ ./configure FCFLAGS=-L/usr/local/lib ...
    

    -L标志将在创建Open MPI的Fortran库时传递给Fortran链接器,从而使其能够找到已安装的Libevent。

  • 一般来说,某厂商系列编译器的最新版本存在的错误最少。我们遇到过这样的情况:厂商XYZ的编译器版本A.B无法编译Open MPI,但版本A.C(其中C>B)却能正常工作。如果遇到编译失败的情况,建议您再次确认是否已安装编译器的最新错误修复和补丁。

  • 用户反馈在使用Open MPI的(非默认)--enable-debug配置选项时,旧版Fortran PGI编译器套件存在问题。根据上述建议使用编译器系列的最新版本,Open MPI团队推荐使用最新版本的PGI套件,和/或不使用--enable-debug配置选项。如果有所帮助,以下是我们通过对PGI编译器套件不同版本进行一些(非全面)测试后发现的情况:

    • pgi-8 : 目前没有已知的兼容版本支持 --enable-debug

    • pgi-9 : 9.0-4 已知良好版本

    • pgi-10: 10.0-0 已知良好版本

    • pgi-11: 已知没有支持 --enable-debug 的稳定版本

    • pgi-12: 12.10版本已知在使用-m32参数时存在问题,但不使用-m32时表现良好 (而12.8和12.9版本在使用--enable-debug参数时均存在问题)

    • pgi-13: 13.9版本已知在-m32下存在问题,13.10版本已知在无-m32情况下运行良好

    • pgi-15: 15.10版本已知与-m32不兼容

  • 同样地,Fortran PGI编译器在处理长源目录路径名时存在一个已知问题,该问题已在9.0-4版本中修复(已知9.0-3版本在这方面存在缺陷)。

  • Open MPI 不支持在 OS X 或 MacOS 上使用 PGI 编译器套件。详情请参阅以下问题:

  • OpenSHMEM的Fortran绑定不支持“无下划线”的Fortran符号约定。IBM的xlf编译器默认以该模式构建。因此,IBM的xlf编译器默认无法构建/链接OpenSHMEM的Fortran绑定。解决方法是在配置时传递FC="xlf -qextname"来强制添加尾部下划线。更多详情请参阅https://github.com/open-mpi/ompi/issues/3612

  • 在PowerPC平台(测试环境为ppc64le)上使用mpi_f08模块的MPI应用程序,在以下情况下很可能会出现运行时故障:

    • 他们使用的是GNU链接器(ld)版本在v2.25.1之后且在v2.28之前,并且

    • 它们使用PGI(测试版本17.5)或XL(测试版本v15.1.5)编译器编译。在默认使用ld 2.26.1版本的Ubuntu 16.04系统中发现了此问题。不过,该问题会影响所有使用上述版本ld的操作系统。这个GNU链接器的回归问题将在2.28版本中修复。这里是该问题的GNU错误链接。XL编译器将在未来版本中包含针对此问题的修复。

  • 在NetBSD-6系统(至少AMD64和i386架构)以及可能的OpenBSD系统上,Libtool会错误识别f95/g95编译器的属性,如果用它来构建Open MPI会导致难以排查的编译时错误。您可以通过以下方式规避此问题:确保libtool不使用f95/g95编译器(例如通过指定FC=参数,或确保在路径中优先找到其他Fortran编译器而非f95/g95),或者通过--disable-mpi-fortran参数禁用Fortran MPI绑定。

  • 在OpenBSD/i386平台上,如果使用--enable-mca-no-build=patcher进行配置,还需要添加--disable-dlopen参数。否则可能会随机出现异常崩溃的情况。

  • 编译Fortran mpi_f08模块需要Absoft 11.5.2版本加上2012年9月的服务包(Absoft表示可应要求提供),或高于11.5.2的版本(例如11.5.3)。

  • Open MPI不支持Sparc v8 CPU目标平台。不过,从Solaris Studio 12.1及后续版本开始,编译器不再推荐使用-xarch=v8plus-xarch=v9参数。当前Solaris Studio编译器更倾向于使用-m32-m64选项来分别生成32位和64位目标代码。根据GCC版本的不同,可能需要使用-m32-mcpu=v9 -m32参数。

  • 如果尝试在Ubuntu系统上使用Solaris Studio的C++编译器配合-m32选项编译OMPI,可能会看到如下警告:

    CC: 警告:未能检测到系统链接器版本,将回退至自定义链接器使用
    

    这将导致编译失败。可以通过以下两种方式解决该问题:要么将LD_LIBRARY_PATH设置为32位库的路径(通常是/lib32),要么在configure命令中添加LDFLAGS="-L/lib32 -R/lib32"参数。需要注意的是,Solaris Studio在Ubuntu Linux发行版上并非官方支持,因此可能还会遇到其他问题。

  • Open MPI 不支持 gccfss 编译器(用于SPARC系统的GCC编译器;这是Sun公司现已停止开发的一个编译器项目)。

  • 至少某些版本的Intel 8.1编译器在编译特定Open MPI源代码文件时会出现段错误。因此,该版本不受支持。

  • 据报告,Intel 9.1和10.0编译器在IA64平台上无法编译Open MPI。截至2012年9月12日,在IA64平台上进行的测试非常少(如果有的话)(使用任何编译器)。对这些平台的支持是"尽力而为"的,但不太可能投入精力来解决该平台上Intel 9.1/10.0编译器的问题。

  • 早期版本的Intel 12.1 Linux编译器套件在x86_64架构上似乎存在一个阻止Open MPI正常工作的错误。症状包括包装器编译器(例如mpicc)和MPI应用程序立即出现段错误。截至2012年2月1日,如果您升级到Intel 12.1 Linux编译器套件的最新版本,该问题将会消失。

  • 用户反馈,Intel Fortran编译器在macOS上链接基于Fortran的MPI应用程序时会失败,并出现类似以下的链接器错误:

    Undefined symbols for architecture x86_64:
      "_ompi_buffer_detach_f08", referenced from:
          import-atom in libmpi_usempif08.dylib
    ld: symbol(s) not found for architecture x86_64
    

    似乎在使用Open MPI的configure脚本前设置环境变量lt_cx_ld_force_load=no可以解决此问题。例如:

    shell$ lt_cv_ld_force_load=no ./configure ...
    
  • Portland Group编译器7.0之前的版本在将较短整数转换为较长整数时,需要使用-Msignextend编译器标志来扩展符号位。这与其他编译器(如GNU)不同。当使用Portland编译器套件编译Open MPI时,应将以下标志传递给Open MPI的configure脚本:

    shell$ ./configure CFLAGS=-Msignextend CXXFLAGS=-Msignextend \
           --with-wrapper-cflags=-Msignextend \
           --with-wrapper-cxxflags=-Msignextend ...
    

    这既会用正确的编译标志编译Open MPI,也会在使用C和C++ MPI包装器编译器编译用户MPI应用程序时自动添加-Msignextend

  • 据报告,Pathscale 5.0.5和6.0.527编译器在尝试构建Open MPI时会出现内部编译器错误。

  • 截至2017年7月,Pathscale编译器套件显然已不再获得商业支持,且似乎不会有后续版本发布。因此,发现的任何关于使用Pathscale编译器套件构建/运行Open MPI的问题可能都无法得到解决。

  • 已知在Suse 9.3系统上使用Absoft编译器构建MPI Fortran绑定时会因Libtool兼容性问题而失败。

  • 现在只有一个Fortran MPI封装编译器和一个Fortran OpenSHMEM封装编译器:分别是mpifortoshfort

    警告

    传统的可执行文件名mpif77mpif90仍然存在,但它们都是指向mpifort的符号链接。用户应立即停止使用这些旧名称,并始终使用mpifort

    类似地,Open MPI的configure脚本仅识别FCFCFLAGS环境变量(分别用于指定Fortran编译器和编译器标志)。而F77FFLAGS环境变量会被忽略

    重要

    因此,强烈建议您指定一个通过文件后缀来区分Fortran代码格式(例如自由格式与固定格式)的Fortran编译器。例如,对于某些版本的IBM XLF编译器,使用FC=xlfFC=xlf90更可取,因为xlf会自动识别自由格式与固定格式的Fortran源代码差异。

    然而,许多Fortran编译器允许指定额外的命令行参数来指示使用哪种Fortran方言。例如,如果FC=xlf90,您可能需要使用mpifort --qfixed ...来编译固定格式的Fortran源文件。

    您可以使用ompi_infooshmem_info来查看Open MPI配置和编译时使用的Fortran编译器。

    根据您的Fortran编译器,最多可能提供三组Fortran MPI绑定:

    1. mpif.h: 这是MPI-1标准中定义的第一个Fortran接口。它是一个需要被包含在Fortran源代码中的文件。在Open MPI的mpif.h中唯一显式声明的接口是MPI_SIZEOF(由于其多态特性)。所有其他接口都是隐式的。

    2. mpi 模块:mpi 模块文件是在 MPI-2 中添加的。它为所有 MPI 接口提供了强大的编译时参数类型检查。

    3. mpi_f08 模块:mpi_f08 模块是在 MPI-3 中新增的。相比 mpif.h 文件和 mpi 模块,它提供了诸多优势。例如,MPI 句柄具有明确的类型(而不是全部为整数)。更多详情请参阅 MPI-3.0(或更新版本)标准

    重要

    强烈推荐在所有新的MPI Fortran子程序和应用程序中使用mpi_f08模块。需要注意的是,mpi_f08模块可以与另外两种Fortran MPI绑定在同一应用程序中配合使用(但每个子程序/函数只能使用一种绑定)。mpif.h/mpi模块与mpi_f08模块的MPI句柄类型之间提供了完全的互操作性,这使得mpi_f08可以在遗留MPI应用程序的新子程序中使用。

    根据OpenSHMEM规范,仅提供一种Fortran OpenSHMEM绑定:

    • shmem.fh: 所有Fortran OpenSHMEM程序都应包含 shmem.f,而使用OpenSHMEM定义常量的Fortran OpenSHMEM程序 必须包含shmem.fh

    以下注意事项适用于上述列出的Fortran绑定:

    • 所有Fortran编译器都支持基于mpif.h/shmem.fh的绑定,但有一个例外:只有当Open MPI使用支持INTERFACE关键字和ISO_FORTRAN_ENV的Fortran编译器构建时,才会包含MPI_SIZEOF接口。最值得注意的是,这排除了4.9版本之前的GNU Fortran编译器套件。

    • mpi模块提供的支持级别取决于您的Fortran编译器。

      如果Open MPI使用非GNU Fortran编译器构建,或者使用GNU Fortran编译器≥v4.9构建,所有MPI子程序都将在mpi模块中进行原型声明。因此,所有对MPI子程序的调用都将在编译时检查其参数类型。

      如果Open MPI使用旧版gfortran(即mpi模块。由于这些编译器的限制,并且根据MPI-3.0(及更高版本)规范的指导,所有带有"choice"缓冲区的MPI子程序将包含在mpi模块中,它们的参数也不会在编译时检查。具体来说,所有不带"choice"缓冲区的MPI子程序都会进行原型声明,并在运行时接受严格的参数类型检查(例如MPI_INITMPI_COMM_RANK等)。

      mpif.h接口类似,MPI_SIZEOF仅支持那些支持INTERFACEISO_FORTRAN_ENV的Fortran编译器。

    • mpi_f08模块已通过Intel Fortran编译器和gfortran ≥ 4.9版本的测试。其他现代Fortran编译器很可能也能兼容。

      许多较旧的Fortran编译器不具备足够的现代Fortran特性来支持mpi_f08模块。例如,gfortran v4.9以下版本就无法提供对mpi_f08模块的充分支持。

    您可以通过检查以下命令的输出,查看您的Open MPI安装中已启用或未启用的所有Fortran功能:

    shell$ ompi_info | grep -i fort