当电脑有多个版本的CuDNN的时候caffe该如何“抉择”?

来源:互联网 发布:thinkphp 子域名部署 编辑:程序博客网 时间:2024/05/20 06:52

前两天,一个师弟问了一个问题,“当电脑里面有多个cudnn的时候,caffe如何使用不同版本的cudnn?”然后还发了下面的链接给我: link。
我觉得这一份笔记写的已经很清楚,但是在路径方面有一点小错误,所以我重新整理了一下,在加上自己的一些理解。


下面先讲怎么处理多个cudnn。

  1. /usr/local/cuda目录下移除cudnn相关的文件(这一步其实不是必须的,因为后面的两个步骤3-4的操作会使新版本的cudnn的优先级高于原有的版本),操作如下:

    sudo rm /usr/local/cuda/lib64/libcudnn*sudo rm /usr/local/cuda/include/cudnn.h
  2. 新建一个目录集中管理各个版本的cudnn库,比如~/cudnn/cudnn_v5存放第五版,~/cudnn/cudnn_v6存放第六版;
  3. 修改caffe根目录下的Makefile.config的INCLUDE_DIRS,添加对应版本的cudnn的include目录,添加lib64目录到LIBRARY_DIRS(通过这一步修改之后,在编译caffe的过程中已经能成功找到对应的头文件和静态库);
  4. 修改.bashrc文件或者.profile文件末尾,添加对应版本cudnn目录下的lib64到LD_LIBRARY_PATH(这一步是为了让caffe的程序在运行的过程中,注意是运行而非编译,找到对应的cudnn动态库):

    export LD_LIBRARY_PATH=/home/XXX/cudnn/cudnn_v6/lib64:$LD_LIBRARY_PATH

    PS:如果对.bashrc文件或者.profile文件不清楚的,可以参考下面的链接: link

到这里,就讲完了~~下面是我自己的一些理解,可以直接忽略~


cudnn(The NVIDIA CUDA® Deep Neural Network library):是一个深度神经网络加速库。一般下载解压之后会有includelib64两个文件夹,分别存放的时候头文件(.h)和库文件(包括静态库.a和动态库.so文件)。

要成功使用cudnn版本的caffe,需要有下面的三个因素:

  1. 告诉caffe头文件(.h)在哪里。这一步是通过赋值cudnn的include文件的路径给Makefile文件中的INCLUDE_DIRS变量实现的;
  2. 告诉caffe静态链接库(.a)在哪里。这一步是通过赋值cudnn的lib64文件的路径给Makefile文件中的LIBRARY_DIRS变量实现的;
  3. 告诉caffe动态链接库(.so)在哪里。这一步是通过给环境变量LD_LIBRARY_PATH添加cudnn的lib64文件的路径来实现的。

    PS:因素1-2影响到是否能正常编译caffe源码,因素3则影响到caffe能否正常运行(当然都是在需要cudnn加速的情况下),所以想让caffe使用某一个版本的cudnn,只需要让caffe最先找到该版本的对应文件

一般配caffe在cudnn的部分是进行了下面的操作:
会把include和lib64中的文件复制到cuda相应的文件夹下面,一般是:

$ cd cudnn/cudnn_v5/lib64/$ sudo cp lib* /usr/local/cuda/lib64/$ cd ..$ cd include$ sudo cp cudnn.h /usr/local/cuda/include/

这样做的目的是确保编译caffe的时候能找到cudnn相关的头文件和库文件,大致过程如下:

  1. caffe根目录下的Makefile.config文件中有:

    CUDA_DIR := /usr/local/cuda
  2. caffe的根目录下的Makefile文件中有:

    CUDA_INCLUDE_DIR := $(CUDA_DIR)/includeCUDA_LIB_DIR :=# add <cuda>/lib64 only if it existsifneq ("$(wildcard $(CUDA_DIR)/lib64)","")    CUDA_LIB_DIR += $(CUDA_DIR)/lib64endifCUDA_LIB_DIR += $(CUDA_DIR)/libINCLUDE_DIRS += $(BUILD_INCLUDE_DIR) ./src ./includeifneq ($(CPU_ONLY), 1)    INCLUDE_DIRS += $(CUDA_INCLUDE_DIR)    LIBRARY_DIRS += $(CUDA_LIB_DIR)    LIBRARIES := cudart cublas curandendif

    所以在执行caffe中的Makefile文件的时候,会把/usr/local/cuda/include//usr/local/cuda/lib64/赋值给INCLUDE_DIRSLIBRARY_DIRS,这样编译caffe的时候就能找到cudnn相关的文件。再加上装cuda的时候,一般会在系统或者用户自己的.profile或者.bashrc文件中加上:

    export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH

    这样,运行caffe的时候就能找到对应的cudnn动态库了。


之所以可以跳过步骤1(不删除/usr/local/cuda下旧版cudnn的先关文件),是因为:
按照步骤2-4添加新的cudnn的路径之后,新版本的cudnn使用时候的优先级高于原有的版本:

  1. 在Makefile文件中执行:

        INCLUDE_DIRS += $(CUDA_INCLUDE_DIR)    LIBRARY_DIRS += $(CUDA_LIB_DIR)

    的时候,INCLUDE_DIRSLIBRARY_DIRS经过Makefile.config的赋值,已经包含了新版的cudnn的include和lib64路径,所以优先级高于旧版本cudnn所在的/usr/local/cuda/include//usr/local/cuda/lib64/所以编译caffe的源文件的时候首选的是新版的cudnn的头文件和静态链接库

  2. 在步骤4修改.bashrc文件或者.profile文件:

    export LD_LIBRARY_PATH=/home/XXX/cudnn/cudnn_v6/lib64:$LD_LIBRARY_PATH

    之后,新版的cudnn的lib64路径在LD_LIBRARY_PATH中位于旧版的/usr/local/cuda/lib64/的前面(可以通过echo $LD_LIBRARY_PATH看看),所以运行caffe的可执行文件的时候首选的是新版的cudnn的动态链接库


大概就是这些了~希望能帮助到有需要的朋友。

原创粉丝点击