<-- Home

使用VS2017编译caffe-windows GTX1060+cuda9.2+cuDNN7.1

先简要说明一下我的开发环境

CPU: Intel Core i7-8750H @2.20GHz
显卡: NVIDIA GeForce GTX 1060
内存: 8GB
IDE: Visual Studio Community 2017 v15.7.5
cuda: cuda9.2
cuDNN: cuDNN7.1

网上有不少关于在Windows环境下配置caffe的文章,但他们使用的IDE都是VS2013、VS2015,cuda版本为8.0。如何使用VS2017编译cuda9.2版本的caffe?

一、安装cuda和cuDNN

到NVIDIA官网下载cuda和对应的cuDNN,cuda9.2与cuDNN7.1

运行cuda9.2安装程序,此时会自动检测系统兼容性。然后可能会显示如下警告信息

原因是厂商给显卡添加了独特的硬件ID,导致cuda内置的驱动无法识别显卡型号。解决方法是找到厂商提供的显卡驱动中的ListDevices.txt文件与Display.Driver文件夹替换cuda安装程序中的相应文件与文件夹。

重新运行cuda安装程序,即可顺利完成安装。

将下载好的cuDNN7.1的文件复制到cuda9.2的相应目录下,完成cuDNN的安装。

运行C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.2\extras\demo_suite下的 deviceQuery.exebandwidthTest.exe

输出Result = PASS信息表示安装成功。

在VS2017中创建项目来测试cuda的使用,具体可以参考这篇博客

在编译过程中,可能会出现如下错误

error -- unsupported Microsoft Visual Studio version! 
Only the versions 2012, 2013, 2015 and 2017 are supported!" compile-time error.

这是cuda的bug,将cuda安装目录下的<your path>/NVIDIA GPU Computing Toolkit\CUDA\v9.2\include\crt\host_config.h文件中的

#if _MSC_VER < 1600 || _MSC_VER > 1911

修改为

#if _MSC_VER < 1600 || _MSC_VER > 1920

二、获取和编译caffe

cuda的安装和配置仅仅是整个过程中的一小部分。最麻烦的是用vs2017编译caffe。

获取caffe

git clone https://github.com/BVLC/caffe.git
cd caffe
git checkout windows

打开scripts\build_win.cmd这个文件

根据自己的需要修改70~99行

我修改为

    :: Change the settings here to match your setup
    :: Change MSVC_VERSION to 12 to use VS 2013 设置为15表示vs2017
    if NOT DEFINED MSVC_VERSION set MSVC_VERSION=15
    :: Change to 1 to use Ninja generator (builds much faster) 不使用Ninja
    if NOT DEFINED WITH_NINJA set WITH_NINJA=0
    :: Change to 1 to build caffe without CUDA support 使用GPU加速
    if NOT DEFINED CPU_ONLY set CPU_ONLY=0
    :: Change to generate CUDA code for one of the following GPU architectures
    :: [Fermi  Kepler  Maxwell  Pascal  All]
    if NOT DEFINED CUDA_ARCH_NAME set CUDA_ARCH_NAME=Auto
    :: Change to Debug to build Debug. This is only relevant for the Ninja generator the Visual Studio generator will generate both Debug and Release configs
    if NOT DEFINED CMAKE_CONFIG set CMAKE_CONFIG=Release
    :: Set to 1 to use NCCL
    if NOT DEFINED USE_NCCL set USE_NCCL=0
    :: Change to 1 to build a caffe.dll
    if NOT DEFINED CMAKE_BUILD_SHARED_LIBS set CMAKE_BUILD_SHARED_LIBS=0
    :: Change to 3 if using python 3.5 (only 2.7 and 3.5 are supported)
    if NOT DEFINED PYTHON_VERSION set PYTHON_VERSION=2
    :: Change these options for your needs. 不使用python和matlab
    if NOT DEFINED BUILD_PYTHON set BUILD_PYTHON=0
    if NOT DEFINED BUILD_PYTHON_LAYER set BUILD_PYTHON_LAYER=0
    if NOT DEFINED BUILD_MATLAB set BUILD_MATLAB=0
    :: If python is on your path leave this alone
    if NOT DEFINED PYTHON_EXE set PYTHON_EXE=python
    :: Run the tests
    if NOT DEFINED RUN_TESTS set RUN_TESTS=0
    :: Run lint
    if NOT DEFINED RUN_LINT set RUN_LINT=0
    :: Build the install target
    if NOT DEFINED RUN_INSTALL set RUN_INSTALL=0

