在 CentOS 7 下编译安装 MPICH、GotoBLAS、HPL

关键字

HPL, BLAS, MPI, VSIPL, Linpack, CentOS, CentOS 7, MPICH, GotoBLAS

概述

HPL,简单讲即 High-Performance Linpack,全称是高性能分布式存储计算机 Linpack 基准的可移植实现。Linpack 是广泛使用的测试超级计算机系统浮点性能的基准测试软件包。通过对超级计算机采用高斯消元法求解一元 N 次稠密线性代数方程组的测试,来评价超级计算机的浮点计算性能。

Linpack 的结果按每秒浮点运算次数(Flops)表示。目前世界级的超算数量级在 P 级 Flops,更高数量级(1024 倍)计算机。在文末的超级计算机知识点介绍中,有相关的说明。

HPL 以源码形式提供,通常搭配 BLAS 库和 MPI 库,以及 VSIPL 库。本文使用 GotoBLAS 和 MPICH 库编译 HPL,以进行性能测试。

  • BLAS:Basic Linear Algebra Subprograms,基本线性代数子方程。
  • MPI:Message Passing Interface,高性能可以移植消息传递接口。
  • VSIPL:Vector Signal Image Processing Library,矢量信号图像处理库

本文旨在帮助读者在 CentOS 7 下顺利编译安装 HPL 最新版,本安装过程应已经过笔者反复测试,以确保成功。

如果按此文安装时遇到任何问题,请留言或通过【桃花岛】官方联系我们。

软件依赖

  • CentOS 7
  • HPL:hpl-2.3
  • BLAS:GotoBLAS2-1.13
  • MPICH:
  • gcc:c 编译器
  • gcc-c++:c++ 编译器
  • gcc-gfortran:fortran 编译器

具体步骤

安装编译工具

主要是 gcc 中的 gfortran,后面的 MPICH 库依赖它。

yum install gcc -y
yum install gcc-c++ -y
yum install gcc-gfortran -y
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.aliyun.com
* centos-sclo-rh: centos.ustc.edu.cn
* centos-sclo-sclo: centos.ustc.edu.cn
* epel: epel.scopesky.iq
* extras: mirrors.aliyun.com
* remi-php73: fr2.rpmfind.net
* remi-safe: ap.stykers.moe
* updates: mirrors.aliyun.com
Resolving Dependencies
--> Running transaction check
---> Package gcc-gfortran.x86_64 0:4.8.5-36.el7_6.2 will be installed
--> Processing Dependency: libquadmath-devel = 4.8.5-36.el7_6.2 for package: gcc-gfortran-4.8.5-36.el7_6.2.x86_64
--> Running transaction check
---> Package libquadmath-devel.x86_64 0:4.8.5-36.el7_6.2 will be installed
--> Finished Dependency Resolution


Dependencies Resolved


=========================================================================================================================================================================================================================================
Package                                                       Arch                                               Version                                                      Repository                                           Size
=========================================================================================================================================================================================================================================
Installing:
gcc-gfortran                                                  x86_64                                             4.8.5-36.el7_6.2                                             updates                                             6.7 M
Installing for dependencies:
libquadmath-devel                                             x86_64                                             4.8.5-36.el7_6.2                                             updates                                              53 k


Transaction Summary
=========================================================================================================================================================================================================================================
Install  1 Package (+1 Dependent package)


Total download size: 6.7 M
Installed size: 16 M
Is this ok [y/d/N]: y
Downloading packages:
(1/2): libquadmath-devel-4.8.5-36.el7_6.2.x86_64.rpm                                                                                                                                                              |  53 kB  00:00:00
(2/2): gcc-gfortran-4.8.5-36.el7_6.2.x86_64.rpm                                                                                                                                                                   | 6.7 MB  00:00:00
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                                                                                     14 MB/s | 6.7 MB  00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : libquadmath-devel-4.8.5-36.el7_6.2.x86_64                                                                                                                                                                             1/2
  Installing : gcc-gfortran-4.8.5-36.el7_6.2.x86_64                                                                                                                                                                                  2/2
  Verifying  : libquadmath-devel-4.8.5-36.el7_6.2.x86_64                                                                                                                                                                             1/2
  Verifying  : gcc-gfortran-4.8.5-36.el7_6.2.x86_64                                                                                                                                                                                  2/2


Installed:
  gcc-gfortran.x86_64 0:4.8.5-36.el7_6.2


Dependency Installed:
  libquadmath-devel.x86_64 0:4.8.5-36.el7_6.2


