linux tensorflow的c++API的编译和测试
一、linux下tensorflow版本的对应需求
注意:TensorFlow C++ API的编译对于bazel等工具的对应版本有非常严格的要求,版本必须匹配,一定要按照表中的版本进行适配安装下载。不然会有很多想不到的错误。
Linux CPU
Version | Python version | Compiler | Build tools |
---|---|---|---|
tensorflow-2.1.0 | 2.7, 3.5-3.7 | GCC 7.3.1 | Bazel 0.27.1 |
tensorflow-2.0.0 | 2.7, 3.3-3.7 | GCC 7.3.1 | Bazel 0.26.1 |
tensorflow-1.14.0 | 2.7, 3.3-3.7 | GCC 4.8 | Bazel 0.24.1 |
tensorflow-1.13.1 | 2.7, 3.3-3.7 | GCC 4.8 | Bazel 0.19.2 |
tensorflow-1.12.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.15.0 |
tensorflow-1.11.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.15.0 |
tensorflow-1.10.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.15.0 |
tensorflow-1.9.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.11.0 |
tensorflow-1.8.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.10.0 |
tensorflow-1.7.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.10.0 |
tensorflow-1.6.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.9.0 |
tensorflow-1.5.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.8.0 |
tensorflow-1.4.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.5.4 |
tensorflow-1.3.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.4.5 |
tensorflow-1.2.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.4.5 |
tensorflow-1.1.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.4.2 |
tensorflow-1.0.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.4.2 |
Linux GPU
Version | Python version | Compiler | Build tools | cuDNN | CUDA |
---|---|---|---|---|---|
tensorflow-2.1.0 | 2.7, 3.5-3.7 | GCC 7.3.1 | Bazel 0.27.1 | 7.6 | 10.1 |
tensorflow-2.0.0 | 2.7, 3.3-3.7 | GCC 7.3.1 | Bazel 0.26.1 | 7.4 | 10.0 |
tensorflow_gpu-1.14.0 | 2.7, 3.3-3.7 | GCC 4.8 | Bazel 0.24.1 | 7.4 | 10.0 |
tensorflow_gpu-1.13.1 | 2.7, 3.3-3.7 | GCC 4.8 | Bazel 0.19.2 | 7.4 | 10.0 |
tensorflow_gpu-1.12.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.15.0 | 7 | 9 |
tensorflow_gpu-1.11.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.15.0 | 7 | 9 |
tensorflow_gpu-1.10.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.15.0 | 7 | 9 |
tensorflow_gpu-1.9.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.11.0 | 7 | 9 |
tensorflow_gpu-1.8.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.10.0 | 7 | 9 |
tensorflow_gpu-1.7.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.9.0 | 7 | 9 |
tensorflow_gpu-1.6.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.9.0 | 7 | 9 |
tensorflow_gpu-1.5.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.8.0 | 7 | 9 |
tensorflow_gpu-1.4.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.5.4 | 6 | 8 |
tensorflow_gpu-1.3.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.4.5 | 6 | 8 |
tensorflow_gpu-1.2.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.4.5 | 5.1 | 8 |
tensorflow_gpu-1.1.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.4.2 | 5.1 | 8 |
tensorflow_gpu-1.0.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.4.2 | 5.1 | 8 |
二、下载所需软件
tensorflow源码
在这里选择你需要的版本
bazel下载:bazel
CUDA下载:CUDA
cuDNN下载:cuDNN 住意:cudnn需要免费注册登录之后才能下载
anaconda下载:anaconda
三、环境搭建
1、anaconda安装及使用
conda create -n tensorflow python=3.6 #创建了一个名为tensorflow的环境,并在这个环境中安装了python3.6
conda activate tensorflow 激活环境 #编译tensorflow时要在这个环境下编译
2、CUDA cuDNN安装
CUDA安装
cuDNN安装
如果需要安装多个版本CUDA和cuDNN参考这里
注意:gpu版本 cuda和cudnn必须和tensorflow版本匹配才能编译成功,都是血与泪的教训。经过测试tensorflow并不能上下兼容cuda和cudnn。
3、安装部分软件
sudo apt install unzip
sudo apt install make
sudo apt install g++
sudo apt install gcc
sudo apt install cmake
sudo apt-get install autoconf
sudo apt-get install automake
sudo apt-get install libtool
sudo apt install curl(used to download gmock)
sudo apt-get install zlib1g-dev
sudo apt-get install liblzma-dev
4、Bazel安装
安装Bazel
chmod +x bazel-<version>-installer-linux-x86_64.sh #给安装包执行权限
./bazel-<version>-installer-linux-x86_64.sh --user #运行安装包
该–user标志将Bazel安装到 H O M E / b i n 系 统 上 的 目 录 并 设 置 . b a z e l r c 路 径 HOME/bin系统上的目录并设置.bazelrc路径 HOME/bin系统上的目录并设置.bazelrc路径HOME/.bazelrc。使用该–help命令可以查看其他安装选项。
设置环境
如果您使用–user上面的标志运行Bazel安装程序,则Bazel可执行文件将安装在您的HOME/bin目录中。将此目录添加到默认路径是个好主意,如下所示:
export PATH="$PATH:$HOME/bin"
您也可以将此命令添加到您的~/.bashrc文件中。
四、编译tensorflow
1、运行./configure
进入源码根目录,运行 ./configure 进行配置,主要是 Python 的路径、CUDA 和 CUDNN 的版本和路径以及显卡的计算能力,以下是我的配置过程仅供参考。
Please specify the location of python. [Default is /home/dl/anaconda3/envs/tensorflow1.1/bin/python]:
Please specify optimization flags to use during compilation when bazel option "--config=opt" is specified [Default is -march=native]:
Do you wish to use jemalloc as the malloc implementation? [Y/n]
jemalloc enabled
Do you wish to build TensorFlow with Google Cloud Platform support? [y/N]
No Google Cloud Platform support will be enabled for TensorFlow
Do you wish to build TensorFlow with Hadoop File System support? [y/N]
No Hadoop File System support will be enabled for TensorFlow
Do you wish to build TensorFlow with the XLA just-in-time compiler (experimental)? [y/N]
No XLA support will be enabled for TensorFlow
Found possible Python library paths:
/home/dl/anaconda3/envs/tensorflow1.1/lib/python3.6/site-packages
Please input the desired Python library path to use. Default is [/home/dl/anaconda3/envs/tensorflow1.1/lib/python3.6/site-packages]
Using python library path: /home/dl/anaconda3/envs/tensorflow1.1/lib/python3.6/site-packages
Do you wish to build TensorFlow with OpenCL support? [y/N]
No OpenCL support will be enabled for TensorFlow
Please specify which gcc should be used by nvcc as the host compiler. [Default is /usr/bin/gcc]:
Please specify the CUDA SDK version you want to use, e.g. 7.0. [Leave empty to use system default]: 8.0
Please specify the location where CUDA 8.0 toolkit is installed. Refer to README.md for more details. [Default is /usr/local/cuda]:
Please specify the Cudnn version you want to use. [Leave empty to use system default]: 5.1
Please specify the location where cuDNN library is installed. Refer to README.md for more details. [Default is /usr/local/cuda]:
Please specify a list of comma-separated Cuda compute capabilities you want to build with.
You can find the compute capability of your device at: https://developer.nvidia.com/cuda-gpus.
Please note that each additional compute capability significantly increases your build time and binary size.
[Default is: "3.5,5.2"]:
......
INFO: Starting clean (this may take a while). Consider using --expunge_async if the clean takes more than several minutes.
.....
INFO: All external dependencies fetched successfully.
Configuration finished
2、编译tensorflow c++ API
#编译C++ API,生成.so文件,Tensorflow调用CUDA
bazel build --config=opt --config=cuda //tensorflow:libtensorflow_cc.so
#编译C++ API,生成.so文件,Tensorflow不调用CUDA
bazel build --config=opt //tensorflow:libtensorflow_cc.so
bazel-bin/tensorflow文件夹下会出现libtensorflow_cc.so,需要在c++程序中调用tensorflow时,需要将路径添加到库路径中。
3、编译其他依赖
#进入tensorflow主目录
cd tensorflow
#运行编译第三方库的脚本
cd tensorflow/contrib/makefile
./build_all_linux.sh
执行成功后,在tensorflow/contrib/makefile目录下:downloads文件夹下存放第三方依赖的一些头文件和静态库,比如nsync、Eigen、protobuf等。
5、测试
1、创建demo文件夹
mkdir demo
cd demo
mkdir src
touch CMakelists.txt
cd src
touch test.cpp
CMakelists.txt为
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
#设置项目名称
SET(PROJECT_NAME demo)
#建立项目
PROJECT(${PROJECT_NAME})
#set C++11 as standard for the whole project
set(CMAKE_CXX_STANDARD 11)
#设置TENSORFLOW_DIR变量,变量内容为安装的tensorflow文件夹路径
set(TENSORFLOW_DIR /home/dl/tensorflow_code/tensorflow-r1.1)
# 将源码目录保存到变量中
aux_source_directory(./src DIR_SRCS) # 搜索当前目录下的所有.cpp文件
#设置包含的目录,项目中的include路径,换成自己的路径即可
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
/home/dl/tensorflow_code/tensorflow-r1.1
/home/dl/tensorflow_code/tensorflow-r1.1/bazel-genfiles
/home/dl/tensorflow_code/tensorflow-r1.1/bazel-bin/tensorflow
/home/dl/tensorflow_code/tensorflow-r1.1/tensorflow/contrib/makefile/downloads/nsync/public
/home/dl/tensorflow_code/tensorflow-r1.1/tensorflow/contrib/makefile/downloads/eigen
/home/dl/tensorflow_code/tensorflow-r1.1/tensorflow/contrib/makefile/downloads/absl
/home/dl/tensorflow_code/tensorflow-r1.1/tensorflow/contrib/makefile/gen/protobuf/include
)
#设置链接库搜索目录,项目中lib路径
link_directories(${TENSORFLOW_DIR}/tensorflow/contrib/makefile/downloads/nsync/builds/default.linux.c++11)
link_directories(${TENSORFLOW_DIR}/home/dl/tensorflow_code/tensorflow-r1.1/bazel-bin/tensorflow) #动态链接库目录
#添加要编译的可执行文件
ADD_EXECUTABLE(${PROJECT_NAME} ${DIR_SRCS})# 生成可执行文件
#设置 target 需要链接的库
#添加可执行文件所需要的库,连接libtensorflow_cc.so和libtensorflow_framework库,链接动态链接库
target_link_libraries(demo /home/dl/tensorflow_code/tensorflow-r1.1/bazel-bin/tensorflow/libtensorflow_cc.so )
#打印调试信息
MESSAGE(STATUS "Project: ${PROJECT_NAME}")
MESSAGE(STATUS "OpenCV library status:")
MESSAGE(STATUS " version: ${OpenCV_VERSION}")
MESSAGE(STATUS " libraries: ${OpenCV_LIBS}")
MESSAGE(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")
MESSAGE(STATUS "Src file: ${DIR_SRCS}")
test.cpp为
#include <tensorflow/core/platform/env.h>
#include <tensorflow/core/public/session.h>
#include <iostream>
using namespace std;
using namespace tensorflow;
int main()
{
Session* session;
Status status = NewSession(SessionOptions(), &session);
if (!status.ok()) {
cout << status.ToString() << "\n";
return 1;
}
cout << "Session successfully created.\n";
}
2、编译和运行
mkdir build
cd build
cmake ..
make
./demo
结果为:
(base) dl@mvr-ubuntu1604:~/demo/build$ ./demo
2020-04-07 11:56:21.928205: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:901] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2020-04-07 11:56:21.928463: I tensorflow/core/common_runtime/gpu/gpu_device.cc:887] Found device 0 with properties:
name: GeForce RTX 2080
major: 7 minor: 5 memoryClockRate (GHz) 1.71
pciBusID 0000:01:00.0
Total memory: 7.79GiB
Free memory: 7.68GiB
2020-04-07 11:56:21.928477: I tensorflow/core/common_runtime/gpu/gpu_device.cc:908] DMA: 0
2020-04-07 11:56:21.928483: I tensorflow/core/common_runtime/gpu/gpu_device.cc:918] 0: Y
2020-04-07 11:56:21.928494: I tensorflow/core/common_runtime/gpu/gpu_device.cc:977] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GeForce RTX 2080, pci bus id: 0000:01:00.0)
Session successfully created.