编译tensorflow-lite-with-select-tf-ops遇到的坑

前言

最近在将tf训练的模型迁移到Android端,使用的是tensorflow-lite,由于模型用到了一些tflite还没有支持的op,所以需要让tflite支持tf的op,官方没有直接给出aar,而是让自己用bazel去编译一个,实在是有点坑啊,官方编译网址:

https://www.tensorflow.org/lite/using_select_tf_ops

大致方法就是:

【1】 安装bazel,【https://docs.bazel.build/versions/master/install.html

【2】 下载tensorflow源码,【https://github.com/tensorflow/tensorflow

【3】 进入源码所在目录,修改WORKSPACE文件,增加sdk路径:

android_sdk_repository (
    name = "androidsdk",
    api_level = 26,
    build_tools_version = "26.0.2",
    path = "/Users/vell/Library/Android/sdk/",
)

android_ndk_repository(
    name = "androidndk",
    path = "/Users/vell/Library/Android/sdk/ndk-bundle",
    api_level = 19,
)

注意修改自己的sdk路径和版本

【4】 进入源码所在的目录执行如下命令:

bazel build --cxxopt='--std=c++11' -c opt             \\
  --config=android_arm --config=monolithic          \\
  //tensorflow/lite/java:tensorflow-lite-with-select-tf-ops

【5】 如果你运气足够好的话,你将在如下目录找到编译好的aar:

bazel-genfiles/tensorflow/lite/java/tensorflow-lite-with-select-tf-ops.aar

【6】 大功告成,但是,我就是那个运气极其差的,总是遇到些奇怪的问题,我这算是有两个吧


“undeclared inclusion(s)” error

ERROR: /data/vellhe/tensorflow-master/tensorflow/core/common_runtime/eager/BUILD:40:1: undeclared inclusion(s) in rule '//tensorflow/core/common_runtime/eager:context':
this rule is missing dependency declarations for the following files included by 'tensorflow/core/common_runtime/eager/context.cc':
  'tensorflow/core/distributed_runtime/collective_param_resolver_distributed.h'
  'tensorflow/core/distributed_runtime/device_resolver_distributed.h'
  'tensorflow/core/distributed_runtime/rpc_collective_executor_mgr.h'
Target //tensorflow/lite/java:tensorflow-lite-with-select-tf-ops failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 85.812s, Critical Path: 33.15s
INFO: 666 processes: 655 local, 11 worker.
FAILED: Build did NOT complete successfully

这个是我遇到最坑的,由于对bazel工具不熟悉,各种google,花了整整一个上午,才搞出点名堂了,如果编译遇到坑的话,还是建议先去熟悉下bazel

其实stackoverflow上已经有大神给到了解决方法:

How to resolve bazel “undeclared inclusion(s)” error?

只不过,如果没有bazel背景是很难真正看懂怎么操作

问题原因

错误信息里可以看出,是.h文件没有声明,tensorflow/core/common_runtime/eager/context.cc里缺三个.h文件的声明,缺的.h文件都在tensorflow/core/distributed_runtime目录下,tensorflow/core/distributed_runtime里有一个BUILD文件,这个目录就相当于也是一个模块,所以需要做的就是将tensorflow/core/distributed_runtime里的.h文件告诉tensorflow/core/common_runtime/eager/context.cc

解决方法:

【1】 编辑tensorflow/core/distributed_runtime/BUILD文件,新增如下:

cc_library(
    name = "headers",
    hdrs = glob(["*.h"])
)

【2】 编辑tensorflow/core/common_runtime/eager/BUILD文件,找到//tensorflow/core/common_runtime/eager:context的定义,在deps里增加一条,"//tensorflow/core/distributed_runtime:headers",,修改后如下:

【3】 大功告成


no member named 'round' in namespace 'std';

ERROR: /Users/vell/workspace/github/tensorflow-master/tensorflow/lite/kernels/internal/BUILD:418:1: C++ compilation of rule '//tensorflow/lite/kernels/internal:neon_tensor_utils' failed (Exit 1)
In file included from tensorflow/lite/kernels/internal/reference/portable_tensor_utils.cc:19:
./tensorflow/lite/c/builtin_op_data.h:154:9: warning: empty struct has size 0 in C, size 1 in C++ [-Wextern-c-compat]
typedef struct {
        ^
./tensorflow/lite/c/builtin_op_data.h:157:9: warning: empty struct has size 0 in C, size 1 in C++ [-Wextern-c-compat]
typedef struct {
        ^
./tensorflow/lite/c/builtin_op_data.h:232:9: warning: empty struct has size 0 in C, size 1 in C++ [-Wextern-c-compat]
typedef struct {
        ^
./tensorflow/lite/c/builtin_op_data.h:235:9: warning: empty struct has size 0 in C, size 1 in C++ [-Wextern-c-compat]
typedef struct {
        ^
./tensorflow/lite/c/builtin_op_data.h:274:9: warning: empty struct has size 0 in C, size 1 in C++ [-Wextern-c-compat]
typedef struct {
        ^
In file included from tensorflow/lite/kernels/internal/reference/portable_tensor_utils.cc:21:
./tensorflow/lite/kernels/internal/round.h:28:10: error: no member named 'round' in namespace 'std'; did you mean simply 'round'?
  return std::round(x);
         ^~~~~~~~~~
         round
external/androidndk/ndk/sysroot/usr/include/math.h:255:8: note: 'round' declared here
double round(double __x);
       ^
5 warnings and 1 error generated.
Target //tensorflow/lite/java:tensorflow-lite-with-select-tf-ops failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 6.732s, Critical Path: 3.36s
INFO: 0 processes.
FAILED: Build did NOT complete successfully

问题原因

tensorflow/lite/kernels/internal/round.h:28:10处,调用了std::round(x);,而在std的namespace里没有round这个函数,所以报错了

解决方法

将std去掉,如下:

本站文章资源均来源自网络,除非特别声明,否则均不代表站方观点,并仅供查阅,不作为任何参考依据!
如有侵权请及时跟我们联系,本站将及时删除!
如遇版权问题,请查看 本站版权声明
THE END
分享
二维码
海报
编译tensorflow-lite-with-select-tf-ops遇到的坑
官方没有直接给出AAR,而是让自己用巴泽尔去编译一个,实在是有点坑啊。
<<上一篇
下一篇>>