您的位置:首页 > 其它

Win10+cuda9.0+cudnn7源码编译tensorflow1.4.0教程(AVX/AVX2指令集支持)

2017-12-30 17:37 1231 查看

Win10+cuda9.0+cudnn7源码编译tensorflow1.4.0教程

到目前的1.4.1版本为止,tensorflow官方发布的whl安装包中,要求使用cuda8.0和cudnn6,直到1.5版本才会升级到cuda9.0和cudnn7。于是决定手动从源码编译tensorflow。

事实上,网上已经存在了很多tensorflow在cuda9.0和cudnn7下编译成功的案例,但是仅限于linux和Mac OS两种操作系统。有需要的朋友可以直接去下载pip安装文件。TensorFlow 1.4 (GPU, CUDA 9, Compute 3.7/6.0/7.0)

在Windows系统下,由于win-nvcc存在bug,导致所有人都不能编译成功。直到12月中旬修复了此问题之后NVCC-BugFix,Windows终于可以编译成功了。

在研究源码编译的过程中参考了以下内容:

TensorFlow CMake build

[CMake] Don’t build tests for RE2 #14696

compile failed for tf-gpu 1.4, cuda 9, cudnn 7, vc 2017, windows 10.

On the way to latest CMake, VS2017, CUDA 9, cudNN 7, Win10 #14801

Upgrade to CuDNN 7 and CUDA 9 #12052

fail to build tensorflow-gpu by CUDA 9.0 cuDNN 7 at win10 envs #14126

Fix for AVX2 support in Visual Studio #13525

编译环境

在我编译的过程中,使用到环境如下:

tensorflow1.4.0

Windows 10

CUDA9.0

cuDNN7

Swig 3.0.12

CMake 3.10.1

Git

Visual Studio 2015

Python 3.6

NumPy 1.13.3

准备工作

在完成了上一部分的配置环境之后,还需要对Tensorflow 1.4.0的代码进行几处修改,才能顺利编译。

修改CUDA版本依赖

修改
tensorflow\contrib\cmake\CMakeLists.txt
文件的221-251行如下,主要修改了CUDA和cuDNN的版本以及添加了自己的显卡的compute cabability 6.1。

if (tensorflow_ENABLE_GPU)
if (WIN32)
find_package(CUDA 9.0 REQUIRED)

# by default we assume compute cabability 3.5 and 5.2. If you change this change it in
# CUDA_NVCC_FLAGS and cuda_config.h below
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS};-gencode arch=compute_30,code=\"sm_30,compute_30\";-gencode arch=compute_35,code=\"sm_35,compute_35\";-gencode arch=compute_52,code=\"sm_52,compute_52\";-gencode arch=compute_61,code=\"sm_61,compute_61\")
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS};--include-path ${PROJECT_BINARY_DIR}/$\{build_configuration\};--expt-relaxed-constexpr)
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS};-ftz=true)  # Flush denormals to zero
set(CUDA_INCLUDE ${CUDA_TOOLKIT_TARGET_DIR} ${CUDA_TOOLKIT_TARGET_DIR}/extras/CUPTI/include)
include_directories(${CUDA_INCLUDE})
add_definitions(-DGOOGLE_CUDA=1 -DTF_EXTRA_CUDA_CAPABILITIES=3.0,3.5,5.2,6.1)

# add cudnn
if(NOT CUDNN_HOME)
set(CUDNN_HOME ${CUDA_TOOLKIT_TARGET_DIR})
endif(NOT CUDNN_HOME)
include_directories(${CUDNN_HOME})
set(CUDA_LIBRARIES ${CUDA_LIBRARIES} ${CUDA_CUDA_LIBRARY} ${CUDA_CUBLAS_LIBRARIES} ${CUDA_CUFFT_LIBRARIES}
${CUDA_curand_LIBRARY} ${CUDA_cupti_LIBRARY} ${CUDA_cusolver_LIBRARY} ${CUDNN_HOME}/lib/x64/cudnn.lib)

# create cuda_config.h
FILE(WRITE ${tensorflow_source_dir}/third_party/gpus/cuda/cuda_config.h
"#ifndef CUDA_CUDA_CONFIG_H_\n"
"#define CUDA_CUDA_CONFIG_H_\n"
"#define TF_CUDA_CAPABILITIES CudaVersion(\"3.0\"),CudaVersion(\"3.5\"),CudaVersion(\"5.2\"),CudaVersion(\"6.1\")\n"
"#define TF_CUDA_VERSION \"64_90\"\n"
"#define TF_CUDNN_VERSION \"64_7\"\n"
"#define TF_CUDA_TOOLKIT_PATH \"${CUDA_TOOLKIT_ROOT_DIR}\"\n"
"#endif  // CUDA_CUDA_CONFIG_H_\n"
)


暂时注释掉__hadd函数

由于tensorflow针对compute cabability >=5.3 有额外的优化,但是其中__hadd函数存在命名冲突,导致在编译过程中存在多个__hadd的实例,编译失败。所以可以暂时注释掉cuda中的__hadd的声明,等待编译完成之后,再取消注释。

