侧边栏壁纸
博主头像
qiql博主等级

水能载舟,亦可赛艇

  • 累计撰写 33 篇文章
  • 累计创建 28 个标签
  • 累计收到 20 条评论

目 录CONTENT

文章目录

🎄Linux 平台 Linpack安装及调试指南【附安装脚本】

qiql
2022-07-15 / 0 评论 / 4 点赞 / 2,059 阅读 / 4,068 字

1 下载安装包

读者可以在文末的参考链接中找到 HPL[1], openMPI[2], OpenBLAS[3] 的下载页面,本文选择的版本为:

软件包 版本
HPL 2.3
openMPI 4.0.4
OpenBLAS 0.3.20

2 安装 OpenMPI

OpenMPI官网:https://www.open-mpi.org/

OpenMPI 需要手动编译安装,以下为本文的安装命令,读者可以根据自身情况修改路径

tar -zxvf /root/share/soft/pkgs/openmpi-4.0.4.tar.gz -C /root/share/soft/build
cd /root/share/soft/build/openmpi-4.0.4
## --prefix参数用于指定openmpi的安装路径
./configure --prefix=/root/share/soft/tool/openmpi/4.0.4
make -j
make install

单核编译 openMPI 大概需要半个小时,如果需要加速可以使用并行编译

编译完毕之后,需要声明一些环境变量

export OPENMPI_HOME=/root/share/soft/tool/openmpi/4.0.4
export PATH=$OPENMPI_HOME/bin:$PATH
export LD_LIBRARY_PATH=$OPENMPI_HOME/lib:$LD_LIBRARY_PATH
export LIBRARY_PATH=$OPENMPI_HOME/lib:$LIBRARY_PATH
export CPATH=$OPENMPI_HOME/include:$CPATH
export C_INCLUDE_PATH=$OPENMPI_HOME/include:$C_INCLUDE_PATH

这些环境变量只会存在于当前的会话窗口中,读者可以将其添加到自己的 bashrc 文件中或添加到 module 中,openmpi 的modulefile 文件见附录 2

安装完成之后,可以将 openMPI 添加到 module 中,便于管理

安装完成之后,可以用新编译得到的 mpi 编译用一下 helloworld 程序,源代码见附录 3

使用 mpicc 命令编译:mpicc -o hellowordlMPI ./helloworld.c

然后使用四个核心并行运行: mpirun -n 4 ./helloworldMPI

如果不报错说明 openMPI 安装成功

3 安装 BLAS

OpenBLAS 官网:https://www.openblas.net/

tar -zxvf /root/share/soft/pkg/OpenBLAS-0.3.20.tar.gz -C /root/share/soft/build/
cd /root/share/soft/build/openblas-0.3.20
make 
make PREFIX=/root/share/soft/tool/openblas/0.3.20 install

如果要用icc 编译openblas 采用 CC=icc FC=ifort make

4 安装 HPL

之前的 openMPI 和 OpenBLAS,本文将其安装在了 tool 目录中,意为工具,但 HPL 是一种应用,所以会将HPL放置在 app 目录中以作区分

mkdir -p /root/share/soft/app/hpl
tar -zxvf /root/share/soft/pkg/hpl-2.3.tar.gz -C /root/share/soft/app/hpl
cd /root/share/soft/app/hpl-2.3
# 进入setup目录选择一个后缀名和机器环境相近的文件复制到hpl的根目录,且将后缀进行更改,这个后缀很重要!读者也可以自定义这个后缀名,本文定义为qiql
cp setup/Make.Linux_PII_FBLAS ./Make.qiql

进入Make.qiql文件ma

