參考文獻
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)
將這些文件傳到百度雲裏面
鏈接: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編譯結束