Complete!

安装后可以验证一下

[root@carbon ~]# gfortran -v
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)

安装 BLAS

选择编译安装 GotoBLAS

首先在官方下载解压,进入目录,指定平台编译安装。

首先查看 CPU 型号是 Intel 的 NEHALEM 架构还是 AMD 的 OPTERON 架构

cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq

返回

Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz

于是下方 make 命令,我们使用 NEHALEM 架构。

wget https://www.tacc.utexas.edu/documents/1084364/1087496/GotoBLAS2-1.13.tar.gz/b58aeb8c-9d8d-4ec2-b5f1-5a5843b4d47b
tar -xvf GotoBLAS2-1.13.tar.gz
cd GotoBLAS2
./configure
make CC=gcc BINARY=64 TARGET=NEHALEM
make install

如果编译出错时,可以执行

gmake clean

如果编译成功,显示如下

......
ar  -ru ../../libgoto2_nehalemp-r1.13.a sgetrs_N_single.o sgetrs_T_single.o sgetrs_N_parallel.o sgetrs_T_parallel.o dgetrs_N_single.o dgetrs_T_single.o dgetrs_N_parallel.o dgetrs_T_parallel.o cgetrs_N_single.o cgetrs_T_single.o cgetrs_R_single.o cgetrs_C_single.o cgetrs_N_parallel.o cgetrs_T_parallel.o cgetrs_R_parallel.o cgetrs_C_parallel.o zgetrs_N_single.o zgetrs_T_single.o zgetrs_R_single.o zgetrs_C_single.o zgetrs_N_parallel.o zgetrs_T_parallel.o zgetrs_R_parallel.o zgetrs_C_parallel.o
make[2]: Leaving directory `/root/GotoBLAS2/lapack/getrs'
make[1]: Leaving directory `/root/GotoBLAS2/lapack'
make -j 2 -C exports so
make[1]: Entering directory `/root/GotoBLAS2/exports'
perl ./gensymbol linux x86_64 _ 0 0 > linux.def
perl ./gensymbol linktest  x86_64 _ 0 0 > linktest.c
gcc -O2 -Wall -m64 -DF_INTERFACE_G77 -fPIC  -DSMP_SERVER -DMAX_CPU_NUMBER=2 -DASMNAME= -DASMFNAME=_ -DNAME=_ -DCNAME= -DCHAR_NAME=\"_\" -DCHAR_CNAME=\"\" -I.. -shared -o ../libgoto2_nehalemp-r1.13.so \
-Wl,--whole-archive ../libgoto2_nehalemp-r1.13.a -Wl,--no-whole-archive \
-Wl,--retain-symbols-file=linux.def -lm -lpthread -lm -lpthread
gcc -O2 -Wall -m64 -DF_INTERFACE_G77 -fPIC  -DSMP_SERVER -DMAX_CPU_NUMBER=2 -DASMNAME= -DASMFNAME=_ -DNAME=_ -DCNAME= -DCHAR_NAME=\"_\" -DCHAR_CNAME=\"\" -I.. -w -o linktest linktest.c ../libgoto2_nehalemp-r1.13.so  && echo OK.
OK.
rm -f linktest
make[1]: Leaving directory `/root/GotoBLAS2/exports'
ln -fs libgoto2_nehalemp-r1.13.so libgoto2.so


GotoBLAS build complete.


  OS               ... Linux             
  Architecture     ... x86_64               
  BINARY           ... 64bit                 
  C compiler       ... GCC  (command line : gcc)
  Fortran compiler ... G77  (command line : g77)
  Library Name     ... libgoto2_nehalemp-r1.13.a (Multi threaded; Max num-threads is 2)

The Message Passing Interface (MPI) standard

MPI 标准有许多提供商,虽然 yum 可以安装 mpich,但缺少编译需要的头文件和库文件,暂未找到解决办法。所以我们选择:

编译安装 mpich-3.3.1

下载 mpich,CentOS 版本的使用 fedora 库的版本

wget http://www.mpich.org/static/downloads/3.3.1/mpich-3.3.1.tar.gz
tar -xvf mpich-3.3.1.tar.gz 
cd mpich-3.3.1
./configure --prefix=/root/hpl/setmpich/
make
make install

make 成功的日志如下