# 
SHELL        = /bin/sh
#
CD           = cd
CP           = cp
LN_S         = ln -s
MKDIR        = mkdir
RM           = /bin/rm -f
TOUCH        = touch
#
# ----------------------------------------------------------------------
# - Platform identifier ------------------------------------------------
# ----------------------------------------------------------------------
#
ARCH         = qiql ## 这里修改成上文提到的那个后缀
#
# ----------------------------------------------------------------------
# - HPL Directory Structure / HPL library ------------------------------
# ----------------------------------------------------------------------
#
TOPdir       = /root/share/soft/app/hpl-2.3 ## 这里修改为hpl的全路径
INCdir       = $(TOPdir)/include
BINdir       = $(TOPdir)/bin/$(ARCH)
LIBdir       = $(TOPdir)/lib/$(ARCH)
#
HPLlib       = $(LIBdir)/libhpl.a 
#
# ----------------------------------------------------------------------
# - Message Passing library (MPI) --------------------------------------
# ----------------------------------------------------------------------
#
MPdir         = mpicc ## 除非读者使用的是 intel 的编译器,那么这个地方应该填写的是 mpiicc,否则都应该填写 mpicc
# MPinc        = -I$(MPdir)/include # 注释本行
# MPlib        = $(MPdir)/lib/libmpich.a # 注释本行
#
# ----------------------------------------------------------------------
# - Linear Algebra library (BLAS or VSIPL) -----------------------------
# ----------------------------------------------------------------------
# LAdir        = $(HOME)/netlib/ARCHIVES/Linux_PII # 注释本行
LAinc        = 
LAlib        =  -L/root/share/soft/tool/openblas/0.3.20/lib -lopenblas ## 这里将中间部分填写为 OpenBLAS 库的安装路径
#
# ----------------------------------------------------------------------
# - F77 / C interface --------------------------------------------------
F2CDEFS      = -DAdd__ -DF77_INTEGER=int -DStringSunStyle
#
# ----------------------------------------------------------------------
# - HPL includes / libraries / specifics -------------------------------
# ----------------------------------------------------------------------
#
HPL_INCLUDES = -I$(INCdir) -I$(INCdir)/$(ARCH) $(LAinc) $(MPinc)
HPL_LIBS     = $(HPLlib) $(LAlib) $(MPlib)
#
# - Compile time options -----------------------------------------------
#
HPL_OPTS     = 
#
# ----------------------------------------------------------------------
#
HPL_DEFS     = $(F2CDEFS) $(HPL_OPTS) $(HPL_INCLUDES)
#
# ----------------------------------------------------------------------
# - Compilers / linkers - Optimization flags ---------------------------
# ----------------------------------------------------------------------
#
CC           = mpicc  # 这里可以直接填 mpicc
CCNOOPT      = $(HPL_DEFS)
CCFLAGS      = $(HPL_DEFS) -fomit-frame-pointer -O3 -funroll-loops -W -Wall
#
#
LINKER       = mpicc  # 这里也可以是mpicc
LINKFLAGS    = $(CCFLAGS)
#
ARCHIVER     = ar
ARFLAGS      = r
RANLIB       = echo
#
# ----------------------------------------------------------------------

修改完毕后,进入 Make.top 文件,将其中的 arch 字段也修改为 qiql

然后执行 make arch=qiql 以开始编译

编译完成后,会在 hpl 的根目录下生成 bin 目录,如果有 xhpl 这个可执行文件和 HPL.dat 配置文件,说明编译成功

5 调试 LInpack

调试 linpack 主要就在于修改 HPL.dat 这个输入文件,这个应用本质上就是在解一个线性方程组,所以需要对方程组的块大小,阶数,并行核数不断进行调整,使其能够充分发挥计算机的效能。目前有一些成熟的工具来生成此 HPL.dat 文件,参考:https://gitlab.fysik.su.se/hpc-support/hpl/-/tree/master

在运行之前,往往需要将 OpenBLAS 的库路径添加到环境变量 LD_LIBRARY_PATH 中去

export LD_LIBRARY_PATH=/root/share/soft/tool/openblas/0.3.20/gcc/11.2.0/lib:$LD_LIBRARY_PATH

HPL.dat 配置文件中各参数说明参考:http://muchong.com/t-2238311-1-pid-3

http://www.netlib.org/benchmark/hpl/tuning.html

一份可供参考的 HPL.dat 文件:

HPLinpack benchmark input file
Innovative Computing Laboratory, University of Tennessee
HPL.out      output file name (if any)
file         device out (6=stdout,7=stderr,file)
1            # of problems sizes (N)
318720       Ns
1            # of NBs
240          NBs
0            PMAP process mapping (0=Row-,1=Column-major)
1            # of process grids (P x Q)
8            Ps
16           Qs
16.0         threshold
3            # of panel fact
0 1 2        PFACTs (0=left, 1=Crout, 2=Right)
2            # of recursive stopping criterium
2 4          NBMINs (>= 1)
1            # of panels in recursion
2            NDIVs
3            # of recursive panel fact.
0 1 2        RFACTs (0=left, 1=Crout, 2=Right)
1            # of broadcast
0            BCASTs (0=1rg,1=1rM,2=2rg,3=2rM,4=Lng,5=LnM)
1            # of lookahead depth
0            DEPTHs (>=0)
2            SWAP (0=bin-exch,1=long,2=mix)
64           swapping threshold
0            L1 in (0=transposed,1=no-transposed) form
0            U  in (0=transposed,1=no-transposed) form
1            Equilibration (0=no,1=yes)
8            memory alignment in double (> 0)

运行命令为:

mpirun -n 128 --allow-run-as-root ./xhpl

6 报错集锦及解决方案

  • No rule to make target `Make.inc’. Stop.

    1. 详细报错信息

      Makefile:47: Make.inc: No such file or director
      make[2]: *** No rule to make target `Make.inc'.  Stop.
      
    2. 原因:这个错误主要是没有正确的修改配置文件导致的,从 Make.top 文件中可以看到这个 Make.inc 文件的来源:

      leaf             :
              - ( $(CD) $(le) ; $(MKDIR) $(arch) )
              - ( $(CD) $(le)/$(arch) ; \
                  $(LN_S) $(TOPdir)/Make.$(arch) Make.inc )
      

      前面的$(TOPdir) 变量是在 Make.qiql(qiql为自定义的后缀名)文件中定义的,所以如果在 Make.qiql 中没有正确的配置 $(TOPdir) ,就会出现这个错误

      注意:$(TOPdir) 是 hpl 的解压目录,该软件的解压与安装在同一目录,读者可以找到Make.top 这个文件所在的位置,然后执行pwd获取当前目录并填入

    3. 解决办法:该错误发生后,无法先执行 make arch=qiql clean 进行清理然后再执行 make arch=qiql 重新编译,清理时会报错,此时建议将整个hpl文件夹删除,重新开始配置和编译

  • gcc: error: mpicc/lib/libmpich.a: No such file or directory

    1. 详细报错信息

      mpicc -DAdd__ -DF77_INTEGER=int -DStringSunStyle  -I/home/wxsc/zhangw/GPFS/qiql/app/hpl-2.3/include -I/home/wxsc/zhangw/GPFS/qiql/app/hpl-2.3/include/qiql  -Impicc/include -fomit-frame-pointer -O3 -funroll-loops -W -Wall -o /home/wxsc/zhangw/GPFS/qiql/app/hpl-2.3/bin/qiql/xhpl HPL_pddriver.o         HPL_pdinfo.o           HPL_pdtest.o /home/wxsc/zhangw/GPFS/qiql/app/hpl-2.3/lib/qiql/libhpl.a  -L/home/wxsc/zhangw/GPFS/qiql/tool/openblas/0.3.20 -lopenblas mpicc/lib/libmpich.a
      gcc: error: mpicc/lib/libmpich.a: No such file or directory
      make[2]: *** [dexe.grd] Error 1
      
    2. 原因:这个错误是因为读者没有正确的理解安装 linpack 的过程,本文所安装的 openmpi,只是 mpi 接口的其中一种实现,除此以外,还有 mpich,intel-mpi等多种实现库,hpl-2.3 中的默认配置文件中使用的是 mpich。所以默认链接的是 libmpich.a 这个文件

      在前文的表述中,要求读者直接注释掉 Make 文件中的 MPinc 和 MPlib 变量,因为此时 MPdir 配置的已经是 mpicc,而 mpicc 已经存在于环境变量中PATH中了,mpicc 的库路径也都声明到了其他的环境变量中去了,程序在编译过程中,如果在 Make 文件中找不到,那么程序会自己在环境变量中去寻找,所以可以直接注释掉这两个变量,当然,读者也可以把这个地方写为实际安装的 openMPI 的 bin 目录,lib 目录,include 目录。

    3. 解决办法:见原因。修改完之后,无需删除整个 hpl 文件夹,执行 make arch=qiql clean 进行清理,然后编译( qiql 为自定义的后缀名)

  • /bin/ld: cannot find -lopenblas

    1. 详细报错信息

      mpicc -DAdd__ -DF77_INTEGER=int -DStringSunStyle  -I/home/wxsc/zhangw/GPFS/qiql/app/hpl-2.3/include -I/home/wxsc/zhangw/GPFS/qiql/app/hpl-2.3/include/qiql   -fomit-frame-pointer -O3 -funroll-loops -W -Wall -o /home/wxsc/zhangw/GPFS/qiql/app/hpl-2.3/bin/qiql/xhpl HPL_pddriver.o         HPL_pdinfo.o           HPL_pdtest.o /home/wxsc/zhangw/GPFS/qiql/app/hpl-2.3/lib/qiql/libhpl.a  -L/home/wxsc/zhangw/GPFS/qiql/tool/openblas/0.3.20 -lopenblas 
      /bin/ld: cannot find -lopenblas
      collect2: error: ld returned 1 exit status
      make[2]: *** [dexe.grd] Error 1
      
    2. 原因:编译 Linpack 需要一个数学库,这个库可以是 OpenBLAS,也可以是GotoBLAS,也可以是 intel 的 MKL,本文选择的是OpenBLAS,在编译时,linpack 需要能够链接到库的库文件( .so 或 .a 文件),所以需要在 Make.qiql 文件中声明 OpenBLAS 库的位置,为了简便起见,本文要求读者直接注释掉了LAdir, LAinc 变量,因为这两个变量实际上并未参与到 linpack 的编译链接过程。

      仔细观察这句命令: LAlib = -L/root/share/soft/tool/openblas/0.3.20/lib -lopenblas 其中的 -L 表示编译器会在/root/share/soft/tool/openblas/0.3.20/lib 路径下寻找需要的库文件, -lopenblas 表示编译器会在 -L 所指定的路径下搜索名为 openblas.so 或 openblas.a 的库文件,**而不会在所指定的路径的子目录下递归的寻找!**所以如果这里的配置出现问题,那么 linpack 在编译时就会报错说找不到 -lopenblas。

    3. 解决方案:仔细核对 openblas 是否安装成功,到 openblas 的安装目录下寻找是否有lib目录,看看lib目录下是否有相应的库文件,然后在配置 LAdir 时,仔细核对所填写的路径是否精确到了 openblas 的 lib 目录。另:在 -L 和其后所指定的路径之间,可以存在空格。修改完之后,无需删除整个 hpl 文件夹,执行 make arch=qiql clean 进行清理,然后编译(qiql为自定义的后缀名)

