我的AI之路(12)--如何配置Caffe使用GPU计算并解决编译中出现的若干错误

前面说过(安装Anaconda3 和Caffe),在github上下载Caffe源码后,安装以下依赖包:

dnf install autoconf automake

dnf install protobuf-devel boost-devel openblas-devel opencv-devel leveldb-devel lmdb-devel hdf5-devel gflags-devel glog-devel lmdb-devel snappy-devel 

把Caffe配置成使用CPU计算,即可编译成功。

把Caffe配置成使用GPU计算,需要在安装好CUDA和cuDNN后,把Makefile.config里把

USE_CUDNN := 1

前面的注释去掉,把

CPU_ONLY := 1

注释掉。

对于CUDA_ARCH的设置,注意看前面的注释说明,由于我安装的是CUDA9.0不再支持2.0计算架构,需要把

扫描二维码关注公众号,回复: 3194991 查看本文章

-gencode arch=compute_20,code=sm_20 \

-gencode arch=compute_20,code=sm_21 \

注释掉,不然后下面编译时报错。

然后执行:

make clean

make -j

重新编译出支持GPU的caffe release build. 

但是编译GPU版Caffe时还需要安装一些支持包,不然编译过程中会报很多错。

1)下载boost源码并编译安装生成filesystem,system,thread,python库文件

wget https://dl.bintray.com/boostorg/release/1.65.1/source/boost_1_65_1.tar.gz
# 下载完成后
tar -xzf boost_1_65_1.tar.gz
cd boost_1_65_1

boost默认只生成python2版本的库,需要生成python3的库的话,使用sudo find / -name "python3.6m" 找到你系统下的 python3.6m头文件所在路径,使用which python3 找到你系统下 python3 二进制文件所在路径,我安装的是Anaconda3提供的Python3.6。把如下内容添加到./bootstrap.sh文件里自动生成project-config.jam的语句之间:

cat>project-config.jam<<EOF

...

import option;

import feature;

echo "using mpi ;

using gcc :  : g++ ;
using python : 3.6 : /home/fychen/anaconda3/bin/python3 : /home/fychen/anaconda3/include/python3.6m : /home/fychen/anaconda3/lib ;"
 
然后执行
./bootstrap.sh --with-python=/home/fychen/anaconda3/bin/python --with-python-version=3.6 --with-python-root=/home/fychen/anaconda3 --with-libraries=filesystem,system,thread,python --prefix=/usr/local
sudo ./b2 install

生成filesystem,system,thread,python3库文件并安装到/usr/local下。

2)下载gflags源码并编译安装

wget https://github.com/gflags/gflags/archive/v2.2.1.tar.gz

tar -xzf v2.2.1.tar.gz

cd gflags-2.2.1

mkdir build
cd build
cmake ..
ccmake ..
make

sudo make install

3)下载glog源码并编译安装

wget https://github.com/google/glog/archive/v0.3.5.tar.gz

tar -xzf v0.3.5.tar.gz

cd glog-0.3.5

./configure  --prefix=/usr/local
make

sudo make install

4)下载hdf5 1.8版源码并编译安装(注意,只能使用1.8版或更早版本,不要使用1.10版本(比如hdf5-1.10.2.tar.gz),因为1.10版和以前的版本是不兼容的,并且使用1.10版会导致Caffe在后面make runtest时报错,后面再说这个错误)

wget https://support.hdfgroup.org/ftp/HDF5/current18/src/hdf5-1.8.20.tar.gz

tar -xzf hdf5-1.8.20.tar.gz

cd hdf5-1.8.20

./configure  --prefix=/usr/local/hdf5
make

sudo make install

5)下载libtool源码并编译安装 #如果使用dnf install libtool,可能会要求先更新升级gcc/g++版本,这可能会引起混乱

wget http://ftp.gnu.org/gnu/libtool/libtool-2.4.6.tar.gz

tar -xzf libtool-2.4.6.tar.gz

cd libtool-2.4.6

./configure --prefix=/usr
make

sudo make install

6)下载protobuf源码并编译安装

wget https://github.com/google/protobuf/archive/v3.6.0.tar.gz

tar -xzf v3.6.0.tar.gz

cd protobuf-3.6.0

./autogen.sh
./configure  --prefix=/usr/local
make

