Ubuntu 自定义路径下安装 SLEPc/PETSc 以及 BLAS/LAPACK 科学计算库

引言

最近在计算矩阵特征值的问题上,用到了 SLEPc(Scalable Library for Eigenvalue Problem Computations),SLEPc 可用于超大稀疏矩阵特征值的快速并行计算,也可以用于其他 SVD 分解等常用矩阵计算。SLEPc 的安装依赖于其他通用科学计算库,比如 PETSc,BLAS/LAPACK 等,环境配置稍显复杂,因此,记录环境配置过程,以备后用。

依赖关系

SLEPc 是一个开源项目,可以在这里找到 https://github.com/firedrakeproject/slepc/ ,有非常详细的使用说明(documentation),使用友好。SLEPc 依赖于 PETSc,而 PETSc 依赖于 BLAS/LAPACK,因此,我们需要一一安装依赖项。

BLAS/LAPACK

BLAS(Basic Linear Algebra Subprograms)定义了一系列矩阵、向量之间的基础运算的接口标准(API),Netlib 实现了 BLAS 的这些接口,得到的库也叫 BLAS。以 BLAS 为基础,Netlib 增加了更多高级的矩阵、向量运算,如分解、求逆、特征值等,并且实现了这些高级接口,于是有了 LAPACK(Linear Algebra PackAage)。这两个库都是用 Fortran 语言开发的(另外插一句,CBLAS 和 CLAPACK 是 BLAS 和 LAPACK 的 C 语言接口)。

默认安装方式 [1] 为(没有试过... 应该不会有什么问题...)

1
2
sudo apt-get install libblas-dev
sudo apt-get install liblapack-dev
默认位置在
1
2
3
4
5
6
7
/usr/lib/x86_64-linux-gnu/libblas.a 
/usr/lib/x86_64-linux-gnu/libblas.so
/usr/local/lib/libblas.a

/usr/lib/x86_64-linux-gnu/liblapack.so
/usr/lib/x86_64-linux-gnu/liblapack.a
/usr/local/lib/liblapack.a

因为我需要安装在自定义路径中,所以下面进行一些自定义配置,如果不需要自定义路径,可以直接跳到 下一节

安装 Fortran 语言的编译器 gfortran

1
sudo apt-get install gfortran

安装 FFTW [2]

i. 下载 FFTW

http://www.fftw.org/download.html

ii. 安装 FFTW

1
2
3
4
5
6
7
tar -zxvf fftw-3.3.10.tar.gz
cd fftw-3.3.10/
# 下面尽可能多的使用了指令集优化,不需要的化可以去掉相应的选项
# cat /proc/cpuinfo 可以查看 cpu 支持的指令集
./configure --prefix=/your/path/to/install --enable-shared --enable-static --enable-single --enable-sse --enable-sse2 --enable-avx --enable-avx2 --enable-fma --enable-mpi --enable-threads --enable-openmp
make
make install

安装 BLAS/LAPACK [2]

i. 确保 cmake 和 gfortran 已经安装

ii. 下载 LAPACK

https://netlib.org/lapack/

幸运的是 LAPACK 中已经包含了 BLAS,所以不用重复下载。

iii. 安装 LAPACK

解压

1
2
tar -zxvf lapack-3.11.tar.gz
cd lapack-3.11
解压之后,它里面会含有 BLAS,CBLAS,LAPACKE 等文件夹。新建 make.inc 文件
1
cp make.inc.example make.inc
如果是使用 gfortran,则无须更改 make.inc 里的内容,否则需要根据系统环境和编译器修改文件里对应的选项。

LAPACK 依赖 BLAS,在编译 LAPACK 前需要编译 BLAS 包,而默认并不编译,因此,需要修改一下makefile

1
2
3
gedit Makefile
# or
# vim Makefile
将第 12~13
1
2
lib: lapacklib tmglib
#lib: blaslib variants lapacklib tmglib
修改为
1
2
#lib: lapacklib tmglib
lib: blaslib variants lapacklib tmglib
然后,进行编译
1
make
【重要】 接下来,进入 LAPACKE 目录并再次编译
1
2
cd LAPACKE
make
lapack-3.11 目录下生成如下四个静态库,liblapack.a, liblapacke.a, librefblas.a, libtmglib.a则表示编译成功,将这四个静态库拷贝到自定义路径下的 lib 路径,同时将 LAPACKE/include 目录下的头文件拷贝到自定义路径下的 include 目录。

安装 MPICH

PETSc 还依赖于 MPICH。

i. 下载 MPICH

https://www.mpich.org/downloads/

ii. 安装 MPICH

一般情况使用默认安装模式就可以了,如果需要自定义安装,可以查看 这里。 以下为默认安装的方式。

解压