附录1 安装脚本

#!/usr/bin/bash
set -e
### 本文件为 linpack 的安装脚本,在执行本脚本之前,需要先指定一些配置
### 当前时间:2022年6月27日16:16:56

## 指定 OpenMPI 的安装包路径【可选】(默认与本脚本位于同一路径)
openmpi_pkg_dir=$(dirname $(readlink -f "$0"))
## 指定 OpenMPI 的 build 路径【可选】(默认与本脚本位于同一路径)
openmpi_build_dir=$(dirname $(readlink -f "$0"))/build
## 指定 OpenMPI 的版本号
openmpi_version=4.0.4
## 指定 OpenMPI 的安装路径
openmpi_install_dir=/to/your/path/openmpi/${openmpi_version}
# /home/wxsc/zhangw/GPFS/qiql/tool/openmpi/${openmpi_version}
## 指定 OpenBLAS 的安装包路径【可选】(默认与本脚本位于同一路径)
openblas_pkg_dir=$(dirname $(readlink -f "$0"))
## 指定 OpenBLAS 的 build 路径【可选】(默认与本脚本位于同一路径)
openblas_build_dir=$(dirname $(readlink -f "$0"))/build
## 指定 OpenBLAS 的版本号
openblas_version=0.3.20
## 指定 OpenBLAS 的安装路径
openblas_install_dir=/to/your/path/openblas/${openblas_version}
# /home/wxsc/zhangw/GPFS/qiql/tool/openblas/${openblas_version}
## 指定 HPL 的安装包路径【可选】(默认与本脚本位于同一路径)
hpl_pkg_dir=$(dirname $(readlink -f "$0"))
## 指定 HPL 的版本号
hpl_version=2.3
## 指定 HPL 的安装路径
hpl_install_dir=/to/your/path
# /home/wxsc/zhangw/GPFS/qiql/app
## 指定 hpl 的后缀,可以设置成任意名称
hpl_arch=qiql
### 指定完毕