rm -f src/binding/fortran/use_mpi/mpifnoext.h
sed -e 's/^C/\!/g' -e '/EXTERNAL/d' \
-e '/REAL\*8/d' \
-e '/DOUBLE PRECISION/d' \
-e '/MPI_WTICK/d' src/binding/fortran/mpif_h/mpif.h > src/binding/fortran/use_mpi/mpifnoext.h
  MOD      src/binding/fortran/use_mpi/mpi_constants.mod-stamp
  MOD      src/binding/fortran/use_mpi/mpi_sizeofs.mod-stamp
  MOD      src/binding/fortran/use_mpi/mpi_base.mod-stamp
  MOD      src/binding/fortran/use_mpi/mpi.mod-stamp
  GEN      lib/libmpifort.la
  CXX      src/binding/cxx/initcxx.lo
  CXXLD    lib/libmpicxx.la
  CC       src/env/mpichversion.o
  CCLD     src/env/mpichversion
  CC       src/env/mpivars.o
  CCLD     src/env/mpivars
cp -p src/env/mpicc.bash src/env/mpicc
cp -p src/env/mpifort.bash src/env/mpifort
cp -p src/env/mpicxx.bash src/env/mpicxx
make[2]: Leaving directory `/root/mpich-3.3.1'
Making all in examples
make[2]: Entering directory `/root/mpich-3.3.1/examples'
  CC       cpi.o
  CCLD     cpi
make[2]: Leaving directory `/root/mpich-3.3.1/examples'
make[1]: Leaving directory `/root/mpich-3.3.1'

make install 成功的日志如下