然后在112行插入

    if "%MSVC_VERSION%"=="15" (
        set CMAKE_GENERATOR=Visual Studio 15 2017 Win64
    )

105~121行变成

if %WITH_NINJA% EQU 0 (
    if "%MSVC_VERSION%"=="14" (
        set CMAKE_GENERATOR=Visual Studio 14 2015 Win64
    )
    if "%MSVC_VERSION%"=="12" (
        set CMAKE_GENERATOR=Visual Studio 12 2013 Win64
    )
    if "%MSVC_VERSION%"=="15" (
        set CMAKE_GENERATOR=Visual Studio 15 2017 Win64
    )
    if "!CMAKE_GENERATOR!"=="" (
        echo ERROR: Unsupported MSVC version
        exit /B 1
    )
) else (
    set CMAKE_GENERATOR=Ninja
)

然后在C盘中搜索VS2017的文件vcvarsall.bat的位置。我搜索出来的位置为C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat

将156行batch_file的值改成该位置

set batch_file=!VS%MSVC_VERSION%0COMNTOOLS!..\..\VC\vcvarsall.bat

修改为

set batch_file=C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat

保存并关闭scripts\build_win.cmd文件。

打开cmake\WindowsDownloadPrebuiltDependencies.cmake文件

在第14行插入

set(DEPENDENCIES_URL_1914_27 "${DEPENDENCIES_URL_BASE}/v${DEPENDENCIES_VERSION}/${DEPENDENCIES_NAME_1900_27}${DEPENDENCIES_FILE_EXT}")
set(DEPENDENCIES_SHA_1914_27 "17eecb095bd3b0774a87a38624a77ce35e497cd2")

1910对应VS2015, 1914对应我的VS2017 v15.7.5。

保存并关闭cmake\WindowsDownloadPrebuiltDependencies.cmake文件。

根据下面的信息查询你的显卡的架构

Fermi (CUDA 3.2 and later, deprecated from CUDA 9):
SM20 or SM_20, compute_30 – Older cards such as GeForce 400, 500, 600, GT-630

Kepler (CUDA 5 and later):
SM30 or SM_30, compute_30 – Kepler architecture (generic – Tesla K40/K80, GeForce 700, GT-730)
Adds support for unified memory programming
SM35 or SM_35, compute_35 – More specific Tesla K40
Adds support for dynamic parallelism. Shows no real benefit over SM30 in my experience.
SM37 or SM_37, compute_37 – More specific Tesla K80
Adds a few more registers. Shows no real benefit over SM30 in my experience

Maxwell (CUDA 6 and later):
SM50 or SM_50, compute_50 – Tesla/Quadro M series
SM52 or SM_52, compute_52 – Quadro M6000 , GeForce 900, GTX-970, GTX-980, GTX Titan X
SM53 or SM_53, compute_53 – Tegra (Jetson) TX1 / Tegra X1

Pascal (CUDA 8 and later)
SM60 or SM_60, compute_60 – GP100/Tesla P100 – DGX-1 (Generic Pascal)
SM61 or SM_61, compute_61 – GTX 1080, GTX 1070, GTX 1060, GTX 1050, GTX 1030, Titan Xp, Tesla P40, 

Tesla P4
SM62 or SM_62, compute_62 – Drive-PX2, Tegra (Jetson) TX2, Denver-based GPU