sudo make install

7)下载lmdb源码并编译安装

wget https://github.com/LMDB/lmdb/archive/LMDB_0.9.22.tar.gz

tar -xzf LMDB_0.9.22.tar.gz

cd LMDB_0.9.22

make

sudo make install

8)下载leveldb源码并编译安装

wget https://github.com/google/leveldb/archive/v1.20.tar.gz

tar -xzf v1.20.tar.gz

cd leveldb-1.20

make
sudo cp -rf include/leveldb /usr/local/include

sudo cp -rf out-shared/libleveldb.so* /usr/local/lib 

9)下载snappy源码并编译安装

wget https://github.com/google/snappy/archive/1.1.7.tar.gz

tar -xzf 1.1.7.tar.gz

cd snappy-1.1.7

mkdir build
cd build
cmake ..
ccmake ..  
make
sudo make install

10)下载OpenBLAS源码并编译安装

wget https://github.com/xianyi/OpenBLAS/archive/v0.3.0.tar.gz

tar -xzf v0.3.0.tar.gz

cd OpenBLAS-0.3.0

make

sudo make PREFIX=/usr/local install

11)下载OpenCV3.4源码并编译安装

wget https://github.com/opencv/opencv/archive/3.4.1.tar.gz

tar -xzf opencv-3.4.1

cd opencv-3.4.1

mkdir build
cd build
cmake ..
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..
make
sudo make install

在编译OpenCV3过程中需要解决多个编译错误,参见 如何解决在Linux下编译OpenCV3时出现的多个错误

安装完以上包后,继续执行make -j编译Caffe,出现如下错误:

/usr/local/lib/libopencv_core.so:对‘dgeqrf_’未定义的引用
/usr/local/lib/libopencv_core.so:对‘sposv_’未定义的引用
/usr/local/lib/libopencv_core.so:对‘sgesdd_’未定义的引用
/usr/local/lib/libopencv_core.so:对‘sgeqrf_’未定义的引用
/usr/local/lib/libopencv_core.so:对‘dgesv_’未定义的引用
/usr/local/lib/libopencv_core.so:对‘sgels_’未定义的引用
/usr/local/lib/libopencv_core.so:对‘sgesv_’未定义的引用
/usr/local/lib/libopencv_core.so:对‘dgetrf_’未定义的引用
/usr/local/lib/libopencv_core.so:对‘sgetrf_’未定义的引用
/usr/local/lib/libopencv_core.so:对‘spotrf_’未定义的引用
/usr/local/lib/libopencv_core.so:对‘dgels_’未定义的引用
/usr/local/lib/libopencv_core.so:对‘dgesdd_’未定义的引用
/usr/local/lib/libopencv_core.so:对‘dposv_’未定义的引用
/usr/local/lib/libopencv_core.so:对‘dpotrf_’未定义的引用

