CentOS7系統上的LAPACK源碼安裝
參考鏈接:linux下安裝blas和lapack
BLAS 和 LAPACK 這兩個數學庫是很多 Linux 科學計算軟件需要調用的,所以經常會用到。
LAPACK,其名為Linear Algebra PACKage的縮寫,是一以Fortran編程語言編寫,用於數值計算的函式集。LAPACK提供了豐富的工具函式,可用於諸如解多元線性方程式、線性系統方程組的最小平方解、計算特征向量、用於計算矩陣QR分解的Householder轉換、以及奇異值分解等問題。
LAPACK的源碼可以從http://www.netlib.org/lapack/處下載,BLAS也包含在其中。
BLAS,全稱Basic Linear AlgebraSubprograms,即基礎線性代數子程序庫,裏面擁有大量已經編寫好的關於線性代數運算的程序。
BLAS的源碼可以從 http://www.netlib.org/blas/ 下載,但實際上LAPACK中已經包含了BLAS。
0. 寫在前面的:
之前采用gfortran來編譯生成了lapack的庫文件,但是在後續采用pgf90命令(pgf90 -llapack)來編譯其它文件時,產生了以下的類似錯誤:
[[email protected] TEC_She]$ make pgf90 -g -fast -c m_bern.f90 pgf90 -g -fast -c d_inpkey.f90 pgf90 -g -fast -c p_menaux.f90 ... pgf90 -g -fast -o main_igsTec -L/usr/local/lib m_bern.o d_inpkey.o ... -llapack -lblas/usr/local/lib/liblapack.a(dormlq.o):在函數‘dormlq_’中: dormlq.f:(.text+0x32b):對‘_gfortran_concat_string’未定義的引用 dormlq.f:(.text+0x887):對‘_gfortran_concat_string’未定義的引用 /usr/local/lib/liblapack.a(dormqr.o):在函數‘dormqr_’中: dormqr.f:(.text+0x2f8):對‘_gfortran_concat_string’未定義的引用 dormqr.f:(.text+0x81c):對‘_gfortran_concat_string’未定義的引用/usr/local/lib/liblapack.a(ilaenv.o):在函數‘ilaenv_’中: ilaenv.f:(.text+0x58):對‘_gfortran_compare_string’未定義的引用 ilaenv.f:(.text+0x287):對‘_gfortran_compare_string’未定義的引用 ilaenv.f:(.text+0x2b4):對‘_gfortran_compare_string’未定義的引用 ilaenv.f:(.text+0x2d5):對‘_gfortran_compare_string’未定義的引用 ilaenv.f:(.text+0x2f4):對‘_gfortran_compare_string’未定義的引用 /usr/local/lib/liblapack.a(ilaenv.o):ilaenv.f:(.text+0x313): more undefined references to `_gfortran_compare_string‘ follow /usr/local/lib/liblapack.a(xerbla.o):在函數‘xerbla_’中: xerbla.f:(.text+0x49):對‘_gfortran_st_write’未定義的引用 xerbla.f:(.text+0x54):對‘_gfortran_string_len_trim’未定義的引用 xerbla.f:(.text+0x66):對‘_gfortran_transfer_character_write’未定義的引用 xerbla.f:(.text+0x76):對‘_gfortran_transfer_integer_write’未定義的引用 xerbla.f:(.text+0x7e):對‘_gfortran_st_write_done’未定義的引用 xerbla.f:(.text+0x87):對‘_gfortran_stop_string’未定義的引用 /usr/local/lib/liblapack.a(iparmq.o):在函數‘iparmq_’中: iparmq.f:(.text+0x150):對‘_gfortran_compare_string’未定義的引用 iparmq.f:(.text+0x16f):對‘_gfortran_compare_string’未定義的引用 iparmq.f:(.text+0x18f):對‘_gfortran_compare_string’未定義的引用 iparmq.f:(.text+0x273):對‘_gfortran_compare_string’未定義的引用 iparmq.f:(.text+0x28e):對‘_gfortran_compare_string’未定義的引用 /usr/local/lib/liblapack.a(iparam2stage.o):iparam2stage.F:(.text+0x263): more undefined references to `_gfortran_compare_string‘ follow make: *** [all] 錯誤 2
這是由於gfortran和pgf90編譯命令不同導致的,因而本文以PGI編譯器來執行lapack源代碼的編譯,即,Fortran程序采用pgf90命令,C程序采用pgcc命令來編譯,相應的具體過程及參數記錄如下。
1. 確保機器上安裝了PGI gfortran編譯器。如果沒有安裝的話,手動安裝:
sudo yum install gfortran
PGI編譯器需要去官網下載,具體安裝過程參見我的另一篇博客《CentOS 7上安裝PGI 2017編譯器》。
2. 下載blas, cblas, lapack 源代碼, 這些源碼都可以在http://www.netlib.org 上找到,下載並解壓。
我下載的版本是lapack-3.7.1.tgz,解壓之後會有一個文件夾,lapack-3.7.1,它含有BLAS,CBLAS,LAPACKE等文件夾,其中BLAS是BLAS的源碼,CBLAS是BLAS的C語言接口。
3. 這裏就是具體的編譯步驟
(1) 編譯blas
進入 BLAS/SRC 文件夾,執行以下幾條命令
cd BLAS/SRC
# gfortran -c -O3 *.f # 編譯所有的 .f 文件,生成 .o文件,這裏采用PGI編譯器的pgf90命令來編譯 pgf90-c -O3 *.f # 編譯所有的 .f 文件,生成 .o文件,這個pgf90編譯命令與~/lapack*/make.inc保持一致 ar rv libblas.a *.o # 鏈接所有的 .o文件,生成.a 文件 sudo cp libblas.a /usr/local/lib #將庫文件復制到系統庫目錄
(2) 編譯cblas
進入CBLAS 文件夾,首先根據你自己的計算機平臺,將目錄下某個 Makefile.XXX復制為 Makefile.in , XXX表示計算機的平臺,如果是linux,那麽就將Makefile.LINUX 復制為Makefile.in,然後執行以下命令
cd .. && cd ../CBLAS
cp ../BLAS/SRC/libblas.a ./testing/ # 將上一步編譯成功的 libblas.a復制到 CBLAS目錄下的testing子目錄 make # 編譯所有的目錄 sudo cp ../libcblas.a /usr/local/lib/libcblas.a #將庫文件復制到系統庫目錄下
(3) 編譯 lapack 以及 lapacke
這一步比較麻煩,首先進入lapack-3.7.1文件夾,然後根據平臺的特點,將該目錄下對應的 make.inc.example 文件另存為 make.inc ,再編輯 Makefile,編譯 lapack 和 lapacke 文件,並將 lapacke 目錄下的頭文件、lapack 目錄下生成的 *.a 文件拷貝到系統目錄(/usr/local/lib, /usr/lib)下。
cd ..
cp make.inc.example make.inc
vi Makefile # 修改 lapack-3.7.1/Makefile 文件,因為 lapack 依賴於 blas 庫 # 舊版本
lib: lapacklib tmglib #lib: blaslib variants lapacklib tmglib # 新版本
#lib: lapacklib tmglib lib: blaslib variants lapacklib tmglib
若采用PGI編譯器,則以下參數也要作修改:
...
# CC is the C compiler, normally invoked with options CFLAGS.
#
CC = pgcc # gcc
CFLAGS = -O3
# Modify the FORTRAN and OPTS definitions to refer to the compiler
# and desired compiler options for your machine. NOOPT refers to
# the compiler options desired when NO OPTIMIZATION is selected.
#
# Note: During a regular execution, LAPACK might create NaN and Inf
# and handle these quantities appropriately. As a consequence, one
# should not compile LAPACK with flags such as -ffpe-trap=overflow.
#
FORTRAN = pgf90 # gfortran
OPTS = -O2 -Mrecursive # -frecursive
DRVOPTS = $(OPTS)
NOOPT = -O0 -Mrecursive # -frecursive
# Define LOADER and LOADOPTS to refer to the loader and desired
# load options for your machine.
#
LOADER = pgf90 # gfortran
LOADOPTS =
# The archiver and the flag(s) to use when building an archive
# (library). If your system has no ranlib, set RANLIB = echo.
#
ARCH = ar
ARCHFLAGS = cr
RANLIB = ranlib
# Timer for the SECOND and DSECND routines
#
# Default: SECOND and DSECND will use a call to the
# EXTERNAL FUNCTION ETIME
#TIMER = EXT_ETIME
# For RS6K: SECOND and DSECND will use a call to the
# EXTERNAL FUNCTION ETIME_
#TIMER = EXT_ETIME_
# For gfortran compiler: SECOND and DSECND will use a call to the
# INTERNAL FUNCTION ETIME
#TIMER = INT_ETIME
# If your Fortran compiler does not provide etime (like Nag Fortran
# Compiler, etc...) SECOND and DSECND will use a call to the
# INTERNAL FUNCTION CPU_TIME
TIMER = INT_CPU_TIME
# If none of these work, you can use the NONE value.
# In that case, SECOND and DSECND will always return 0.
#TIMER = NONE
...
make # 編譯所有的lapack文件 cd LAPACKE # 進入LAPACKE 文件夾,這個文件夾包含lapack的C語言接口文件
make # 編譯lapacke
sudo cp include/*.h /usr/local/include #將lapacke的頭文件復制到系統頭文件目錄,
# 包括: lapacke.h, lapacke_config.h, lapacke_mangling.h,lapacke_mangling_with_flags.h lapacke_utils.h
cd .. # 返回到 lapack-3.7.1 目錄
sudo cp *.a /usr/local/lib # 將生成的所有庫文件復制到系統庫目錄,包括:liblapack.a, liblapacke.a, librefblas.a,libtmglib.a。
sudo cp *.a /usr/lib # 將生成的所有庫文件復制到系統庫目錄,包括:liblapack.a, liblapacke.a, librefblas.a,libtmglib.a
Ques: 事實上,編譯 lapack 時生成的 librefblas.a 文件與編譯 BLAS 時生成的 libblas.a 文件大小基本一樣,這裏生成了兩次,是否可以省去第(1)-(2)步?
至此blas,cblas 和 lapack 就成功安裝到你的電腦上了。
CentOS7系統上的LAPACK源碼安裝