tensorflow C++动态库编译
目录编译安装Bazel编译libtensorflow_cc.so编译Protobuf和Eigen整理库文件和头文件测试示例在虚拟机(无GPU)CentOS 7.6上编译TensorFlow 1.13版本的C++动态库,以及整理相应的头文件。完成后,只需要库文件以及头文件即可用C++ API调用TensorFlow. 这样的好处是自己的工程可以自由选择编译工具,而不需要依赖谷...
目录
在虚拟机(无GPU)CentOS 7.6上编译TensorFlow 1.13版本的C++动态库,以及整理相应的头文件。完成后,只需要库文件以及头文件即可用C++ API调用TensorFlow. 这样的好处是自己的工程可以自由选择编译工具,而不需要依赖谷歌的构建工具Bazel.
编译安装Bazel
TensorFlow要用Bazel来进行构建,所以要先安装Bazel,后面我们编译好动态库后,就可以摆脱Bazel这个依赖了。
Bazel官网安装教程:https://docs.bazel.build/versions/master/install-compile-source.html
我这里是按照如下方式操作的,最后输入bazel version命令确认安装成功
wget https://github.com/bazelbuild/bazel/releases/download/0.21.0/bazel-0.21.0-installer-linux-x86_64.sh
chmod +x ./bazel-0.21.0-installer-linux-x86_64.sh
./bazel-0.21.0-installer-linux-x86_64.sh
编译libtensorflow_cc.so
git clone 获取tensorflow的源码
git clone https://github.com/tensorflow/tensorflow
cd tensorflow
git checkout r1.13
编译之前,要进行一系列的配置:
./configure
接下来,配置系统会给出各种询问,以确认编译时的配置参数,直接按回车,确认默认值Y(默认值通常就是被大写的选项),下面挑选比较重要的几个参数解释如下:
Do you wish to build TensorFlow with CUDA support? [y/N]:
No CUDA support will be enabled for TensorFlow.
这个选项是询问是否使用CUDA。CUDA是一种由NVIDIA推出的通用并行计算架构,该架构使GPU能够解决复杂的计算问题。如果用户配备有NVIDIA的GPU,可以选择“y”,如果仅使用TensorFlow的CPU版本,回车确认“N”。
Do you wish to build TensorFlow with MPI support? [y/N]:
No MPI support will be enabled for TensorFlow.
这个选项是询问是否使用MPI。MPI(Message-Passing-Interface 消息传递接口)是实现进程级别的并行程序的通信协议,它通过在进程之间进行消息传递。如果不是基于TensorFlow做并行程序开发,建议回车确认选择默认值“N”。
Please specify optimization flags to use during compilation when bazel option "--config=opt" is specified [Default is -march=native]:
这个选项是指定CPU编译优化选项。默认值就是“-march=native”。这里“m”表示“machine(机器)”,“arch”就是“architecture”简写。“march”合在一起表示机器的结构,如果选择“-march=native”,则表示选择本地(native)CPU,如果本地CPU比较高级,就可以支持SSE4.2、AVX等选项。这里建议选择默认值。
编译过程中可能会报错"no such package '@png_archive//",建议在编译之前运行如下命令:
yum install -y patch
编译C++ API所需的库,期间Bazel需要联网下载许多依赖,时间有点长:
bazel build --config=opt //tensorflow:libtensorflow_cc.so
编译正常完成后,会在bazel-bin/tensorflow/
文件夹下生产libtensorflow_cc.so
和libtensorflow_framework.so
这两个动态库文件。
编译Protobuf和Eigen
这个步骤中需要运行autogen.sh,在此之前得 yum install autoconf automake libtool
yum install autoconf
yum install automake
yum install libtool
# 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
测试示例
准备好库文件和相应的头文件后,可以编译测试示例:
示例代码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;
}
$ cd /root/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
如果编译失败遇到一个小问题,./include/tensorflow/core/lib/core/stringpiece.h:29:38: fatal error: absl/strings/string_view.h: No such file or directory
解决办法:cp -r ../tensorflow/tensorflow/contrib/makefile/downloads/absl/absl/ include/.
编译成功后,如果./test失败,没找到库文件,就直接运行下面这句命令
export LD_LIBRARY_PATH=/root/tf_test/lib:$LD_LIBRARY_PATH
正确的情况下,应该会输出19 -3,还会输出类似Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2 AVX AVX2 FMA
的信息,这涉及到CPU指令优化的问题,说明在编译动态库的时候没有选择进行指令优化。
参考:
TensorFlow C++动态库编译 https://www.jianshu.com/p/d46596558640
tensorflow c++ API的编译和调用 https://zhuanlan.zhihu.com/p/46566618
TensorFlow学习系列之七:TensorFlow的源码编译 https://blog.csdn.net/yhily2008/article/details/79967118
更多推荐
所有评论(0)