Volta (CUDA 9 and later)
SM70 or SM_70, compute_70 – Tesla V100
SM71 or SM_71, compute_71 – probably not implemented
SM72 or SM_72, compute_72 – currently unknown

我的显卡是GTX1060,是Pascal架构(SM61 or SM_61, compute_61)

打开cmake\Cuda.cmake文件,将90~104行注释掉,根据上面查询的结果,在104行后面添加

set(__cuda_arch_bin "61")

“61”就是上面Pascal架构对应的SM61 or SM_61。

90~105行为

  #if(${CUDA_ARCH_NAME} STREQUAL "Fermi")
  #  set(__cuda_arch_bin "20 21(20)")
  #elseif(${CUDA_ARCH_NAME} STREQUAL "Kepler")
  #  set(__cuda_arch_bin "30 35")
  #elseif(${CUDA_ARCH_NAME} STREQUAL "Maxwell")
  #  set(__cuda_arch_bin "50")
  #elseif(${CUDA_ARCH_NAME} STREQUAL "Pascal")
  #  set(__cuda_arch_bin "60 61")
  #elseif(${CUDA_ARCH_NAME} STREQUAL "All")
  #  set(__cuda_arch_bin ${Caffe_known_gpu_archs})
  #elseif(${CUDA_ARCH_NAME} STREQUAL "Auto")
  #  caffe_detect_installed_gpus(__cuda_arch_bin)
  #else()  # (${CUDA_ARCH_NAME} STREQUAL "Manual")
  #  set(__cuda_arch_bin ${CUDA_ARCH_BIN})
  #endif()
  set(__cuda_arch_bin "61")

保存并关闭该文件。运行scripts\build_win.cmd,控制台输出如下

