使用 Intel 编译器集合交叉编译 mpich-3.2

Cross-compile mpich-3.2 with Intel compilers collection

我正在使用 Parallel Studio 2019 中的英特尔编译器集合,并尝试针对最近的 CPU 构建 MPICH-3.2。我的 configure 情景:

MPICHLIB_CFLAGS="-xCORE-AVX512" \
MPICHLIB_CXXFLAGS="-xCORE-AVX512" \
MPICHLIB_FCFLAGS="-xCORE-AVX512" \
MPICHLIB_FFLAGS="-xCORE-AVX512" \
LDFLAGS="-Wl,--disable-new-dtags" \
./configure \
CC="/opt/intel/bin/icc" \
CXX="/opt/intel/bin/icpc" \
FC="/opt/intel/bin/ifort" \
F77="/opt/intel/bin/ifort" \
--with-pic \
--enable-shared \
AR="ar" \ 
RANLIB="ranlib" \ 
--enable-f77 \
--enable-fc \
--enable-cxx \
--enable-fast=all,nompit \
--prefix=/usr \
--host=x86_64-pc-linux-gnu \
--with-cross=/root/fort.types

/root/fort.types 包含:

CROSS_F77_SIZEOF_INTEGER=4
CROSS_F77_SIZEOF_REAL=4
CROSS_F77_SIZEOF_DOUBLE_PRECISION=8
CROSS_F77_TRUE_VALUE=1
CROSS_F77_FALSE_VALUE=0
CROSS_F90_ADDRESS_KIND=8
CROSS_F90_INTEGER_KIND=4

configure 成功完成但构建失败并出现以下错误:

CC       src/glue/romio/lib_libmpi_la-all_romio_symbols.lo
src/binding/fortran/use_mpi/create_f90_real.c(75): error: expected an expression
    { MPIR_F90_REAL_MODEL, MPI_REAL},
                         ^

src/binding/fortran/use_mpi/create_f90_real.c(76): error: expected an expression
    { MPIR_F90_DOUBLE_MODEL, MPI_DOUBLE_PRECISION } };
                           ^

compilation aborted for src/binding/fortran/use_mpi/create_f90_real.c (code 2)
make[2]: *** [src/binding/fortran/use_mpi/lib_libmpi_la-create_f90_real.lo] Error 1
make[2]: *** Waiting for unfinished jobs....
src/binding/fortran/use_mpi/create_f90_complex.c(76): error: expected an expression
    { MPIR_F90_REAL_MODEL, MPI_COMPLEX},
                         ^

src/binding/fortran/use_mpi/create_f90_complex.c(77): error: expected an expression
    { MPIR_F90_DOUBLE_MODEL, MPI_DOUBLE_COMPLEX } };
                           ^

