在CentOS 7.2上編譯TensorFlow 1.4版本的C++動態(tài)庫魔熏,以及整理相應(yīng)的頭文件靶草。完成后,只需要庫文件以及頭文件即可用C++ API調(diào)用TensorFlow. 這樣的好處是自己的工程可以自由選擇編譯工具夕春,而不需要依賴谷歌的構(gòu)建工具Bazel.
基本依賴
- 安裝Java
$ java -version
java version "1.8.0_144"
- 編譯安裝Bazel
TensorFlow要用Bazel來進行構(gòu)建惶我,所以要先安裝Bazel,后面我們編譯好動態(tài)庫后冠骄,就可以擺脫Bazel這個依賴了伪煤。Bazel的編譯安裝很簡單,最終得到的是self-contained Bazel binary凛辣,按照官網(wǎng)教程即可抱既。
$ bazel version
Build label: 0.7.0- (@non-git)
- 安裝其他依賴
TensorFlow官網(wǎng),源碼編譯安裝的教程中扁誓,提到要安裝一些Python依賴蝙砌。這里建議用virtualenv或者其他的Python運行環(huán)境管理工具來做隔離阳堕,專門為這個動態(tài)庫的編譯建一個新的Python運行環(huán)境,否則會把機器的Python環(huán)境搞得比較亂择克。
sudo yum install python-devel # ubuntu是python-dev
pip install six
pip install numpy
pip instal wheel
編譯libtensorflow_cc.so
git clone
獲取TensorFlow的源碼恬总。當(dāng)然,也可以直接去TensorFlow Release的頁面上找相應(yīng)版本的源碼:
git clone https://github.com/tensorflow/tensorflow
cd tensorflow
git checkout r1.4
編譯之前肚邢,要進行一系列的配置壹堰,包括Python路徑等等:
./configure
編譯C++ API所需的庫,期間Bazel需要聯(lián)網(wǎng)下載許多依賴骡湖,時間有點長:
bazel build --config=opt //tensorflow:libtensorflow_cc.so
編譯正常完成后贱纠,會在bazel-bin/tensorflow/
文件夾下生產(chǎn)libtensorflow_cc.so
和libtensorflow_framework.so
這兩個動態(tài)庫文件。
編譯Protobuf和Eigen
# protobuf
mkdir /tmp/proto
./tensorflow/contrib/makefile/download_dependencies.sh
cd tensorflow/contrib/makefile/downloads/protobuf/
./autogen.sh
./configure --prefix=/tmp/proto/
make
make install
# eigen
mkdir /tmp/eigen
cd ../eigen
mkdir build_dir
cd build_dir
cmake -DCMAKE_INSTALL_PREFIX=/tmp/eigen/ ../
make install
cd ../../../../../..
整理庫文件和頭文件
把編譯得到的庫文件以及分散在各個地方的頭文件整理集中起來响蕴。
- 庫文件
mkdir -p ../tf_test/lib
cp bazel-bin/tensorflow/libtensorflow_cc.so ../tf_test/lib/
cp bazel-bin/tensorflow/libtensorflow_framework.so ../tf_test/lib/ # 之前編譯r0.12和r1.3版本的庫谆焊,只需要libtensorflow_cc.so,1.4版本的似乎分成了兩個so文件浦夷,即還需要libtensorflow_framework.so
cp /tmp/proto/lib/libprotobuf.a ../tf_test/lib/
- 頭文件
mkdir -p ../tf_test/include/tensorflow
cp -r bazel-genfiles/* ../tf_test/include/
cp -r tensorflow/cc ../tf_test/include/tensorflow
cp -r tensorflow/core ../tf_test/include/tensorflow
cp -r third_party ../tf_test/include
cp -r /tmp/proto/include/* ../tf_test/include
cp -r /tmp/eigen/include/eigen3/* ../tf_test/include
上面是從1.3版本的這個教程里提到的目錄辖试,但是對于1.4以后的版本,似乎還缺少nsync的頭文件劈狐,這點在這個教程里有提到:
cp -r tensorflow/contrib/makefile/downloads/nsync/public ../tf_test/include/external/nsync/public
不需要的.cc文件可以刪掉:
cd ../tf_test/
find . -name "*.cc" -type f -delete
測試示例
準(zhǔn)備好庫文件和相應(yīng)的頭文件后罐孝,可以編譯測試示例:
示例代碼tf_test/test.cc
:
#include "tensorflow/cc/client/client_session.h"
#include "tensorflow/cc/ops/standard_ops.h"
#include "tensorflow/core/framework/tensor.h"
int main() {
using namespace tensorflow;
using namespace tensorflow::ops;
Scope root = Scope::NewRootScope();
// Matrix A = [3 2; -1 0]
auto A = Const(root, { {3.f, 2.f}, {-1.f, 0.f}});
// Vector b = [3 5]
auto b = Const(root, { {3.f, 5.f}});
// v = Ab^T
auto v = MatMul(root.WithOpName("v"), A, b, MatMul::TransposeB(true));
std::vector<Tensor> outputs;
ClientSession session(root);
// Run and fetch v
TF_CHECK_OK(session.Run({v}, &outputs));
// Expect outputs[0] == [19; -3]
LOG(INFO) << outputs[0].matrix<float>();
return 0;
}
$ pwd
/some/where/tf_test
$ ls
include lib test.cc
$ g++ -std=c++11 -I./include -I./include/external/nsync/public -L./lib test.cc -ltensorflow_cc -ltensorflow_framework -o test
$ ./test
正確的情況下,應(yīng)該會輸出19 -3肥缔,還會輸出類似Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2 AVX AVX2 FMA
的信息莲兢,這涉及到CPU指令優(yōu)化的問題,可以在編譯動態(tài)庫的時候進行指令優(yōu)化续膳,具體可以看TensorFlow官網(wǎng)的教程改艇,這里就不展開了。
后記
TensorFlow的版本升級迭代比較頻繁坟岔,網(wǎng)上各個版本的C++動態(tài)庫編譯及涉及到的頭文件位置都不太一樣谒兄。本人還看過一個教程,先基于源碼編譯TensorFlow的pip包炮车,用pip安裝TensorFlow之后,再去安裝目錄(/usr/lib/python2.7/site-packages/tensorflow/include)
下找頭文件酣溃∈菽拢總之,遇到編譯的問題赊豌,可以google問題的解法扛或,比較各人的環(huán)境配置總會存在差異的地方。