前言
目前需要给一台机器安装BLAS,CBLAS, LAPACK,本来是一件很简单的事情,常规的安装步骤参考:
https://blog.csdn.net/liu_feng_zi_/article/details/107336825
https://www.jianshu.com/p/33c4aea6117b
但是安装过程中出现各种错误,如下:
-
gfortran -O3 -c c_dblat1.f c_dblat1.f:214:48: 214 | CALL STEST1(DNRM2TEST(N,SX,INCX),STEMP,STEMP,SFAC) | 1 错误: Rank mismatch in argument ‘strue1’ at (1) (scalar and rank-1) c_dblat1.f:218:48: 218 | CALL STEST1(DASUMTEST(N,SX,INCX),STEMP,STEMP,SFAC) | 1 错误: Rank mismatch in argument ‘strue1’ at (1) (scalar and rank-1) make[1]: *** [Makefile:132:c_dblat1.o] 错误 1 make[1]: 离开目录“/mnt/sdb/soft/tool/cblas/3.10.0/gcc/11.2.0/CBLAS/testing” make: *** [Makefile:180:alltst] 错误 2
-
gfortran -o xscblat1 c_sblat1.o c_sblas1.o ../lib/cblas_LINUX.a /root/share/soft/tool/blas/3.10.0/icc/2019/BLAS-3.10.0/libblas.a ../lib/cblas_LINUX.a(cblas_srotg.o):在函数‘cblas_srotg’中: cblas_srotg.c:(.text+0x1):对‘srotg_’未定义的引用 ../lib/cblas_LINUX.a(snrm2sub.o):在函数‘snrm2sub_’中: snrm2sub.f:(.text+0x5):对‘snrm2_’未定义的引用 ../lib/cblas_LINUX.a(scnrm2sub.o):在函数‘scnrm2sub_’中: scnrm2sub.f:(.text+0x5):对‘scnrm2_’未定义的引用 /root/share/soft/tool/blas/3.10.0/icc/2019/BLAS-3.10.0/libblas.a(scopy.o):在函数‘scopy_’中: scopy.f:(.text+0x1f0):对‘_intel_fast_memcpy’未定义的引用 scopy.f:(.text+0x247):对‘_intel_fast_memcpy’未定义的引用 collect2: 错误:ld 返回 1 make[1]: *** [Makefile:72:xscblat1] 错误 1 make[1]: 离开目录“/mnt/sdb/soft/tool/cblas/3.10.0/gcc/11.2.0/CBLAS/testing” make: *** [Makefile:180:alltst] 错误 2 (base) [root@localhost CBLAS]# gfortran -o xscblat1 c_sblat1.o c_sblas1.o ../lib/cblas_LINUX.a /root/share/soft/tool/blas/3.10.0/icc/2019/BLAS-3.10.0/libblas.a /usr/bin/ld: 找不到 c_sblat1.o: 没有那个文件或目录 /usr/bin/ld: 找不到 c_sblas1.o: 没有那个文件或目录 /usr/bin/ld: 找不到 ../lib/cblas_LINUX.a: 没有那个文件或目录 collect2: 错误:ld 返回 1 (base) [root@localhost CBLAS]# gfortran -o xscblat1 c_sblat1.o c_sblas1.o ../lib/cblas_LINUX.a /root/share/soft/tool/blas/3.10.0/icc/2019/BLAS-3.10.0/libblas.a /usr/bin/ld: 找不到 c_sblat1.o: 没有那个文件或目录 /usr/bin/ld: 找不到 c_sblas1.o: 没有那个文件或目录 /usr/bin/ld: 找不到 ../lib/cblas_LINUX.a: 没有那个文件或目录 collect2: 错误:ld 返回 1
-
ar r ../lib/cblas_LINUX.a cblas_srotg.o cblas_srotmg.o cblas_srot.o cblas_srotm.o cblas_sswap.o cblas_sscal.o cblas_scopy.o cblas_saxpy.o cblas_sdot.o cblas_sdsdot.o cblas_snrm2.o cblas_sasum.o cblas_isamax.o sdotsub.o sdsdotsub.o snrm2sub.o sasumsub.o isamaxsub.o cblas_drotg.o cblas_drotmg.o cblas_drot.o cblas_drotm.o cblas_dswap.o cblas_dscal.o cblas_dcopy.o cblas_daxpy.o cblas_ddot.o cblas_dsdot.o cblas_dnrm2.o cblas_dasum.o cblas_idamax.o ddotsub.o dsdotsub.o dnrm2sub.o dasumsub.o idamaxsub.o cblas_cswap.o cblas_cscal.o cblas_csscal.o cblas_ccopy.o cblas_caxpy.o cblas_cdotu_sub.o cblas_cdotc_sub.o cblas_icamax.o cdotcsub.o cdotusub.o icamaxsub.o cblas_zswap.o cblas_zscal.o cblas_zdscal.o cblas_zcopy.o cblas_zaxpy.o cblas_zdotu_sub.o cblas_zdotc_sub.o cblas_dznrm2.o cblas_dzasum.o cblas_izamax.o zdotcsub.o zdotusub.o dzasumsub.o dznrm2sub.o izamaxsub.o cblas_scasum.o scasumsub.o cblas_scnrm2.o scnrm2sub.o cblas_sgemv.o cblas_sgbmv.o cblas_sger.o cblas_ssbmv.o cblas_sspmv.o cblas_sspr.o cblas_sspr2.o cblas_ssymv.o cblas_ssyr.o cblas_ssyr2.o cblas_stbmv.o cblas_stbsv.o cblas_stpmv.o cblas_stpsv.o cblas_strmv.o cblas_strsv.o cblas_dgemv.o cblas_dgbmv.o cblas_dger.o cblas_dsbmv.o cblas_dspmv.o cblas_dspr.o cblas_dspr2.o cblas_dsymv.o cblas_dsyr.o cblas_dsyr2.o cblas_dtbmv.o cblas_dtbsv.o cblas_dtpmv.o cblas_dtpsv.o cblas_dtrmv.o cblas_dtrsv.o cblas_cgemv.o cblas_cgbmv.o cblas_chemv.o cblas_chbmv.o cblas_chpmv.o cblas_ctrmv.o cblas_ctbmv.o cblas_ctpmv.o cblas_ctrsv.o cblas_ctbsv.o cblas_ctpsv.o cblas_cgeru.o cblas_cgerc.o cblas_cher.o cblas_cher2.o cblas_chpr.o cblas_chpr2.o cblas_zgemv.o cblas_zgbmv.o cblas_zhemv.o cblas_zhbmv.o cblas_zhpmv.o cblas_ztrmv.o cblas_ztbmv.o cblas_ztpmv.o cblas_ztrsv.o cblas_ztbsv.o cblas_ztpsv.o cblas_zgeru.o cblas_zgerc.o cblas_zher.o cblas_zher2.o cblas_zhpr.o cblas_zhpr2.o cblas_sgemm.o cblas_ssymm.o cblas_ssyrk.o cblas_ssyr2k.o cblas_strmm.o cblas_strsm.o cblas_dgemm.o cblas_dsymm.o cblas_dsyrk.o cblas_dsyr2k.o cblas_dtrmm.o cblas_dtrsm.o cblas_cgemm.o cblas_csymm.o cblas_chemm.o cblas_cherk.o cblas_cher2k.o cblas_ctrmm.o cblas_ctrsm.o cblas_csyrk.o cblas_csyr2k.o cblas_zgemm.o cblas_zsymm.o cblas_zhemm.o cblas_zherk.o cblas_zher2k.o cblas_ztrmm.o cblas_ztrsm.o cblas_zsyrk.o cblas_zsyr2k.o cblas_globals.o cblas_xerbla.o xerbla.o ar: ../lib/cblas_LINUX.a: 没有那个文件或目录 make[1]: *** [Makefile:238:all] 错误 1
编译BLAS
从 http://www.netlib.org/blas/ 获取到最新的安装包,解压,然后进入解压目录,我的路径为: /root/share/soft/tool/blas/3.10.0/icc/2019/
我先用了 icc 对 blas 进行编译
# 先用icc2019编译blas
cd /root/share/soft/tool/
mkdir blas && cd blas && mkdir 3.10.0 && cd 3.10.0 && mkdir icc && cd icc && mkdir 2019
tar -zxvf /root/share/soft/pkg/blas-3.10.0.tgz -C /root/share/soft/tool/blas/3.10.0/icc/
cd /root/share/soft/tool/blas/3.10.0/icc/
mv BLAS-3.10.0/ 2019/
cd 2019/
ifort -c -O3 *.f
ar rv libblas.a *.o
cp libblas.a /usr/local/lib
如果编译成功,那么就会在解压后的目录下,得到libblas.a这个文件,这个文件是编译 cblas 所需要的
编译CBLAS
从 http://www.netlib.org/blas/#_cblas 获取到cblas最新的安装包,我先是使用了 icc-2019 编译器对其进行编译,发现编译失败,执行的命令如下:
我的路径为:
/root/share/soft/tool/cblas/3.10.0/icc/2019
cd /root/share/soft/tool
mkdir cblas && cd cblas && mkdir 3.10.0 && cd 3.10.0 && mkdir icc && cd icc
tar -zxvf /root/share/soft/pkg/cblas-3.10.0.tgz -C /root/share/soft/tool/cblas/3.10.0/icc/
cd /root/share/soft/tool/cblas/3.10.0/icc/
mv CBLAS/ 2019/
cd 2019/
cp Makefile.LINUX Makefile.in
vim Makefile.in
# 在Makefile.in 中,进行如下修改,使其使用 icc 编译器进行编译
CC=icc
FC=ifort
BLLIB = /root/share/soft/tool/blas/3.10.0/icc/2019/libblas.a
# 保存并退出
执行 make 进行编译,但是报错:
icc -O3 -DADD_ -I../include -c cblas_cgemv.c
In file included from /usr/include/bits/floatn.h(119),
from /usr/include/stdlib.h(55),
from cblas_cgemv.c(9):
/usr/include/bits/floatn-common.h(214): error: invalid combination of type specifiers
typedef float _Float32;
^
In file included from /usr/include/bits/floatn.h(119),
from /usr/include/stdlib.h(55),
from cblas_cgemv.c(9):
/usr/include/bits/floatn-common.h(251): error: invalid combination of type specifiers
typedef double _Float64;
^
In file included from /usr/include/bits/floatn.h(119),
from /usr/include/stdlib.h(55),
from cblas_cgemv.c(9):
/usr/include/bits/floatn-common.h(268): error: invalid combination of type specifiers
typedef double _Float32x;
^
In file included from /usr/include/bits/floatn.h(119),
from /usr/include/stdlib.h(55),
from cblas_cgemv.c(9):
/usr/include/bits/floatn-common.h(285): error: invalid combination of type specifiers
typedef long double _Float64x;
^
compilation aborted for cblas_cgemv.c (code 2)
make[1]: *** [Makefile:245:cblas_cgemv.o] 错误 2
make[1]: 离开目录“/mnt/sdb/soft/tool/cblas/3.10.0/icc/2019/src”
make: *** [Makefile:147:allprecision] 错误 2
几番搜索无果,将 Makefile.in
文件中的 CC
改成 icc -no-gcc
后,仍然报相同的错,初步的猜测是icc自身的问题,所以更换编译器,使用gcc编译
目前机器上原本有一个8.5版本的gcc,但是后面又手动装了11.2.0版本的gcc,先用了gcc/11.2.0对其进行编译,命令如下:
cblas的路径为:
/root/share/soft/tool/cblas/3.10.0/gcc/11.2.0/
cd /root/share/soft/tool/cblas/3.10.0
mkdir gcc && cd gcc
tar -zxvf /root/share/soft/pkg/cblas-3.10.0.tgz -C /root/share/soft/tool/cblas/3.10.0/gcc/
cd /root/share/soft/tool/cblas/3.10.0/gcc/
mv CBLAS/ 11.2.0/
cd 11.2.0/
cp Makefile.LINUX Makefile.in
vim Makefile.in
# 在 Makefile.in 中,对其进行如下修改:
CC=gcc
FC=gfortran
BLLIB = /root/share/soft/tool/blas/3.10.0/icc/2019/libblas.a
# 保存退出 Makefile.in
然后执行make命令进行编译,报错:
gcc -I../include -O3 -DADD_ -c c_sblas1.c
gfortran -O3 -c c_sblat1.f
c_sblat1.f:214:48:
214 | CALL STEST1(SNRM2TEST(N,SX,INCX),STEMP,STEMP,SFAC)
| 1
错误: Rank mismatch in argument ‘strue1’ at (1) (scalar and rank-1)
c_sblat1.f:218:48:
218 | CALL STEST1(SASUMTEST(N,SX,INCX),STEMP,STEMP,SFAC)
| 1
错误: Rank mismatch in argument ‘strue1’ at (1) (scalar and rank-1)
make[1]: *** [Makefile:132:c_sblat1.o] 错误 1
make[1]: 离开目录“/mnt/sdb/soft/tool/cblas/3.10.0/gcc/11.2.0/testing”
更换 gcc/8.5.0 版本,重新编译
cd /root/share/soft/tool/cblas/3.10.0/gcc
tar -zxvf /root/share/soft/pkg/cblas-3.10.0.tgz -C /root/share/soft/tool/cblas/3.10.0/gcc/
cd /root/share/soft/tool/cblas/3.10.0/gcc/
mv CBLAS/ 8.5.0/
cd 8.5.0/
cp Makefile.LINUX Makefile.in
vim Makefile.in
# 在 Makefile.in 中,对其进行如下修改:
CC=gcc
FC=gfortran
BLLIB = /root/share/soft/tool/blas/3.10.0/icc/2019/libblas.a
# 保存退出 Makefile.in
# 更换gcc版本
module unload gcc/11.2.0
gcc -v
执行make命令进行编译,报错,信息如下:
gcc -I../include -O3 -DADD_ -c c_sblas1.c
gfortran -O3 -c c_sblat1.f
c_sblat1.f:214:48:
CALL STEST1(SNRM2TEST(N,SX,INCX),STEMP,STEMP,SFAC)
1
警告: Rank mismatch in argument ‘strue1’ at (1) (scalar and rank-1) [-Wargument-mismatch]
c_sblat1.f:218:48:
CALL STEST1(SASUMTEST(N,SX,INCX),STEMP,STEMP,SFAC)
1
警告: Rank mismatch in argument ‘strue1’ at (1) (scalar and rank-1) [-Wargument-mismatch]
gfortran -o xscblat1 c_sblat1.o c_sblas1.o ../lib/cblas_LINUX.a /root/share/soft/tool/blas/3.10.0/icc/2019/libblas.a
../lib/cblas_LINUX.a(cblas_srotg.o):在函数‘cblas_srotg’中:
cblas_srotg.c:(.text+0x1):对‘srotg_’未定义的引用
../lib/cblas_LINUX.a(snrm2sub.o):在函数‘snrm2sub_’中:
snrm2sub.f:(.text+0x5):对‘snrm2_’未定义的引用
../lib/cblas_LINUX.a(scnrm2sub.o):在函数‘scnrm2sub_’中:
scnrm2sub.f:(.text+0x5):对‘scnrm2_’未定义的引用
/root/share/soft/tool/blas/3.10.0/icc/2019/libblas.a(scopy.o):在函数‘scopy_’中:
scopy.f:(.text+0x1f0):对‘_intel_fast_memcpy’未定义的引用
scopy.f:(.text+0x247):对‘_intel_fast_memcpy’未定义的引用
collect2: 错误:ld 返回 1
make[1]: *** [Makefile:72:xscblat1] 错误 1
make[1]: 离开目录“/mnt/sdb/soft/tool/cblas/3.10.0/gcc/8.5.0/testing”
make: *** [Makefile:180:alltst] 错误 2
从错误上看,cblas源码貌似出现了问题,且在编译blas得到的libblas.a也有问题,一个一个排查吧
先修改源码,从 github 上查找到了类似问题,需要对CBLAS目录下的testing目录下的 c_sblat1.f
文件进行修改
跳转到214行处
CALL STEST1(SNRM2TEST(N,SX,INCX),STEMP,STEMP,SFAC)
CALL STEST1(SNRM2TEST(N,SX,INCX),STEMP(1),STEMP,SFAC)
ELSE IF (ICASE.EQ.8) THEN
* .. SASUMTEST ..
STEMP(1) = DTRUE3(NP1)
CALL STEST1(SASUMTEST(N,SX,INCX),STEMP,STEMP,SFAC)
CALL STEST1(SASUMTEST(N,SX,INCX),STEMP(1),STEMP,SFAC)
执行命令:
make clean
make
发现少了一个警告:
gfortran -o xscblat1 c_sblat1.o c_sblas1.o ../lib/cblas_LINUX.a /root/share/soft/tool/blas/3.10.0/icc/2019/libblas.a
../lib/cblas_LINUX.a(cblas_srotg.o):在函数‘cblas_srotg’中:
cblas_srotg.c:(.text+0x1):对‘srotg_’未定义的引用
../lib/cblas_LINUX.a(snrm2sub.o):在函数‘snrm2sub_’中:
snrm2sub.f:(.text+0x5):对‘snrm2_’未定义的引用
../lib/cblas_LINUX.a(scnrm2sub.o):在函数‘scnrm2sub_’中:
scnrm2sub.f:(.text+0x5):对‘scnrm2_’未定义的引用
/root/share/soft/tool/blas/3.10.0/icc/2019/libblas.a(scopy.o):在函数‘scopy_’中:
scopy.f:(.text+0x1f0):对‘_intel_fast_memcpy’未定义的引用
scopy.f:(.text+0x247):对‘_intel_fast_memcpy’未定义的引用
collect2: 错误:ld 返回 1
make[1]: *** [Makefile:72:xscblat1] 错误 1
make[1]: 离开目录“/mnt/sdb/soft/tool/cblas/3.10.0/gcc/8.5.0/testing”
make: *** [Makefile:180:alltst] 错误 2
现在,只能排查是不是 blas 的问题了,先使用 gcc/11.2.0 重新编译blas
命令如下:
cd /root/share/soft/tool/blas/3.10.0/
mkdir gcc && cd gcc
tar -zxvf /root/share/soft/pkg/blas-3.10.0.tgz -C /root/share/soft/tool/blas/3.10.0/gcc/
mv blas-3.10.0 11.2.0
# 检查 gcc 版本
module load gcc/11.2.0
gcc -v
这里可以直接使用 make 命令进行编译, 得到的 blas_LINUX.a 文件就是编译 CBLAS 所需要的
重新开始编译 cblas
cd /root/share/soft/tool/cblas/3.10.0/gcc/8.5.0
vim Makefile.in
# 将BLLIB修改如下:
BLLIB = /root/share/soft/tool/blas/3.10.0/gcc/11.2.0/blas_LINUX.a
# 保存并退出
# 检查gcc版本
module unload gcc/11.2.0
gcc -v
make clean
make
没有报错信息了,perfect
使用gcc/11.2.0重新编译cblas,这一次,只需要修改Makefile.in 中的BLLIB变量
cd /root/share/soft/tool/cblas/3.10.0/gcc/11.2.0
make clean
vim Makefile.in
# 找到BLLIB,修改如下:
BLLIB = /root/share/soft/tool/blas/3.10.0/gcc/11.2.0/blas_LINUX.a
# 保存并退出
module load gcc/11.2.0
make
仍然报错,信息如下:
ranlib ../lib/cblas_LINUX.a
make[1]: 离开目录“/mnt/sdb/soft/tool/cblas/3.10.0/gcc/11.2.0/src”
( cd testing && make all )
make[1]: 进入目录“/mnt/sdb/soft/tool/cblas/3.10.0/gcc/11.2.0/testing”
gcc -I../include -O3 -DADD_ -c c_sblas1.c
gfortran -O3 -c c_sblat1.f
c_sblat1.f:214:48:
214 | CALL STEST1(SNRM2TEST(N,SX,INCX),STEMP,STEMP,SFAC)
| 1
错误: Rank mismatch in argument ‘strue1’ at (1) (scalar and rank-1)
c_sblat1.f:218:48:
218 | CALL STEST1(SASUMTEST(N,SX,INCX),STEMP,STEMP,SFAC)
| 1
错误: Rank mismatch in argument ‘strue1’ at (1) (scalar and rank-1)
make[1]: *** [Makefile:132:c_sblat1.o] 错误 1
make[1]: 离开目录“/mnt/sdb/soft/tool/cblas/3.10.0/gcc/11.2.0/testing”
make: *** [Makefile:180:alltst] 错误 2
可以看到,其实编译已经成功了,因为已经得到了 cblas_LINUX.a 这个文件,只是在测试的时候出现了问题,看来的确是需要修改源码的,进入 testing
目录下的 c_sblat1.f
文件
跳转到214行处
CALL STEST1(SNRM2TEST(N,SX,INCX),STEMP,STEMP,SFAC)
CALL STEST1(SNRM2TEST(N,SX,INCX),STEMP(1),STEMP,SFAC)
ELSE IF (ICASE.EQ.8) THEN
* .. SASUMTEST ..
STEMP(1) = DTRUE3(NP1)
CALL STEST1(SASUMTEST(N,SX,INCX),STEMP,STEMP,SFAC)
CALL STEST1(SASUMTEST(N,SX,INCX),STEMP(1),STEMP,SFAC)
然后执行命令:
make clean
make
报错:
gfortran -o xscblat1 c_sblat1.o c_sblas1.o ../lib/cblas_LINUX.a /root/share/soft/tool/blas/3.10.0/gcc/11.2.0/blas_LINUX.a
gcc -I../include -O3 -DADD_ -c c_dblas1.c
gfortran -O3 -c c_dblat1.f
c_dblat1.f:214:48:
214 | CALL STEST1(DNRM2TEST(N,SX,INCX),STEMP,STEMP,SFAC)
| 1
错误: Rank mismatch in argument ‘strue1’ at (1) (scalar and rank-1)
c_dblat1.f:218:48:
218 | CALL STEST1(DASUMTEST(N,SX,INCX),STEMP,STEMP,SFAC)
| 1
错误: Rank mismatch in argument ‘strue1’ at (1) (scalar and rank-1)
make[1]: *** [Makefile:132:c_dblat1.o] 错误 1
make[1]: 离开目录“/mnt/sdb/soft/tool/cblas/3.10.0/gcc/11.2.0/testing”
make: *** [Makefile:180:alltst] 错误 2
虽然可以编译成功,但是测试依然报错,看来是代码实在太老了,要测试cblas提供的测试代码的话必须要用旧版本的gcc编译器。
小结
- blas可以直接用make命令进行编译
- blas需要用gcc进行编译,编译后的结果是
blas_LINUX.a
这个文件 - cblas需要用gcc进行编译,8.5或者11.2都可以,但是需要在Makefile.in中指定好BLLIB的路径
- 编译完cblas之后,如果想要顺利通过测试,需要修改源码,详见 github ,
- 使用gcc/11.2.0 的话,即使修改了源码,依然无法通过测试
评论区