这些函数是lapack里的,之所以不认识,应该是上面使用源码编译和安装OpenBLAS v0.3.0.tar.gz时lapack没有关联编译安装成功(原因应该是v0.3.0.tar.gz里面集成的netlib-lapack是lapack3.8.0版,我做过实验,下载lapack3.8.0版源码(wget http://www.netlib.org/lapack/lapack-3.8.0.tar.gz ),然后用dnf install gcc-gfortran安装gfortran,然后编译lapack3.8.0,结果报错:

gfortran  -o testlsame lsame.o lsametst.o
collect2: fatal error: cannot find 'ld'
compilation terminated.

,如果下载lapack3.7.0源码(http://www.netlib.org/lapack/lapack-3.7.0.tgz)来编译则没有任何问题,所以我怀疑因为OpenBLAS v0.3.0.tar.gz集成的是lapack3.8.0,在编译OpenBLAS v0.3.0时因为错误并没有自动关联编译和安装lapack,所造成上面编译Caffe时报错),需要用dnf install gcc-gfortran 安装gfortran并手工下载源码包lapack-3.7.0(http://www.netlib.org/lapack/lapack-3.7.0.tgz)和BLAS-3.8.0.tar源码包(http://www.netlib.org/blas/blas-3.8.0.tgz)后手工编译和安装BLAS-3.8.0和lapack-3.7.0。

修改BLAS的make.inc,增加-fPIC标志,并修改要生成的BLASLIB文件的名字:

OPTS     = -O3 -fPIC

NOOPT     = -fPIC

BLASLIB      = libblas$(PLAT).a

如果除了生成默认的libblas_LINUX.a文件外,你想生成so文件,则需要修改BLAS-3.8.0的Makefile,增加生成libblas.so库文件:

$(BLASLIB): $(ALLOBJ)
$(ARCH) $(ARCHFLAGS) $@ $(ALLOBJ)
$(CC) -shared -fPIC $(ALLOBJ) -o libblas.so
$(RANLIB) $@

然后执行make生成libblas_LINUX.a和libblas.so。如果想安装到/usr/local/lib/下,执行cp libblas_LINUX.a libblas.so /usr/local/lib/

然后修改lapack-3.7.0的make.inc,增加-fPIC标志,定义CC变量和修改BLASLIB变量,指向libblas库文件的所在路径:

OPTS     = -O2 -frecursive -fPIC

...

NOOPT    = -O0 -frecursive -fPIC

...

CC = gcc

CFLAGS = -O3

...

BLASLIB     = -lblas -L /usr/local/lib

如果想增加生成liblapack.so库文件,需修改lapack-3.7.0/SRC/Makefile:

../$(LAPACKLIB): $(ALLOBJ) $(ALLXOBJ) $(DEPRECATED)
$(ARCH) $(ARCHFLAGS) $@ $(ALLOBJ) $(ALLXOBJ) $(DEPRECATED)
$(CC) -shared -fPIC $(ALLOBJ) $(ALLXOBJ) -lgfortran -lm -o liblapack.so
$(RANLIB) $@

执行make编译lapack-3.7.0报错:

ztplqt.o:在函数‘ztplqt_’中:
ztplqt.f:(.text+0x0): ztplqt_ 的多重定义
ztplqt.o:ztplqt.f:(.text+0x0):第一次在此定义
ztplqt2.o:在函数‘ztplqt2_’中:
ztplqt2.f:(.text+0x0): ztplqt2_ 的多重定义
ztplqt2.o:ztplqt2.f:(.text+0x0):第一次在此定义
ztpmlqt.o:在函数‘ztpmlqt_’中:
ztpmlqt.f:(.text+0x0): ztpmlqt_ 的多重定义
ztpmlqt.o:ztpmlqt.f:(.text+0x0):第一次在此定义
collect2: 错误:ld 返回 1

原因是lapack-3.7.0/SRC/Makefile里有个错误,把这三个.o文件包含了两次,删掉其中一句即可:

   ztplqt.o ztplqt2.o ztpmlqt.o \
   zgelqt.o zgelqt3.o zgemlqt.o \
   zgetsls.o zgeqr.o zlatsqr.o zlamtsqr.o zgemqr.o \
   zgelq.o zlaswlq.o zlamswlq.o zgemlq.o \
   ztplqt.o ztplqt2.o ztpmlqt.o \

如果有时编译lapack-3.7.0时报错collect2: fatal error: cannot find 'ld',可能是你的home的PATH变量混乱了,执行PATH=/usr/bin:$PATH或者修改.bashrc里的PATH设置然后重新登录,然后继续编译即可。

如果不采取上面的修改使用-fPIC标志并生成so库文件,而是把默认生成的liblapack.a拷贝到/usr/local/lib后,后面运行caffe时会报错:

/usr/local/bin/ld: /usr/local/lib/liblapack.a(sgels.o): relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC

/usr/local/lib/liblapack.a: 无法添加符号: 错误的值
collect2: 错误:ld 返回 1
Makefile:573: recipe for target '.build_release/lib/libcaffe.so.1.0.0' failed
make: *** [.build_release/lib/libcaffe.so.1.0.0] Error 1

完成了上面的修改后再执行make编译lapack时又出错:

make[2]: Leaving directory '/home/fychen/Downloads/lapack-3.7.0/TESTING/EIG'
NEP: Testing Nonsymmetric Eigenvalue Problem routines
./xeigtstz < nep.in > znep.out 2>&1
/bin/sh: 行 1: 14114 Segmentation fault      (核心已转储)./xeigtstz < nep.in > znep.out 2>&1

Makefile:469: recipe for target 'znep.out' failed

执行ulimit -s unlimited后再执行make编译出库文件liblapack.a和liblapack.so,然后把liblapack.a和liblapack.so库文件拷贝到/usr/local/lib和/usr/local/lib64下面(OpenCV和Caffe编译过程中使用到liblapack.a)。

然后在Caffe的Makefile里添加上:

else ifeq ($(BLAS), open)
        # OpenBLAS

        LIBRARIES += openblas lapack

再执行make -j编译Caffe,然后又报错:

CXX/LD -o .build_release/tools/extract_features.bin
/usr/local/lib/liblapack.a(sormbr.o):在函数‘sormbr_’中:
sormbr.f:(.text+0x37f):对‘_gfortran_concat_string’未定义的引用
sormbr.f:(.text+0x53a):对‘_gfortran_concat_string’未定义的引用
sormbr.f:(.text+0x591):对‘_gfortran_concat_string’未定义的引用
sormbr.f:(.text+0x5d1):对‘_gfortran_concat_string’未定义的引用
/usr/local/lib/liblapack.a(sormlq.o):在函数‘sormlq_’中:
sormlq.f:(.text+0x31e):对‘_gfortran_concat_string’未定义的引用
/usr/local/lib/liblapack.a(sormlq.o):sormlq.f:(.text+0x741): 跟着更多未定义的参考到 _gfortran_concat_string
/usr/local/lib/liblapack.a(iparam2stage.o):在函数‘iparam2stage_’中:
iparam2stage.F:(.text+0x1bf):对‘_gfortran_compare_string’未定义的引用

collect2: 错误:ld 返回 1

这说明需要把gfortran的库加入到搜索路径:

else ifeq ($(BLAS), open)
        # OpenBLAS

        LIBRARIES += openblas gfortran lapack

然后再执行make -j编译完Caffe后,再执行make test,再执行make runtest,后面如果报错:

#006: H5PLpath.c line 604 in H5PL__find_plugin_in_path_table(): search in path /usr/local/hdf5/lib/plugin encountered an error
    major: Plugin for dynamically loaded library
    minor: Can't get value
  #007: H5PLpath.c line 656 in H5PL__find_plugin_in_path(): can't open directory: /usr/local/hdf5/lib/plugin
    major: Plugin for dynamically loaded library
    minor: Can't open directory or file

出现这个错误的话,说明你安装错了hdf5版本,hdf5不能使用最新的1.10版,而要安装1.8版或更早的版本,执行

sudo rm -rf /usr/local/hdf5

删除已安装的hdf5-1.10版,再编译安装1.8.20版,再运行make runtest即可顺利完成所有示例测试:

表明配置使用GPU计算的Caffe正确编译完成并能正常使用了。

我的AI之路(1)--前言

我的AI之路(2)--安装Fedora 28

我的AI之路(3)--安装Anaconda3 和Caffe

我的AI之路(4)--在Anaconda3 下安装Tensorflow 1.8

我的AI之路(5)--如何选择和正确安装跟Tensorflow版本对应的CUDA和cuDNN版本

我的AI之路(6)--在Anaconda3 下安装PyTorch

我的AI之路(7)--安装OpenCV3_Python 3.4.1 + Contrib以及PyCharm

我的AI之路(8)--体验用OpenCV 3的ANN进行手写数字识别及解决遇到的问题

我的AI之路(9)--使用scikit-learn

我的AI之路(10)--如何在Linux下安装CUDA和CUDNN

我的AI之路(11)--如何解决在Linux下编译OpenCV3时出现的多个错误

我的AI之路(12)--如何配置Caffe使用GPU计算并解决编译中出现的若干错误

我的AI之路(13)--解决编译gcc/g++源码过程中出现的错误

我的AI之路(14)--Caffe example:使用MNIST数据集训练和测试LeNet-5模型

我的AI之路(15)--Linux下编译OpenCV3的最新版OpenCV3.4.1及错误解决

我的AI之路(16)--云服务器上安装和调试基于Tensorflow 1.10.1的训练环境

我的AI之路(17)--Tensorflow和Caffe的API及Guide

我的AI之路(18)--Tensorflow的模型安装之object_detection

猜你喜欢

转载自blog.csdn.net/XCCCCZ/article/details/80955609
今日推荐