if [ ! -e /usr/local/share/doc/mpich ] ; then mkdir -p /usr/local/share/doc/mpich ; fi
if [ -s ./doc/userguide/user.pdf ] ; then /usr/bin/install -c -m 644 ./doc/userguide/user.pdf /usr/local/share/doc/mpich/user.pdf ; fi
if [ -s ./doc/installguide/install.pdf ] ; then /usr/bin/install -c -m 644 ./doc/installguide/install.pdf /usr/local/share/doc/mpich/install.pdf ; fi
if [ -s ./doc/logging/logging.pdf ] ; then /usr/bin/install -c -m 644 ./doc/logging/logging.pdf /usr/local/share/doc/mpich/logging.pdf ; fi
mkdir -p '/usr/local/include'
/usr/bin/install -c -m 644 src/binding/fortran/use_mpi/mpi.mod src/binding/fortran/use_mpi/mpi_sizeofs.mod src/binding/fortran/use_mpi/mpi_constants.mod src/binding/fortran/use_mpi/mpi_base.mod '/usr/local/include'
mkdir -p '/usr/local/include'
/usr/bin/install -c -m 644 src/binding/cxx/mpicxx.h src/binding/fortran/mpif_h/mpif.h src/include/mpi.h '/usr/local/include'
mkdir -p '/usr/local/lib/pkgconfig'
/usr/bin/install -c -m 644 src/packaging/pkgconfig/mpich.pc '/usr/local/lib/pkgconfig'
make[3]: Leaving directory `/root/mpich-3.3.1'
make[2]: Leaving directory `/root/mpich-3.3.1'
Making install in examples
make[2]: Entering directory `/root/mpich-3.3.1/examples'
make[3]: Entering directory `/root/mpich-3.3.1/examples'
make[3]: Nothing to be done for `install-exec-am'.
make[3]: Nothing to be done for `install-data-am'.
make[3]: Leaving directory `/root/mpich-3.3.1/examples'
make[2]: Leaving directory `/root/mpich-3.3.1/examples'
make[1]: Leaving directory `/root/mpich-3.3.1'

export 编译安装的目录 setmpich

#vim ~/.bashrc

加入内容后保存退出

export PATH=/root/hpl/setmpich/bin:$PATH
export LD_LIBRARY_PATH=/root/setmpich/lib:$LD_LIBRARY_PATH

source 命令使生效

#source ~/.bashrc

检查是否安装成功

[root@carbon ~]# which mpirun
/root/hpl/setmpich/bin/mpirun

编译 examples 试试

[root@carbon ~]# cd ~/mpich-3.3.1
[root@carbon mpich-3.3.1]# cd examples
[root@carbon examples]# mpicc -o hellow hellow.c
[root@carbon examples]# mpirun -np 4 ./hellow
Hello world from process 0 of 4
Hello world from process 1 of 4
Hello world from process 2 of 4
Hello world from process 3 of 4

编译 HPL

编译好 BLAS 和 MPI 后就有了编译 HPL 的基础。

我们建立 /root/hpl/ 目录用来下载编译 hpl

wget http://www.netlib.org/benchmark/hpl/hpl-2.3.tar.gz
tar -xvf hpl-2.3.tar.gz
cd /root/hpl/hpl-2.3
emacs Make.centos

编辑一个 Make.centos 配置文件

SHELL        = /bin/sh
CD           = cd
CP           = cp
LN_S         = ln -s
MKDIR        = mkdir
RM           = /bin/rm -f
TOUCH        = touch
ARCH         = centos
TOPdir       = $(HOME)/hpl/hpl-2.3
INCdir       = $(TOPdir)/include
BINdir       = $(TOPdir)/bin/$(ARCH)
LIBdir       = $(TOPdir)/lib/$(ARCH)
HPLlib       = $(LIBdir)/libhpl.a 
MPdir        = $(HOME)/hpl/setmpich
MPinc        = -I$(MPdir)/include
MPlib        = $(MPdir)/lib/libmpich.so
LAdir        = $(HOME)/GotoBLAS2
LAinc        =
LAlib        = $(LAdir)/libgoto2.a
F2CDEFS      =
HPL_INCLUDES = -I$(INCdir) -I$(INCdir)/$(ARCH) $(LAinc) $(MPinc) -lpthread
HPL_LIBS     = $(HPLlib) $(LAlib) $(MPlib) -lpthread
HPL_OPTS     = -DHPL_CALL_CBLAS
HPL_DEFS     = $(F2CDEFS) $(HPL_OPTS) $(HPL_INCLUDES)
CC           = $(MPdir)/bin/mpicc -lpthread
CCNOOPT      = $(HPL_DEFS)
CCFLAGS      = $(HPL_DEFS) -fomit-frame-pointer -O3 -funroll-loops
LINKER       = $(MPdir)/bin/mpif77
LINKFLAGS    = $(CCFLAGS)
ARCHIVER     = ar
ARFLAGS      = r
RANLIB       = echo

保存退出后执行:

make arch=centos

完成后,我们可以进入 bin/centos 目录,看到编译出的 HPL.dat 和 xhpl 文件了。

[root@carbon hpl-2.3]# cd bin/centos/
[root@carbon centos]# ls
HPL.dat  xhpl

执行性能基准测试

通过不断调整 HPL.dat 中的参数,进行 xhpl 性能测试,既可以获得报告。

参数详解请见官方文档:

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

相关内容可以另写一篇说明。

问题汇总

问题:使用 make 编译,报错:make[1]: *** [sgemm_oncopy.o] 错误 1

E  -UCOMPLEX -c -UDOUBLE -UCOMPLEX ../kernel/x86_64/gemm_ncopy_4.S -o sgemm_oncopy.o
../kernel/x86_64/gemm_ncopy_4.S: Assembler messages:
../kernel/x86_64/gemm_ncopy_4.S:192: Error: undefined symbol `RPREFETCHSIZE' in operation
../kernel/x86_64/gemm_ncopy_4.S:193: Error: undefined symbol `RPREFETCHSIZE' in operation
../kernel/x86_64/gemm_ncopy_4.S:194: Error: undefined symbol `RPREFETCHSIZE' in operation
../kernel/x86_64/gemm_ncopy_4.S:195: Error: undefined symbol `RPREFETCHSIZE' in operation
../kernel/x86_64/gemm_ncopy_4.S:197: Error: undefined symbol `WPREFETCHSIZE' in operation
../kernel/x86_64/gemm_ncopy_4.S:345: Error: undefined symbol `RPREFETCHSIZE' in operation
../kernel/x86_64/gemm_ncopy_4.S:346: Error: undefined symbol `RPREFETCHSIZE' in operation
../kernel/x86_64/gemm_ncopy_4.S:348: Error: undefined symbol `WPREFETCHSIZE' in operation
make[1]: *** [sgemm_oncopy.o] 错误 1
make[1]: *** 正在等待未完成的任务....
make[1]: Leaving directory `/home/chj/program/GotoBLAS2/kernel'
make: *** [libs] 错误 1

解决:添加编译选项

make CC=gcc BINARY=64 TARGET=NEHALEM

问题:No Fortran 77 compiler found

编译 mpich 时,执行 ./configure 提示 No Fortran 77 compiler found.

checking for shared library (esp. rpath) characteristics of CC... done (results in src/env/cc_shlib.conf)
configure: error: No Fortran 77 compiler found. If you don't need to
        build any Fortran programs, you can disable Fortran support using
        --disable-fortran. If you do want to build Fortran
        programs, you need to install a Fortran compiler such as gfortran
        or ifort before you can proceed.