修改
{CUDA_PATH}\include\crt\device_functions.h
文件,注释掉2204行,

//__DEVICE_FUNCTIONS_DECL__ __device_builtin__ int                    __hadd(int, int);


禁用re2-testing

修改
tensorflow/contrib/cmake/external/re2.cmake
文件,在47行下面新加一行如下,用于禁用re2的test模块。

-DRE2_BUILD_TESTING:BOOL=OFF


Fix 生成AVX2指令集的bug

修改
third_party/eigen3/unsupported/Eigen/CXX11/src/FixedPoint/PacketMathAVX2.h
文件,添加头文件和函数定义,如下所示。

#include <immintrin.h>
#include <emmintrin.h>
#include <smmintrin.h>

inline int _mm256_extract_epi16_N0(const __m256i X)
{
return _mm_extract_epi16(_mm256_extractf128_si256(X, 0 >> 3), 0 % 8);
}

inline int _mm256_extract_epi16_N1(const __m256i X)
{
return _mm_extract_epi16(_mm256_extractf128_si256(X, 1 >> 3), 1 % 8);
}

inline int _mm256_extract_epi8_N0(const __m256i X)
{
return _mm_extract_epi8(_mm256_extractf128_si256((X), 0 >> 4), <
4000
span class="hljs-number">0 % 16);
}

inline int _mm256_extract_epi8_N1(const __m256i X)
{
return _mm_extract_epi8(_mm256_extractf128_si256((X), 1 >> 4), 1 % 16);
}


将所有的
_mm256_extract_epi8(,0)
修改为
_mm256_extract_epi8_N0()


将所有的
_mm256_extract_epi8(,1)
修改为
_mm256_extract_epi8_N1()


将所有的
_mm256_extract_epi16(,0)
修改为
_mm256_extract_epi16_N0()


将所有的
_mm256_extract_epi16(,1)
修改为
_mm256_extract_epi16_N1()


修改Engin的版本

tensorflow/workspace.bzl
文件的184-193行修改为如下内容:

native.new_http_archive(
name = "eigen_archive",
urls = [
"https://bitbucket.org/eigen/eigen/get/c2947c341c68.tar.gz",
"http://mirror.bazel.build/bitbucket.org/eigen/eigen/get/c2947c341c68.tar.gz",
],
sha256 = "f21f8ab8a8dbcb91cd0deeade19a043f47708d0da7a4000164cdf203b4a71e34",
strip_prefix = "eigen-eigen-c2947c341c68",
build_file = str(Label("//third_party:eigen.BUILD")),
)


进行编译

新建并进入build目录

D:\cppworkspace\tensorflow-1.4.0>cd tensorflow\contrib\cmake

D:\cppworkspace\tensorflow-1.4.0\tensorflow\contrib\cmake>mkdir build

D:\cppworkspace\tensorflow-1.4.0\tensorflow\contrib\cmake>cd build

D:\cppworkspace\tensorflow-1.4.0\tensorflow\contrib\cmake\build>


初始化命令行编译环境

D:\cppworkspace\tensorflow-1.4.0\tensorflow\contrib\cmake\build>"D:\Microsoft Visual Studio 14.0\VC\bin\amd64\vcvars64.bat"


执行cmake命令

需要设置swig路径、python.exe路径、python3.lib路径、GPU开启、cudnn路径以及AVX和AVX2指令集支持。如果CPU不支持这些指令集,可省略。(使用AVX/AVX2指令可以充分利用CPU的性能)

cmake .. -A x64 -DCMAKE_BUILD_TYPE=Release ^
-DSWIG_EXECUTABLE=D:\swigwin-3.0.12\swig.exe ^
-DPYTHON_EXECUTABLE=D:\Python36\python.exe ^
-DPYTHON_LIBRARIES=D:\Python36\libs\python3.lib ^
-Dtensorflow_ENABLE_GPU=ON ^
-DCUDNN_HOME=D:\CUDA\cudnn ^
-Dtensorflow_WIN_CPU_SIMD_OPTIONS=/arch:AVX ^
-Dtensorflow_WIN_CPU_SIMD_OPTIONS=/arch:AVX2


编译pip安装包及安装

MSBuild /p:Configuration=Release tf_python_build_pip_package.vcxproj


通过pip安装编译好的tensorflow

编译好的whl文件在
tf_python\dist
路径下。

D:\cppworkspace\tensorflow-1.4.0\tensorflow\contrib\cmake\build>cd tf_python\dist

D:\cppworkspace\tensorflow-1.4.0\tensorflow\contrib\cmake\build\tf_python\dist>pip install tensorflow_gpu-1.4.0-cp36-cp36m-win_amd64


whl文件下载

同样是是Windows+CUDA9.0+cuDNN7+Python3.6的朋友,可以直接下载编译好的whl文件。

链接:https://pan.baidu.com/s/1nvzMnup 密码:92ne
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息