INFO: ============================================================
INFO: Summary:
INFO: ============================================================
INFO: MSVC_VERSION               = 15
INFO: WITH_NINJA                 = 0
INFO: CMAKE_GENERATOR            = "Visual Studio 15 2017 Win64"
INFO: CPU_ONLY                   = 0
INFO: CUDA_ARCH_NAME             = Auto
INFO: CMAKE_CONFIG               = Release
INFO: USE_NCCL                   = 0
INFO: CMAKE_BUILD_SHARED_LIBS    = 0
INFO: PYTHON_VERSION             = 2
INFO: BUILD_PYTHON               = 0
INFO: BUILD_PYTHON_LAYER         = 0
INFO: BUILD_MATLAB               = 0
INFO: PYTHON_EXE                 = "python"
INFO: RUN_TESTS                  = 0
INFO: RUN_LINT                   = 0
INFO: RUN_INSTALL                = 0
INFO: ============================================================
**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.7.5
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'
-- Selecting Windows SDK version 10.0.17134.0 to target Windows 10.0.16299.
-- The C compiler identification is MSVC 19.14.26433.0
-- The CXX compiler identification is MSVC 19.14.26433.0
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.14.26428/bin/Hostx86/x64/cl.exe
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.14.26428/bin/Hostx86/x64/cl.exe -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.14.26428/bin/Hostx86/x64/cl.exe
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.14.26428/bin/Hostx86/x64/cl.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Building without python. Prebuilt dependencies will default to Python 2.7
-- Downloading prebuilt dependencies to C:/Users/MSI11/.caffe/dependencies/download/libraries_v140_x64_py27_1.1.0.tar.bz2
-- [download 0% complete]
...
-- [download 100% complete]
-- Extracting dependencies
-- Looking for pthread.h
-- Looking for pthread.h - not found
-- Found Threads: TRUE
-- Boost version: 1.61.0
-- Found the following Boost libraries:
--   system
--   thread
--   filesystem
--   chrono
--   date_time
--   atomic
-- Found GFlags: C:/Users/MSI11/.caffe/dependencies/libraries/include
-- Found gflags  (include: C:/Users/MSI11/.caffe/dependencies/libraries/include, library: gflags_shared)
-- Found Glog: C:/Users/MSI11/.caffe/dependencies/libraries/include
-- Found glog    (include: C:/Users/MSI11/.caffe/dependencies/libraries/include, library: glog)
-- Found Protobuf: C:/Users/MSI11/.caffe/dependencies/libraries/bin/protoc.exe (found version "3.1.0")
-- Found PROTOBUF Compiler: C:/Users/MSI11/.caffe/dependencies/libraries/bin/protoc.exe
-- Found LMDB: C:/Users/MSI11/.caffe/dependencies/libraries/include
-- Found lmdb    (include: C:/Users/MSI11/.caffe/dependencies/libraries/include, library: lmdb)
-- Found LevelDB: C:/Users/MSI11/.caffe/dependencies/libraries/include
-- Found LevelDB (include: C:/Users/MSI11/.caffe/dependencies/libraries/include, library: leveldb)
-- Found ZLIB: optimized;C:/Users/MSI11/.caffe/dependencies/libraries/lib/caffezlib.lib;debug;C:/Users/MSI11/.caffe/dependencies/libraries/lib/caffezlibd.lib (found version "1.2.8")
-- Found Snappy: C:/Users/MSI11/.caffe/dependencies/libraries/include
-- Found Snappy  (include: C:/Users/MSI11/.caffe/dependencies/libraries/include, library: snappy_static;optimized;C:/Users/MSI11/.caffe/dependencies/libraries/lib/caffezlib.lib;debug;C:/Users/MSI11/.caffe/dependencies/libraries/lib/caffezlibd.lib)
-- CUDA detected: 9.2
-- Found cuDNN: ver. 7.1.4 found (include: C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v9.2/include, library: C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v9.2/lib/x64/cudnn.lib)
-- Added CUDA NVCC flags for: sm_61
-- OpenCV ARCH: x64
-- OpenCV RUNTIME:
-- OpenCV STATIC: OFF
CMake Warning at C:/Users/MSI11/.caffe/dependencies/libraries/OpenCVConfig.cmake:166 (message):
  Found OpenCV Windows Pack but it has no binaries compatible with your
  configuration.

  You should manually point CMake variable OpenCV_DIR to your build of OpenCV
  library.
Call Stack (most recent call first):
  cmake/Dependencies.cmake:114 (find_package)
  CMakeLists.txt:80 (include)


CMake Error at cmake/Dependencies.cmake:114 (find_package):
  Found package configuration file:

    C:/Users/MSI11/.caffe/dependencies/libraries/OpenCVConfig.cmake

  but it set OpenCV_FOUND to FALSE so package "OpenCV" is considered to be
  NOT FOUND.
Call Stack (most recent call first):
  CMakeLists.txt:80 (include)


-- Configuring incomplete, errors occurred!
See also "E:/Projects/caffe/build/CMakeFiles/CMakeOutput.log".
See also "E:/Projects/caffe/build/CMakeFiles/CMakeError.log".
ERROR: Configure failed

脚本会自动下载编译需要的依赖库,上面提示我们OpenCV的RUNTIME配置错误,原因是我们使用的是VS2017,原来的cmake文件里面没有相应的配置。

打开C:/Users/<your username>/.caffe/dependencies/libraries/OpenCVConfig.cmake文件 在86行后插入

  elseif(MSVC_VERSION EQUAL 1914)
    set(OpenCV_RUNTIME vc14)

75~89行变为

  if(MSVC_VERSION EQUAL 1400)
    set(OpenCV_RUNTIME vc8)
  elseif(MSVC_VERSION EQUAL 1500)
    set(OpenCV_RUNTIME vc9)
  elseif(MSVC_VERSION EQUAL 1600)
    set(OpenCV_RUNTIME vc10)
  elseif(MSVC_VERSION EQUAL 1700)
    set(OpenCV_RUNTIME vc11)
  elseif(MSVC_VERSION EQUAL 1800)
    set(OpenCV_RUNTIME vc12)
  elseif(MSVC_VERSION EQUAL 1900)
    set(OpenCV_RUNTIME vc14)
  elseif(MSVC_VERSION EQUAL 1914)
    set(OpenCV_RUNTIME vc14)
  endif()