## 开始安装 OpenMPI
echo "============================================================================="
echo "============================================================================="
echo "=================== start install openmpi-$openmpi_version} ================="
mkdir -p ${openmpi_build_dir}
tar -zxvf ${openmpi_pkg_dir}/openmpi-${openmpi_version}.tar.gz -C ${openmpi_build_dir}
cd ${openmpi_build_dir}/openmpi-${openmpi_version}
./configure --prefix=${openmpi_install_dir}
make -j
make install
## 安装 OpenMPI 完毕
echo "=================== openmpi has been install to ${openmpi_install_dir} ======"
echo "=================== install openmpi-${openmpi_version} finish ==============="
echo "============================================================================="
echo "============================================================================="


## 开始安装 OpenBLAS
echo "============================================================================="
echo "============================================================================="
echo "=================== start install OpenBLAS-$openblas_version} ==============="
mkdir -p ${openblas_build_dir}
tar -zxvf ${openblas_pkg_dir}/OpenBLAS-${openblas_version}.tar.gz -C ${openblas_build_dir}
cd ${openblas_build_dir}/OpenBLAS-${openblas_version}
make -j
make PREFIX=${openblas_install_dir} install
## 安装 OpenBLAS 完毕
echo "=================== OpenBLAS has been install to ${openblas_install_dir} ===="
echo "=================== install OpenBLAS-${openblas_version} finish ============="
echo "============================================================================="
echo "============================================================================="

## 开始安装 hpl
mkdir -p ${hpl_install_dir}
tar -zxvf ${hpl_pkg_dir}/hpl-${hpl_version}.tar.gz -C ${hpl_install_dir}
cd ${hpl_install_dir}/hpl-${hpl_version}

## 新建一个环境变量脚本,后面如果要使用hpl,需要 source 该脚本,脚本放置在hpl的根目录下
touch env.hpl.sh
## 将 OpenMPI 添加到环境变量中去
echo export OPENMPI_HOME=${openmpi_install_dir} > env.hpl.sh
echo export PATH=\$OPENMPI_HOME/bin:\$PATH >> env.hpl.sh
echo export LD_LIBRARY_PATH=\$OPENMPI_HOME/lib:\$LD_LIBRARY_PATH >> env.hpl.sh
echo export LIBRARY_PATH=\$OPENMPI_HOME/lib:\$LIBRARY_PATH >> env.hpl.sh
echo export CPATH=\$OPENMPI_HOME/include:\$CPATH >> env.hpl.sh
echo export C_INCLUDE_PATH=\$OPENMPI_HOME/include:\$C_INCLUDE_PATH >> env.hpl.sh
## OpenMPI 添加环境变量完毕
## 将编译得到的 OpenBLAS 库路径添加到环境变量中去
echo export LD_LIBRARY_PATH=${openblas_install_dir}/lib:\$LD_LIBRARY_PATH >> env.hpl.sh
## 添加完毕

cd ${hpl_install_dir}/hpl-${hpl_version}
source ./env.hpl.sh

# 进入setup目录选择一个后缀名和机器环境相近的文件复制到hpl的根目录,且将后缀进行更改,这个后缀很重要!
cp setup/Make.Linux_PII_FBLAS Make.${hpl_arch}

## 修改ARCH字段
sed -i "s/ARCH         = Linux_PII_FBLAS/ARCH         = ${hpl_arch}/g" ./Make.${hpl_arch}

