Mac 下 TensorFlow C++ API 的编译与测试

Posted 珍妮的选择

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mac 下 TensorFlow C++ API 的编译与测试相关的知识,希望对你有一定的参考价值。


Mac 下 TensorFlow C++ API 的编译与测试

文章目录

在​​前篇博客​​介绍了从源码编译 TensorFlow 的 .whl 文件, 以便用 pip 进行安装. 本文介绍 TensorFlow C++ API 的编译与测试, 为后续用 C++ 玩耍 TF 打下基础 ????????????.

广而告之

可以在微信中搜索 “珍妮的算法之路” 或者 “world4458” 关注我的微信公众号;另外可以看看知乎专栏 ​​PoorMemory-机器学习​​, 以后文章也会发在知乎专栏中;

准备工作

  1. Python 环境准备

我采用的是 ​​Anaconda3-4.2.0​​​ 发行版, Python 的版本为 ​​3.5.2​​.

  1. 下载 TensorFlow 源码, 因此下载完源代码后, 使用 git 进行分支切换 (比如希望切换至​​r2.0​​ 版本)
git clone --recursive https://github.com/tensorflow/tensorflow   ## 下载 TensorFlow
cd tensorflow/ ## 最好备份一份源代码
git checkout r2.0 ## 切换到 r2.0 版本
  1. 安装 Bazel. 需要注意 Bazel 的版本有较为严格的要求, 在​​前篇博客​​​介绍了切换到​​r1.10​​ 分支下, 如何安装对应的 Bazel.

此外, 如果安装的 TensorFlow 是 2.0 以上版本, 可以查看 ​​tensorflow/configure.py​​​, 搜索 ​​Bazel​​ 关键字, 查询到:

_TF_MIN_BAZEL_VERSION = 0.24.1
_TF_MAX_BAZEL_VERSION = 0.26.1

清楚地指明了合适的 Bazel 版本. 由于我最后安装的 TensorFlow 版本是 ​​r2.0​​​ 版, 这里我选择了 ​​0.26.1​​​, 于是到 ​​https://github.com/bazelbuild/bazel/releases/tag/0.26.1​​ 下载 Mac 版本:

mkdir ~/Programs
cd ~/Programs
wget

在当前目录下得到 ​​bazel-0.26.1-darwin-x86_64​​, 重命名并增加执行权限:

mv bazel-0.26.1-darwin-x86_64 bazel
chmod

为了随时能访问 ​​bazel​​​, 需要将其路径加入到环境变量中, 修改 ​​~/.zshrc​​​ 或者 ​​~/.bashrc​​ 文件, 增加:

export PATH=$PATH:~/Programs

执行 ​​source ~/.zshrc​​​ 或者 ​​source ~/.bashrc​​​ 或 ​​exec $SHELL​​ 后, 再执行:

bazel version

## 输出结果
Build label: 0.26.1
Build target: bazel-out/darwin-opt/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar
Build time: Thu Jun 6 11:08:11 2019 (1559819291)

看是否能得到输出结果.

  1. 安装​​automake​​ , 后续编译会用上, 比如 autoconf.
brew install

开始编译

  1. 首先要进行设定一些安装选项. 进入​​tensorflow/​​​ 源码目录下, 并执行​​./configure​​​ 文件, 会要求进行一些配置, 一律选择​​N​​, 少给自己添堵~ ????????????
cd tensorflow/
./configure

WARNING: Running Bazel server needs to be killed, because the startup options are different.
WARNING: --batch mode is deprecated. Please instead explicitly shut down your Bazel server using the command "bazel shutdown".
You have bazel 0.26.1 installed.
Please specify the location of python. [Default is anaconda3-4.2.0/bin/python]: ## 默认的话则按 Enter 进行确认, 否则添加新的路径

Found possible Python library paths:
anaconda3-4.2.0/lib/python3.5/site-packages
Please input the desired Python library path to use. Default is [anaconda3-4.2.0/lib/python3.5/site-packages] ## 默认则按 Enter

Do you wish to build TensorFlow with XLA JIT support? [Y/n]: ## n
No XLA JIT support will be enabled for TensorFlow.

Do you wish to build TensorFlow with OpenCL SYCL support? [y/N]: ## n
No OpenCL SYCL support will be enabled for TensorFlow.

Do you wish to build TensorFlow with ROCm support? [y/N]: ## n
No ROCm support will be enabled for TensorFlow.

Do you wish to build TensorFlow with CUDA support? [y/N]: ## n
No CUDA support will be enabled for TensorFlow.

Do you wish to download a fresh release of clang? (Experimental) [y/N]: ## n
Clang will not be downloaded.

Please specify optimization flags to use during compilation when bazel option "--config=opt" is specified [Default is -march=native -Wno-sign-compare]: ## n


Would you like to interactively configure ./WORKSPACE for android builds? [y/N]: ## n
Not configuring the WORKSPACE for Android builds.

Do you wish to build TensorFlow with ios support? [y/N]: ## n
No iOS support will be enabled for TensorFlow.

## ...
  1. 使用 Bazel 进行源码编译
bazel build //tensorflow:libtensorflow_cc.so

等待近一个小时, 编译即可完成. 中间如果报错, Google 吧~. 我到这步没有出现啥问题.

  1. 完成编译之后, 会在当前目录下生成多个目录:
├── bazel-bin
├── bazel-genfiles
├── bazel-out
├── bazel-tensorflow
├── bazel-testlogs

可以在 ​​bazel-bin/tensorflow​​​ 目录下看到编译好后的 ​​libtensorflow_cc.so​​​ 文件以及 ​​libtensorflow_framework.1.dylib​​ 文件.

  1. 编译其他依赖, 比如 Eigen3, Protobuf, Nsync 等库:
cd tensorflow/  ## 先进入到 tensorflow 的源码目录
cd tensorflow/contrib/makefile
./build_all_linux.sh ## 执行该脚本, 对依赖项进行编译

等待数十分钟, 完成依赖项的编译. 此时将在 ​​tensorflow/contrib/makefile/downloads​​​ 目录下看到各个编译好的依赖项, 包含头文件以及静态库等. 期间曾报错 ​​autoconf not found​​​, 是因为前面 ​​brew install automake​​​ 中的 ​​automake​​ 忘了安装.

测试用例

完成 TF 的编译之后, 就要写点 C++ 代码来测试下有没有效果了. 这里参考 ​​Linux环境下编译TensorFlow C++ API和测试方法总结(完美版)​​​ 中的测试用例一, 并对 ​​CMakeLists.txt​​ 文件进行了修改, 以符合我的需要.

首先创建一个目录, 用于存放自己写的测试代码 ​​test.cpp​​:

mkdir local
cd

其中 ​​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";

而 ​​CMakeLists.txt​​ 中的内容为:

#指定 cmake 的最小版本
cmake_minimum_required(VERSION 2.8.8)
#项目名称/工程名
project(demo)
#设置c++编译器
# Set C++14 as standard for the whole project
set(CMAKE_CXX_STANDARD 14)
#设置TENSORFLOW_DIR变量,变量内容为安装的tensorflow文件夹路径
set(TENSORFLOW_DIR /Users/xxx/Codes/Python/BuildTF/tensorflow) ## 注意这里是我的 TensorFlow 源码目录
# 将源码目录保存到变量中
aux_source_directory(. DIR_SRCS) # 搜索当前目录下的所有.cpp文件
#add_library(demo $SRC_LIST) #明确指定包含哪些源文件
#设置包含的目录,项目中的include路径,换成自己的路径即可, 注意包含了 TensorFlow 本身以及第三方依赖库的路径
include_directories(
$CMAKE_CURRENT_SOURCE_DIR

$TENSORFLOW_DIR
$TENSORFLOW_DIR/bazel-genfiles
$TENSORFLOW_DIR/bazel-bin/tensorflow
$TENSORFLOW_DIR/tensorflow/contrib/makefile/downloads/nsync/public
$TENSORFLOW_DIR/tensorflow/contrib/makefile/downloads/eigen
$TENSORFLOW_DIR/tensorflow/contrib/makefile/downloads/absl
$TENSORFLOW_DIR/tensorflow/contrib/makefile/downloads/protobuf
$TENSORFLOW_DIR/tensorflow/contrib/makefile/downloads/protobuf/src
)
#设置链接库搜索目录,项目中lib路径
link_directories($TENSORFLOW_DIR/tensorflow/contrib/makefile/downloads/nsync/builds/default.macos.c++11)
link_directories($TENSORFLOW_DIR/bazel-bin/tensorflow) #动态链接库目录
#添加要编译的可执行文件
#add_executable(demo test.cpp)
add_executable(demo $DIR_SRCS) ## 生成可执行文件
#设置 target 需要链接的库
#添加可执行文件所需要的库,连接libtensorflow_cc.so和libtensorflow_framework库,链接动态链接库
#target_link_libraries(demo tensorflow_cc tensorflow_framework)
## 其中 $TENSORFLOW_DIR/bazel-bin/tensorflow/libtensorflow_framework.1.dylib 不添加也能成功编译
target_link_libraries(demo $TENSORFLOW_DIR/bazel-bin/tensorflow/libtensorflow_cc.so $TENSORFLOW_DIR/bazel-bin/tensorflow/libtensorflow_framework.1.dylib)

完成以上步骤后, 在当前目录下创建 ​​build​​​ 目录, 并执行如下命令对 ​​test.cpp​​ 进行编译:

mkdir build   #创建build文件,是为了将编译程序放到build文件中
cd build
cmake .. #使用cmake构建生成make文件
make #使用make编译
./demo #运行可执行文件

得到如下结果:

2020-04-26 23:20:31.366661: I tensorflow/core/platform/cpu_feature_guard.cc:142]

说明代码被成功编译了!

以后可以和 TensorFlow C++ API 愉快的玩耍了~ (泪流满面) ????????????

参考资料


以上是关于Mac 下 TensorFlow C++ API 的编译与测试的主要内容,如果未能解决你的问题,请参考以下文章

带有 TensorRT 的 C++ Tensorflow API

用 C++ 和 Python 编写的所有 Tensorflow 算法是不是都只是易于使用的 API?

如何使用 c++ 在 tensorflow 中保存模型

用于推理的 TensorFlow Lite C++ API 示例

在 Tensorflow 的 C++ TensorShape API 中,Python 的 None 是啥等价物?

Tensorflow C++ API实现MatMul矩阵相乘操作