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

水能载舟,亦可赛艇

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

目 录CONTENT

文章目录

🍓Linux 平台 CBLAS 编译报错集锦及解决方案

qiql
2022-07-15 / 0 评论 / 0 点赞 / 1,855 阅读 / 3,801 字

前言

目前需要给一台机器安装BLAS,CBLAS, LAPACK,本来是一件很简单的事情,常规的安装步骤参考:

https://blog.csdn.net/liu_feng_zi_/article/details/107336825

https://www.jianshu.com/p/33c4aea6117b

但是安装过程中出现各种错误,如下:

  1. 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
    
  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
    
  3. 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编译器。

小结

  1. blas可以直接用make命令进行编译
  2. blas需要用gcc进行编译,编译后的结果是 blas_LINUX.a 这个文件
  3. cblas需要用gcc进行编译,8.5或者11.2都可以,但是需要在Makefile.in中指定好BLLIB的路径
  4. 编译完cblas之后,如果想要顺利通过测试,需要修改源码,详见 github
  5. 使用gcc/11.2.0 的话,即使修改了源码,依然无法通过测试
0

评论区