## 修改TOPdir 为 hpl 的实际安装路径
# sed -i "s/TOPdir       = \$(HOME)\/hpl/TOPdir       = ${hpl_install_dir}\/hpl-${hpl_version}/g" ./Make.${hpl_arch}
sed -i "/TOPdir       = \$(HOME)\/hpl/a\\TOPdir       = ${hpl_install_dir}\/hpl-${hpl_version}" ./Make.${hpl_arch}
## 修改MPdir 为mpicc
sed -i "s/MPdir        = \/usr\/local\/mpi/MPdir        = mpicc/g" ./Make.${hpl_arch}

## 在MPinc字段前加注释#
sed -i 's/MPinc  */#&/g' ./Make.${hpl_arch}
## 在MPlib字段前加注释
sed -i 's/MPlib  */#&/g' ./Make.${hpl_arch}
## 在LAdir字段前加注释
sed -i 's/LAdir  */#&/g' ./Make.${hpl_arch}
## 在LAinc字段前加注释
sed -i 's/LAinc  */#&/g' ./Make.${hpl_arch}
## 在LAlib字段后添加 OpenBLAS 正确的路径
sed -i "/LAlib        =/a\\LAlib        = -L${openblas_install_dir}\/lib -lopenblas" ./Make.${hpl_arch}
## 将 CC 字段修改为 mpicc
sed -i 's/CC           = \/usr\/bin\/gcc/CC           = mpicc/g' ./Make.${hpl_arch}
## 将 LINKER 字段修改为mpicc
sed -i 's/LINKER       = \/usr\/bin\/g77/LINKER       = mpicc/g' ./Make.${hpl_arch}
## Make.${hpl_arch} 文件修改完毕

## 修改 Make.top 文件中的 arch 字段
sed -i "s/arch             = UNKNOWN/arch             = ${hpl_arch}/g" ./Make.top
## Make.top 文件修改完毕

## 编译 hpl
make arch=${hpl_arch}
## 编译完毕
echo "============================================================================="
echo "============================================================================="
echo "============================================================================="
echo "============================================================================="
echo "============================================================================="
echo "hpl has been install to ${hpl_install_dir}/hpl-${hpl_version}/bin/${hpl_arch}"
echo "openmpi-${openmpi_version} has been install to ${openmpi_install_dir}, openblas-${openblas_version} has been install to ${openblas_install_dir}"
echo "Before using hpl, please source the env.hpl.sh script in the ${hpl_install_dir}/hpl-${hpl_version} to add environment variables to the session"
echo "============================================================================="
echo "============================================================================="
echo "============================================================================="

set +e
### END

附录 2 openMPI 的 modulefile

#%Module

proc ModulesHelp { } {
  puts stderr "\tThis module adds openmpi compiled with default intel compiler."
}
module load gcc/11.2.0

set OPENMPI_HOME /root/share/soft/tool/openmpi/4.0.4

set MPI_ROOT $OPENMPI_HOME
prepend-path PATH $OPENMPI_HOME/bin
prepend-path LD_LIBRARY_PATH $OPENMPI_HOME/lib
prepend-path LIBRARY_PATH $OPENMPI_HOME/lib
prepend-path CPATH $OPENMPI_HOME/include
prepend-path C_INCLUDE_PATH $OPENMPI_HOME/include

# installed by qiql, 2022-06-24.

附录 3 MPI 测试并行程序

#include <mpi.h>
#include <stdio.h>

int main(int argc, char** argv) {
    // Initialize the MPI environment
    MPI_Init(NULL, NULL);

    // Get the number of processes
    int world_size;
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);

    // Get the rank of the process
    int world_rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);

    // Get the name of the processor
    char processor_name[MPI_MAX_PROCESSOR_NAME];
    int name_len;
    MPI_Get_processor_name(processor_name, &name_len);

    // Print off a hello world message
    printf("Hello world from processor %s, rank %d out of %d processors\n",
           processor_name, world_rank, world_size);

    // Finalize the MPI environment.
    MPI_Finalize();
}

  1. HPL 各版本下载页 ↩︎

  2. openMPI 各版本下载页 ↩︎

  3. OpenBLAS 各版本下载页 ↩︎

4

评论区