保存并关闭该文件。然后打开C:\Users\<your username>\.caffe\dependencies\libraries\include\boost-1_61\boost\config\compiler\nvcc.hpp文件

将该文件内容全部替换为

//  (C) Copyright Eric Jourdanneau, Joel Falcou 2010
//  Use, modification and distribution are subject to the 
//  Boost Software License, Version 1.0. (See accompanying file 
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org for most recent version.

//  NVIDIA CUDA C++ compiler setup

#ifndef BOOST_COMPILER
#  define BOOST_COMPILER "NVIDIA CUDA C++ Compiler"
#endif

#if defined(__CUDACC_VER_MAJOR__) && defined(__CUDACC_VER_MINOR__) && defined(__CUDACC_VER_BUILD__)
#  define BOOST_CUDA_VERSION __CUDACC_VER_MAJOR__ * 1000000 + __CUDACC_VER_MINOR__ * 10000 + __CUDACC_VER_BUILD__
#else
// We don't really know what the CUDA version is, but it's definitely before 7.5:
#  define BOOST_CUDA_VERSION 7000000
#endif

// NVIDIA Specific support
// BOOST_GPU_ENABLED : Flag a function or a method as being enabled on the host and device
#define BOOST_GPU_ENABLED __host__ __device__

// A bug in version 7.0 of CUDA prevents use of variadic templates in some occasions
// https://svn.boost.org/trac/boost/ticket/11897
// This is fixed in 7.5. As the following version macro was introduced in 7.5 an existance
// check is enough to detect versions < 7.5
#if BOOST_CUDA_VERSION < 7050000
#   define BOOST_NO_CXX11_VARIADIC_TEMPLATES
#endif
// The same bug is back again in 8.0:
#if (BOOST_CUDA_VERSION > 8000000) && (BOOST_CUDA_VERSION < 8010000)
#   define BOOST_NO_CXX11_VARIADIC_TEMPLATES
#endif
// Most recent CUDA (8.0) has no constexpr support in msvc mode:
#if defined(_MSC_VER)
#  define BOOST_NO_CXX11_CONSTEXPR
#endif

#ifdef __CUDACC__
//
// When compiing .cu files, there's a bunch of stuff that doesn't work with msvc:
//
#if defined(_MSC_VER)
#  define BOOST_NO_CXX14_DIGIT_SEPARATORS
#  define BOOST_NO_CXX11_UNICODE_LITERALS
#endif
//
// And this one effects the NVCC front end,
// See https://svn.boost.org/trac/boost/ticket/13049
//
#if (BOOST_CUDA_VERSION >= 8000000) && (BOOST_CUDA_VERSION < 8010000)
#  define BOOST_NO_CXX11_NOEXCEPT
#endif

#endif

保存并关闭该文件,重新运行scripts\build_win.cmd

然后就可以顺利的编译了,编译过程中会出现一大大大大大大大大大大大大堆警告,而且VS2017编译器输出的警告居然是乱码(σ‘・д・)σ???!

我也不知道是咋回事。

在编译过程中以及将来的程序编译中会大量出现”Unknown compiler version - please run the configure tests and report the results”警告,该警告不影响编译结果。原因是boost库版本低不认识VS2017的编译器。

等了10分钟,终于编译完了,build文件夹下面就是编译好的caffe。

试试编译好的build\tools\Release\caffe.exe跑一下mnist数据集

不知道官方还会不会解决caffe和VS2017兼容问题……毕竟caffe2都出来了,先凑合着用吧。

_(:з」∠)_

如果您发现什么问题或者有什么意见和建议欢迎与我联系。