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 https://github.com/bazelbuild/bazel/releases/download/0.26.1/bazel-0.26.1-darwin-x86_64

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

mv bazel-0.26.1-darwin-x86_64 bazel
chmod +x bazel

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

export PATH=$PATH:~/Programs

执行 source ~/.zshrc 或者 source ~/.bashrcexec $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)
Build timestamp: 1559819291
Build timestamp as int: 1559819291

看是否能得到输出结果.

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

开始编译

  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.

## ...
Configuration finished
  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 local
vim test.cpp
vim CMakeLists.txt

其中 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] Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.2 AVX AVX2 FMA
Session successfully created.

说明代码被成功编译了!

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

参考资料

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值