1
2
tar -zxvf mpich-4.1.1.tar.gz
cd mpich-4.1.1
编译
1
2
3
./configure --prefix=/your/path/to/install 2>&1 | tee c.txt
make 2>&1 | tee m.txt
make install 2>&1 | tee mi.txt
添加环境变量,打开~/.bashrc,添加如下命令并重新打开 shell
1
export PATH=/your/path/to/install/bin:$PATH;
检查,如果一切正常,下面两个命令会输出你指定的安装路径/your/path/to/install/bin
1
2
which mpicc
which mpiexec
本地测试和结果
1
2
3
4
5
6
7
8
# to run the CPI example with 'n' processes on your local machine
mpiexec -n <number> ./examples/cpi

# if successfully installed, the outout will like this:
# Process 0 of 2 is on adt
# Process 1 of 2 is on adt
# pi is approximately 3.1415926544231318, Error is 0.0000000008333387
# wall clock time = 0.001997

PETSc 和 SLEPc 版本

由于 SLEPc 是基于 PETSc 的,所以需要先安装 PETSc,再安装 SLEPc。与此同时,要确保所下载的 PETSc 和 SLEPc 的版本能够符合 版本对应表

安装 PETSc

i. 下载 PETSc

https://petsc.org/release/install/download/

ii. 安装 PETSc

1
2
3
4
tar -zxvf petsc-3.18.5.tar.gz
cd petsc-3.18.5
./configure --with-shared-libraries=0 --with-blas-lib=/your/path/to/librefblas.a --with-lapack-lib=/your/path/to/liblapack.a --with-mpi-dir=/your/path/to/mpi
make check all
需要使用 PETSc 库,将 include 目录下的所有文件拷贝到安装目录 include 下指定位置,同时将 arch-linux-c-debug/include 目录下的所有头文件拷贝到安装目录 include 下指定位置,将 arch-linux-c-debug/lib/libpetsc.a 拷贝到安装目录 lib 下指定位置。

安装 SLEPc

i. 下载 SLEPc

https://slepc.upv.es/download/

ii. 安装 SLEPc

1
2
3
4
5
6
7
8
9
tar -zxvf slepc-3.18.3.tar.gz
cd slepc-3.18.3

export PETSC_DIR=/path/to/petsc-3.18.5 # 此处应为 PETSc 解压并且编译过的路径,如我这里为 petsc-3.18.5 的绝对路径
export PETSC_ARCH=arch/of/petsc # 此处应为 PETSc 编译时确定的当前编译版本的库的绝对路径,可以在 petsc-3.18.5 路径下找到 arch 开头的文件夹,如我这里为 arch-linux-c-debug
export SLEPC_DIR=/path/to/slepc-3.18.3 # 此处应为解压的 SLEPc 的路径

./configure
make check all
最后将 include 目录下的所有文件拷贝到安装目录 include 下指定位置,【重要】 同时,将 arch-linux-c-debug/include/slepcconf.h 拷贝到安装目录 include 下指定位置。将 arch-linux-c-debug/lib/libslepc.a 拷贝到安装目录 lib 下指定位置。

可能遇到的问题

在使用 SLEPc 时,编译工程的过程中,需要添加的头文件路径有

1
2
3
4
5
6
.../mpich/include
.../include/petsc
.../include/slepc
.../include/fftw
.../include/lapack

需要链接的库有
1
2
3
4
5
6
7
8
9
10
11
12
13
libslepc.a
libpetsc.a
libmpi.a
libmpicxx.a
libmpifort.a
liblapack.a
liblapacke.a
librefblas.a
libtmglib.a
libfftw3f.a
libfftw3f_mpi.a
libfftw3f_omp.a
libfftw3f_threads.a

如果遇到了 undefined reference to MPI_XXXX 的错误,还必须添加 OPENMPI 的头文件和库 [3]

1
2
3
4
5
6
7
# 添加头文件路径(或者你的 openmpi 安装路径)
/usr/lib/openmpi/include

# 添加库路径(或者你的 openmpi 安装路径)
/usr/lib/openmpi/lib
# 链接选项
-lmpi
如果没有安装 OPENMPI 的话,需要安装一下,使用sudo apt-get install openmpi,但是需要注意版本。

如果遇到了 undefined reference to symbol 'udev_device_unref@@LIBUDEV_183' 的问题,需要添加 libudev.so。用locate libudev 找到路径,然后添加库路径

1
2
3
4
# 路径
/usr/lib/x86_64-linux-gnu
# 链接选项
-ludev

如果遇到了undefined reference to symbol '__atomic_fetch_xor_16@@LIBATOMIC_1.0',需要添加

1
2
# 链接选项
-latomic

如果遇到了undefined reference to '_gfortran_concat_string',需要添加

1
2
# 链接选项
-lgfortran

如果遇到了undefined reference to XSetForeground (Maybe Some Drawing Functions),需要添加

1
2
# 链接选项
-lX11

参考

  • [1] Ubuntu BLAS/LAPACK 安装
  • [2] 非 ROOT 路径安装 BLAS/LAPACK
  • [3] undefined reference to MPI_Init 解决办法
请我喝杯咖啡吧。