解决:安装 gfortran 编译器

yum install gcc
yum install gcc-c++
yum install gcc-gfortran

问题: 直接安装 mpich 的 rpm 包提示依赖没有安装

[root@carbon ~]# rpm -i mpich-3.3.1-1.fc32.x86_64.rpm
error: Failed dependencies:
        (python(abi) = 3.8 if python3) is needed by mpich-3.3.1-1.fc32.x86_64
        environment(modules) is needed by mpich-3.3.1-1.fc32.x86_64
        libgfortran.so.5()(64bit) is needed by mpich-3.3.1-1.fc32.x86_64
        libgfortran.so.5(GFORTRAN_8)(64bit) is needed by mpich-3.3.1-1.fc32.x86_64
        libgfortran.so.5(GFORTRAN_9)(64bit) is needed by mpich-3.3.1-1.fc32.x86_64
        libhwloc.so.15()(64bit) is needed by mpich-3.3.1-1.fc32.x86_64
        libstdc++.so.6(CXXABI_1.3.8)(64bit) is needed by mpich-3.3.1-1.fc32.x86_64
        libstdc++.so.6(CXXABI_1.3.9)(64bit) is needed by mpich-3.3.1-1.fc32.x86_64
        rpmlib(PayloadIsZstd) <= 5.4.18-1 is needed by mpich-3.3.1-1.fc32.x86_64
        rpmlib(RichDependencies) <= 4.12.0-1 is needed by mpich-3.3.1-1.fc32.x86_64

解决:使用编译安装。 或者逐个安装依赖,这种方法未尝试。

知识点

TOP500

人类在对自然的探索中发现了问题,通过数学很好的定义了问题,甚至已经找到了解决问题的方法,但根据找到的方法,使用普通计算机按步骤求解的时长超出了问题的时间约束,有的甚至超越了人类平均的寿命。比如用个人电脑计算天气预报,不是算不出,理论上可以算,但算出来的天气概率和未来状态已经成为历史,起不到预报的效果,因此让求解失去了价值。于是人类造出超级机器解决需要超级计算的问题。而 HPL 正是衡量这些超级机器计算性能的软件。

自 1993 年,位于德国的 TOP500 每 6 个月发布世界上超级计算机的排名,这个排名便是依赖 Linpack 测试基准跑分。

K/M/G/P/T 和 Flops,KMGPT 很好理解,都是具体的数字,分别是(^是计算机中的次方计算符):

  • K=1024=2^10
  • M=2^20
  • G=2^30
  • T=2^40
  • P=2^50
  • Flops=Float per second

目前,直观的感受是,我们 CPU 主频通常在 1.x~3.x G,SSD 硬盘在 1 T 以下。能进到 P 级的计算能力的设备,就进入了世界级的俱乐部。

LINPACK 简介

我们会发现世界的复杂问题都可以通过对世界建模,再抽象为不同属性的对象,把不同对象属性放入矩阵,再对矩阵运算来求解是解决问题常用方法。

LINPACK 就是使用线性代数矩阵运算来度量计算系统性能的测试软件。它采用 C 和 Fortran 语言编写,经过编译,几乎可以运行在所有系统上。

LINPACK Benchmark 是由 Jack Dongarra 提出的,可以从 netlib 以 postscript 脚本形式获得详细描述,以及各种计算机上的性能结果列表。还可以下载 LINPACK 报告的最新版本:performance.ps。可在 http://www.netlib.org/benchmark/hpl/ 找到 Linpack 基准测试的并行实现,以及如何运行它的说明。

LINPACK Benchmark 中使用的基准是解稠密线性方程组。它允许用户扩展问题的规模并优化软件,以实现给定机器的最佳性能。我国超算神威太湖之光也有一个测试数值,它使用普通的硬件节点,以节点数量取胜,以前是世界排名第一,从数值上刚被反超,成为第三。但此性能数值不能反映给定系统的整体性能,因为没有任何一个数值可以做到。但是,它确实反映了用于求解密集线性方程组的专用系统的性能。

详细来说,通过测量不同问题大小 n 的实际性能,用户不仅可以获得问题大小 Nmax 的最大已达到性能 Rmax,而且可以获得获得性能 Rmax 一半的问题大小 N1/2。这些数值以及理论峰值性能 Rpeak 是 TOP500 中给出的数字。

发表评论

电子邮件地址不会被公开。 必填项已用*标注