Linux下tensorflow1.13.1 C++ API的編譯和使用

參考文獻

https://blog.csdn.net/asialee_bird/article/details/100990483

https://www.jianshu.com/p/7f6b8a290f81

前言

因爲服務器網速的原因,無法使用下載tensorflow源碼,即通過官網方法

git clone https://github.com/tensorflow/tensorflow.git
cd tensorflow

下載的tensorflow源碼默認是master裏面的代碼,想要編譯tensorflow其他版本的話,需要使用

git checkout branch_name  # r1.9, r1.10, etc. 

然後想到的就是直接下載固定的tensorflow的版本,然後將其傳到服務器中進行編譯。其中固定版本tensorflow下載地址,有的tensorflow版本下載完成以後才幾兆B,這樣子的源文件是編譯不了的(缺少文件),下面tensorflow1.13是30多兆,是可以編譯成功的。

服務器的環境

說下運行環境,

Ubuntu18.04,

python3.7

CUDA 10.0,

cuDNN 7.6.3

查看cuda和cudnn版本

nvcc -V
cat /usr/local/cuda/include/cudnn.h | grep CUDNN_MAJOR -A 2

1、軟件下載

(1)tensorflow-1.13.1源碼(tensorflow 1.13.1

(2)bazel-0.19.2-installer-linux-x86_64.sh(bazel-0.19.2-installer-linux-x86_64.sh

(4)protobuf-3.6.1.2.tar.gz

將這些文件傳到百度雲裏面

鏈接:https://pan.baidu.com/s/1wIX9u_mNVgDo8RydT7sNIA 
提取碼:yt5x

期間也嘗試了很多東西,下面是一些下載的文件

鏈接:https://pan.baidu.com/s/1hOiY_ClmPAnT1s1totjg8Q 
提取碼:ozc1

2、Bazel編譯器的安裝

bazel編譯器和tensorflow版本必須匹配,不然無法編譯,可以去參考官網給的資料

 

bazel編譯器我直接安裝到我自己用戶目錄下(如:/home/zyt5/)了,沒有安裝在根目錄下

chmod +x bazel-0.19.2-installer-linux-x86_64.sh
./bazel-0.19.2-installer-linux-x86_64.sh --user

安裝完成之後,還需要在bashrc裏面添加環境變量

vim ~/.bashrc

然後鍵入

export PATH="$PATH:$HOME/bin"

保存後使其生效,輸入指令

source ~/.bashrc

可以查看bazel版本

bazel version

3、安裝protobuf

安裝Protobuf有一點很重要,要與所編譯的tensorflow版本相對應,這個可以參考官網

解壓文件

tar zxvf protobuf-3.6.1.2.tar.gz 

然後新建一個編譯完成的文件夾

mkdir protobuf_bin

 下載好後進入protobuf-3.6.1.2目錄輸入以下命令安裝

cd protobuf-3.6.1.2/
./autogen.sh

如果出現

./autogen.sh: 32: ./autogen.sh: autoreconf: not found

 請管理員執行

sudo apt-get install autoconf automake libtool

 在protobuf-3.6.1.2目錄下執行

./configure --prefix=$HOME/protobuf_bin (自己新建的目錄)
make -j4
make install 

編譯好後添加環境變量(根據自己的安裝路徑來)

vim ~/.bashrc

export PATH=$PATH:$HOME/tools/protobuf_bin/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/tools/protobuf_bin/lib
export CPLUS_INCLUDE_PATH="/home/zhouxd/tools/protobuf_bin/include"

source ~/.bashrc

查看版本以驗證安裝

 protoc --version

如果想要卸載protobuf

cd protobuf-3.6.1.2/
make uninstall

4、tensorflow源碼編譯

tar zxvf tensorflow-1.13.1.tar.gz 
cd tensorflow-1.13.1/
./configure

按照下面圖片的方式執行,只要CUDA support選擇Y,其他基本上都是默認和N,其中默認是10.0,如果不是在後面寫上對應的版本,我cudnn是7.6.3,默認是7,直接默認也是OK的。

設置完成之後需要編譯了

// 有顯卡
bazel build --config=opt --config=cuda //tensorflow:libtensorflow_cc.so
// 無顯卡
bazel build --config=opt //tensorflow:libtensorflow_cc.so

注意:部分博主說沒有使用--config=monolithic,會出現opencv無法使用 ,我沒有添加但是依舊可以

這個需要一段時間才能安裝完成,期間可能會報錯,因爲在bazel編譯tensorflow源碼還需要其他依賴項,因爲網速的原因無法下載完全故會報錯,沒什麼解決辦法,重新編譯(即上面的bazel指令),直到成功。(期間試過將這些依賴項下載完成放在需要的位置上,但是還是會下載的,還是需要重新編譯)

ERROR: error loading package '': Encountered error while reading extension file 'container/container.bzl': no such package '@io_bazel_rules_docker//container': java.io.IOException: Error downloading [https://github.com/bazelbuild/rules_docker/archive/a9bb1dab84cdf46e34d1b34b53a17bda129b5eba.tar.gz] to /home/zyt5/.cache/bazel/_bazel_zyt5/957c869dd334b8c29712fd21f3584066/external/io_bazel_rules_docker/a9bb1dab84cdf46e34d1b34b53a17bda129b5eba.tar.gz: Tried to reconnect at offset 403,461 but server didn't support it

編譯成功後,tensorflow-1.13.1目錄下會出現 bazel-xxx 的幾個文件,在tensorflow-1.13.1/bazel-bin/tensorflow文件下會出現 libtensorflow_cc.so 和 libtensorflow_framework.so 動態庫文件

編譯安裝其他依賴項

cd ~/tensorflow-1.13.1/tensorflow/contrib/makefile/
./build_all_linux.sh

注意:build_all_linux.sh這個命令是包含./download_dependencies.sh,但是單獨執行./download_dependencies.sh這個命令不成功

執行成功後,在tensorflow-1.13.1/tensorflow/contrib/makefile目錄下:downloads文件夾下存放第三方依賴的一些頭文件和靜態庫,比如absl  cub  double_conversion  eigen  fft2d  gemmlowp  googletest  nsync  re2。這些第三方庫是可以自己安裝的,可以去參考:https://www.jianshu.com/p/7f6b8a290f81

Eigen3需要進行編譯才能使用

首先打開上一步的downloads文件夾,裏面會有個eigen文件夾,進入eigen文件夾打開終端依次輸入如下指令:

mkdir build
cd build
cmake ..
make
sudo make install

安裝完畢後,在usr/local/include目錄下會出現eigen3文件夾這個先安裝在了根目錄下了,最好安裝自己的用戶目錄下

說明:Eigen 是一個高層次的C ++庫,有效支持線性代數,矩陣和矢量運算,數值分析及其相關的算法;Protocol Buffers (簡稱 Protobuf)是 Google 開源的一款跨語言,跨平臺,擴展性好的序列化工具,相比於 XML 和 JSON 等流行的編碼格式,這種數據結構化語言需要使用protoc進行編譯。

5、測試tensorflow C++API 

在自己的目錄下新建一個cpptest文件夾,文件夾的目錄如下:

對於main.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";
}

其中CMakeLists.txt文件如下

#指定 cmake 的最小版本
cmake_minimum_required(VERSION 3.10.2)
#項目名稱/工程名
project(cpptest)
#設置c++編譯器
set(CMAKE_CXX_STANDARD 14)
 
#aux_source_directory(./src DIR_SRCS)  # 搜索當前目錄下的所有.cpp文件  
 
#設置TENSORFLOW_DIR變量,變量內容爲安裝的tensorflow文件夾路徑
set(TENSORFLOW_DIR /home/zyt5/tensorflow-1.13.1)
include_directories(${TENSORFLOW_DIR}
                                 ${TENSORFLOW_DIR}/bazel-genfiles
	                ${TENSORFLOW_DIR}/tensorflow/contrib/makefile/downloads/absl
	                ${TENSORFLOW_DIR}/tensorflow/contrib/makefile/downloads/nsync/public
	                /usr/local/include/eigen3
	                /home/zyt5/protobuf_bin/include)	

link_directories(${TENSORFLOW_DIR} /home/zyt5/tensorflow-1.13.1/bazel-bin/tensorflow)  #動態鏈接庫目錄
#add_executable(cpptest ${DIR_SRCS})    ## 生成可執行文件 
add_executable(cpptest main) 
 
#添加可執行文件所需要的庫,連接libtensorflow_cc.so和libtensorflow_framework庫,鏈接動態鏈接庫
target_link_libraries(cpptest tensorflow_cc tensorflow_framework)

編譯和運行

mkdir build   #創建build文件,是爲了將編譯程序放到build文件中
cd build
cmake ..   #使用cmake構建生成make文件
make       #使用make編譯
./cpptest    #運行可執行文件

運行結果如下,說明tensorflow編譯結束

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章