compilation aborted for src/binding/fortran/use_mpi/create_f90_complex.c (code 2)
make[2]: *** [src/binding/fortran/use_mpi/lib_libmpi_la-create_f90_complex.lo] Error 1
make[2]: Leaving directory `/root/mpich-3.2'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/root/mpich-3.2'
make: *** [all] Error 2

我 google 关于这个并且发现 mpif90model.h isn't initialized 并且因此宏 MPIR_F90_* 是未定义的。上面有提到link:

More specifically, the binaries that are supposed to run and tell configure what it wants to know fail to link because configure tries to set rpath.

如何在不禁用 fortran 库的情况下针对 Intel 编译器交叉编译 MPICH-3.2?

我在 Docker 环境中以 SLES 11 SP4 作为容器编译 MPICH-3.2 OS。

问题已通过向 /root/fort.types 添加以下变量解决:

CROSS_F90_OFFSET_KIND=8
CROSS_F90_REAL_MODEL=6,37
CROSS_F90_DOUBLE_MODEL=15,307
CROSS_F90_INTEGER_MODEL=9
CROSS_F90_ALL_INTEGER_MODELS=2,1,4,2,9,4,18,8,
CROSS_F90_INTEGER_MODEL_MAP={2,1,1},{4,2,2},{9,4,4},{18,8,8},

MPICH-3.2 的 configure 似乎还没有准备好 jet 来构建交叉编译版本而没有一点 "magic"。 MPICH 项目的官方邮件列表对解决问题没有任何帮助。我希望我的发现对任何人都有帮助。

要添加到 ,您可以采取一些步骤来为 CROSS_ 变量找到合适的值,方法是针对任何目标手动构建和 运行 一些程序你喜欢的平台。我不认为这些步骤是英特尔编译器特有的;你只需要工作的 C 和 Fortran(交叉)编译器和一个工作的链接器。

作为参考,我使用 clanggfortran 执行了这些步骤。程序本身改编自 mpich-3.3.2.

中包含的 configure 脚本

CROSS_F90_OFFSET_KIND

您应该构建并运行以下程序:

      program main
      integer ii
      ii = selected_int_kind(16)
      open(8, file="conftest1.out", form="formatted")
      write (8,*) ii
      close(8)
      stop
      end

输出文件 conftest1.out 给出了您应该设置的值 CROSS_F90_OFFSET_KIND。就我而言,我得到以下输出:

           8

因此,我设置CROSS_F90_OFFSET_KIND=8


CROSS_F90_REAL_MODEL

您应该构建并运行以下程序:

      program main
      real aa
      open(8, file="pac_fconftest.out", form="formatted")
      write(8,*) precision(aa), ",", range(aa)
      close(8)
      end

输出文件 pac_fconftest.out 给出了您应该设置的值 CROSS_F90_REAL_MODEL。就我而言,我得到以下输出:

           6 ,          37

因此,我设置CROSS_F90_REAL_MODEL=6,37


CROSS_F90_DOUBLE_MODEL

您应该构建并运行以下程序:

      program main
      double precision aa
      open(8, file="pac_fconftest.out", form="formatted")
      write(8,*) precision(aa), ",", range(aa)
      close(8)
      end

输出文件 pac_fconftest.out 给出了您应该设置的值 CROSS_F90_DOUBLE_MODEL。就我而言,我得到以下输出:

          15 ,         307

因此,我设置CROSS_F90_DOUBLE_MODEL=15,307


CROSS_F90_INTEGER_MODEL

您应该构建并运行以下程序:

      program main
      integer aa
      open(8, file="pac_fconftest.out", form="formatted")
      write(8,*) range(aa)
      close(8)
      end

输出文件 pac_fconftest.out 给出了您应设置的值 CROSS_F90_INTEGER_MODEL。就我而言,我得到以下输出:

           9

因此,我设置CROSS_F90_INTEGER_MODEL=9


CROSS_F90_ALL_INTEGER_MODELS

您应该构建并运行以下程序:

      program main
      integer r, lastkind
      lastkind=selected_int_kind(1)
      open(8, file="pac_fconftest.out", form="formatted")
      do r=2,30
         k = selected_int_kind(r)
         if (k .ne. lastkind) then
            write(8,*) r-1, ",", lastkind
            lastkind = k
         endif
         if (k .le. 0) then
            exit
         endif
      enddo
      if (k.ne.lastkind) then
         write(8,*) 31, ",", k
      endif
      close(8)
      end

输出文件 pac_fconftest.out 给出了您应该设置的值 CROSS_F90_ALL_INTEGER_MODELS。就我而言,我得到以下输出:


           2 ,           1
           4 ,           2
           9 ,           4
          18 ,           8

因此,我设置CROSS_F90_ALL_INTEGER_MODELS=2,1,4,2,9,4,18,8


CROSS_F90_INTEGER_MODEL_MAP

首先,您需要构建一个提供 cisize 函数的 C 文件。

int cisize_(char *,char*);
int cisize_(char *i1p, char *i2p)
{
  int isize_val=0;
  isize_val = (int)(i2p - i1p);
  return isize_val;
}

然后,对于 CROSS_F90_ALL_INTEGER_MODELS 的输出中的每一行,让 $range 成为第一个整数,让 $offset 成为第二个整数。编译以下程序,将给定行替换为 $range$offset,并将其替换为 运行。

      program main
      integer (kind=$kind) a(2)
      integer cisize
      open(8, file="pac_fconftest.out", form="formatted")
      write(8,*) $range, ",", $kind, ",", cisize( a(1), a(2) )
      close(8)
      end

运行为每一行运行此程序后,您可以将所有输出连接在一起。 (请记住,上面的程序每次都会输出到同一个文件 pac_fconftest.out。)在我的例子中,我的串联输出如下。

           2 ,           1 ,           1
           4 ,           2 ,           2
           9 ,           4 ,           4
          18 ,           8 ,           8

因此,我设置CROSS_F90_INTEGER_MODEL_MAP={2,1,1},{4,2,2},{9,4,4},{18,8,8}