TensorFlow 静态 C API 库 - 如何链接 10 个子依赖项?

2023-12-12

我正在尝试链接 TensorFlow 库的静态 C API 版本。 我使用以下命令构建了静态库:

// get the sources
git clone https://github.com/tensorflow/tensorflow.git tensorflow_src

// create a build directory
mkdir builddir
cd builddir

// build the lib using CMake
cmake -S ../tensorflow_src/tensorflow/lite/c -DTFLITE_C_BUILD_SHARED_LIBS:BOOL=OFF
cmake --build . -j

这构建了libtensorflow-lite.a。但是,那libtensorflow-lite.a不是独立的,并且有自己的一组 10 个依赖项,声明在 CMake 文件中:

# TensorFlow Lite dependencies.

find_package(absl REQUIRED)
find_package(eigen REQUIRED)
find_package(farmhash REQUIRED)
find_package(fft2d REQUIRED)
find_package(flatbuffers REQUIRED)
find_package(gemmlowp REQUIRED)
find_package(neon2sse REQUIRED)
find_package(clog REQUIRED)
find_package(cpuinfo REQUIRED)  #CPUINFO is used by XNNPACK and RUY library
find_package(ruy REQUIRED)

问题是,我如何找到.a所需子库的名称?

I used find ./builddir -type f -name "*.a"列出 CMake 构建的库,预计大约有 10 个库,但实际列表太长:

./_deps/xnnpack-build/libXNNPACK.a
./_deps/ruy-build/ruy/libruy_pack_avx2_fma.a
./_deps/ruy-build/ruy/libruy_have_built_path_for_avx2_fma.a
./_deps/ruy-build/ruy/libruy_block_map.a
./_deps/ruy-build/ruy/libruy_system_aligned_alloc.a
./_deps/ruy-build/ruy/libruy_have_built_path_for_avx512.a
./_deps/ruy-build/ruy/profiler/libruy_profiler_instrumentation.a
./_deps/ruy-build/ruy/libruy_trmul.a
./_deps/ruy-build/ruy/libruy_cpuinfo.a
./_deps/ruy-build/ruy/libruy_blocking_counter.a
./_deps/ruy-build/ruy/libruy_pack_arm.a
./_deps/ruy-build/ruy/libruy_apply_multiplier.a
./_deps/ruy-build/ruy/libruy_kernel_avx2_fma.a
./_deps/ruy-build/ruy/libruy_prepacked_cache.a
./_deps/ruy-build/ruy/libruy_tune.a
./_deps/ruy-build/ruy/libruy_context_get_ctx.a
./_deps/ruy-build/ruy/libruy_have_built_path_for_avx.a
./_deps/ruy-build/ruy/libruy_ctx.a
./_deps/ruy-build/ruy/libruy_wait.a
./_deps/ruy-build/ruy/libruy_allocator.a
./_deps/ruy-build/ruy/libruy_context.a
./_deps/ruy-build/ruy/libruy_kernel_avx.a
./_deps/ruy-build/ruy/libruy_prepare_packed_matrices.a
./_deps/ruy-build/ruy/libruy_pack_avx512.a
./_deps/ruy-build/ruy/libruy_kernel_arm.a
./_deps/ruy-build/ruy/libruy_denormal.a
./_deps/ruy-build/ruy/libruy_kernel_avx512.a
./_deps/ruy-build/ruy/libruy_frontend.a
./_deps/ruy-build/ruy/libruy_pack_avx.a
./_deps/ruy-build/ruy/libruy_thread_pool.a
./_deps/flatbuffers-build/libflatbuffers.a
./_deps/fft2d-build/libfft2d_fftsg2d.a
./_deps/fft2d-build/libfft2d_fftsg.a
./_deps/farmhash-build/libfarmhash.a
./_deps/clog-build/libclog.a
./_deps/abseil-cpp-build/absl/synchronization/libabsl_graphcycles_internal.a
./_deps/abseil-cpp-build/absl/synchronization/libabsl_synchronization.a
./_deps/abseil-cpp-build/absl/strings/libabsl_strings.a
./_deps/abseil-cpp-build/absl/strings/libabsl_str_format_internal.a
./_deps/abseil-cpp-build/absl/strings/libabsl_cord.a
./_deps/abseil-cpp-build/absl/strings/libabsl_strings_internal.a
./_deps/abseil-cpp-build/absl/status/libabsl_status.a
./_deps/abseil-cpp-build/absl/hash/libabsl_city.a
./_deps/abseil-cpp-build/absl/hash/libabsl_wyhash.a
./_deps/abseil-cpp-build/absl/hash/libabsl_hash.a
./_deps/abseil-cpp-build/absl/flags/libabsl_flags_reflection.a
./_deps/abseil-cpp-build/absl/flags/libabsl_flags_program_name.a
./_deps/abseil-cpp-build/absl/flags/libabsl_flags_internal.a
./_deps/abseil-cpp-build/absl/flags/libabsl_flags_private_handle_accessor.a
./_deps/abseil-cpp-build/absl/flags/libabsl_flags_marshalling.a
./_deps/abseil-cpp-build/absl/flags/libabsl_flags_commandlineflag_internal.a
./_deps/abseil-cpp-build/absl/flags/libabsl_flags_commandlineflag.a
./_deps/abseil-cpp-build/absl/flags/libabsl_flags_config.a
./_deps/abseil-cpp-build/absl/flags/libabsl_flags.a
./_deps/abseil-cpp-build/absl/numeric/libabsl_int128.a
./_deps/abseil-cpp-build/absl/debugging/libabsl_symbolize.a
./_deps/abseil-cpp-build/absl/debugging/libabsl_debugging_internal.a
./_deps/abseil-cpp-build/absl/debugging/libabsl_demangle_internal.a
./_deps/abseil-cpp-build/absl/debugging/libabsl_stacktrace.a
./_deps/abseil-cpp-build/absl/base/libabsl_spinlock_wait.a
./_deps/abseil-cpp-build/absl/base/libabsl_raw_logging_internal.a
./_deps/abseil-cpp-build/absl/base/libabsl_malloc_internal.a
./_deps/abseil-cpp-build/absl/base/libabsl_throw_delegate.a
./_deps/abseil-cpp-build/absl/base/libabsl_exponential_biased.a
./_deps/abseil-cpp-build/absl/base/libabsl_base.a
./_deps/abseil-cpp-build/absl/base/libabsl_log_severity.a
./_deps/abseil-cpp-build/absl/time/libabsl_time_zone.a
./_deps/abseil-cpp-build/absl/time/libabsl_civil_time.a
./_deps/abseil-cpp-build/absl/time/libabsl_time.a
./_deps/abseil-cpp-build/absl/container/libabsl_hashtablez_sampler.a
./_deps/abseil-cpp-build/absl/container/libabsl_raw_hash_set.a
./_deps/abseil-cpp-build/absl/types/libabsl_bad_variant_access.a
./_deps/abseil-cpp-build/absl/types/libabsl_bad_optional_access.a
./_deps/cpuinfo-build/libcpuinfo.a

库的状态似乎如下:

  1. absl:找到 30 个库
  2. eigen:好的,模板库在标头中定义
  3. farmhash:好的,找到 1 个库
  4. fft2d:好的,找到 2 个库
  5. Flatbuffers:好的,找到 1 个库
  6. gemmlowp:好的,仅标题
  7. neon2sse:好的,仅标题
  8. clog:好的,找到 1 个库
  9. cpuinfo:好的,找到 1 个库
  10. ruy:找到 30 个库

总而言之,大多数库都没有问题,要么有 1 个库可供链接,要么这些库只是标头。尚待解决的问题是:

  • absl
  • ruy

因为它们包含大约 30.a库。 不确定我是否必须链接到所有这些?这会非常麻烦,因为我的构建系统是 Meson 并且我正在使用自定义目标()与 TensorFlow 链接。


一年后,但我自己刚刚经历过这个,所以这是我的答案。
根据我的经验(使用 makefile 并且没有你的-DTFLITE_C_BUILD_SHARED_LIBS:BOOL=OFF)执行推理的程序不需要链接到 Abseil。
您需要链接到您提到的所有其他库,除了ruy_kernel_arm and ruy_pack_arm,假设您在 x64 平台上运行程序。 (烦人的是-DTFLITE_ENABLE_RUY=OFF在构建 TfLite 时不受尊重,所以你只能选择 Ruy)

详细步骤:

Build TfLite:
mkdir ~/my_tflite_project
cd ~/my_tflite_project/
git clone https://github.com/tensorflow/tensorflow.git tensorflow_src
mkdir tflite_build_x64
cd tflite_build_x64/
cmake ../tensorflow_src/tensorflow/lite/
    /* You may encounter two CMake messages:
    -- The Fortran compiler identification is unknown
    I believe a Fortran compiler is only necessary to build Fortran bindings for TfLite.

    -- Could NOT find CLANG_FORMAT: Found unsuitable version "0.0", but required is exact version "9" (found CLANG_FORMAT_EXECUTABLE-NOTFOUND)
    sudo apt install clang-format-9
    Annoyingly you need clang-format-9, plain clang-format (version 13, the newest) won't do. */
cmake --build . -j 4

相关库:

$ cd ~/my_tflite_project/tflite_build_x64
$ ls *.a
libtensorflow-lite.a
$ ls pthreadpool/*.a
pthreadpool/libpthreadpool.a
$ ls _deps/*/*.a
_deps/clog-build/libclog.a        _deps/farmhash-build/libfarmhash.a  _deps/fft2d-build/libfft2d_fftsg2d.a      _deps/xnnpack-build/libXNNPACK.a
_deps/cpuinfo-build/libcpuinfo.a  _deps/fft2d-build/libfft2d_fftsg.a  _deps/flatbuffers-build/libflatbuffers.a
$ ls _deps/ruy-build/ruy/*.a
_deps/ruy-build/ruy/libruy_allocator.a         _deps/ruy-build/ruy/libruy_ctx.a                           _deps/ruy-build/ruy/libruy_kernel_avx.a       _deps/ruy-build/ruy/libruy_prepacked_cache.a
_deps/ruy-build/ruy/libruy_apply_multiplier.a  _deps/ruy-build/ruy/libruy_denormal.a                      _deps/ruy-build/ruy/libruy_kernel_avx2_fma.a  _deps/ruy-build/ruy/libruy_prepare_packed_matrices.a
_deps/ruy-build/ruy/libruy_block_map.a         _deps/ruy-build/ruy/libruy_frontend.a                      _deps/ruy-build/ruy/libruy_kernel_avx512.a    _deps/ruy-build/ruy/libruy_system_aligned_alloc.a
_deps/ruy-build/ruy/libruy_blocking_counter.a  _deps/ruy-build/ruy/libruy_have_built_path_for_avx.a       _deps/ruy-build/ruy/libruy_pack_arm.a         _deps/ruy-build/ruy/libruy_thread_pool.a
_deps/ruy-build/ruy/libruy_context.a           _deps/ruy-build/ruy/libruy_have_built_path_for_avx2_fma.a  _deps/ruy-build/ruy/libruy_pack_avx.a         _deps/ruy-build/ruy/libruy_trmul.a
_deps/ruy-build/ruy/libruy_context_get_ctx.a   _deps/ruy-build/ruy/libruy_have_built_path_for_avx512.a    _deps/ruy-build/ruy/libruy_pack_avx2_fma.a    _deps/ruy-build/ruy/libruy_tune.a
_deps/ruy-build/ruy/libruy_cpuinfo.a           _deps/ruy-build/ruy/libruy_kernel_arm.a                    _deps/ruy-build/ruy/libruy_pack_avx512.a      _deps/ruy-build/ruy/libruy_wait.a

使用 TfLite 构建 MWE:

$ cd ~/my_tflite_project
$ mkdir my_dev_x64
$ cd my_dev_x64/
/* Construct minimal.cpp and makefile below */
$ cat minimal.cpp
#include "tensorflow/lite/model.h"
#include "tensorflow/lite/interpreter.h"
#include "tensorflow/lite/kernels/register.h"
#include <iostream>

int main() {
    std::unique_ptr<tflite::FlatBufferModel> model = tflite::FlatBufferModel::BuildFromFile("your_network_here.tflite");
    tflite::ops::builtin::BuiltinOpResolver resolver;

    std::cout "Done\n";
    return EXIT_SUCCESS;
}

$ cat makefile
COMPILER     := g++

LINKER       := g++

CXX_FILES    := minimal.cpp

OBJ_FILES    := $(CXX_FILES:.cpp=.o)

EXE_FILE     := app

INCLUDE_DIRS := -I../tensorflow_src -I../tflite_build_x64/flatbuffers/include

LIB_DIRS     := \
        -L../tflite_build_x64 \
        -L../tflite_build_x64/_deps/fft2d-build \
        -L../tflite_build_x64/_deps/flatbuffers-build \
        -L../tflite_build_x64/_deps/ruy-build/ruy \
        -L../tflite_build_x64/_deps/farmhash-build \
        -L../tflite_build_x64/_deps/xnnpack-build \
        -L../tflite_build_x64/_deps/cpuinfo-build \
        -L../tflite_build_x64/_deps/clog-build \
        -L../tflite_build_x64/pthreadpool

LIBS         := \
        -ltensorflow-lite \
        -lfft2d_fftsg \
        -lfft2d_fftsg2d \
        -lflatbuffers \
        -lruy_ctx \
        -lruy_allocator \
        -lruy_frontend \
        -lruy_context_get_ctx \
        -lruy_context \
        -lruy_apply_multiplier \
        -lruy_prepacked_cache \
        -lruy_tune \
        -lruy_cpuinfo \
        -lruy_system_aligned_alloc \
        -lruy_prepare_packed_matrices \
        -lruy_trmul \
        -lruy_block_map \
        -lruy_denormal \
        -lruy_thread_pool \
        -lruy_blocking_counter \
        -lruy_wait \
        -lruy_kernel_avx \
        -lruy_kernel_avx2_fma \
        -lruy_kernel_avx512 \
        -lruy_pack_avx \
        -lruy_pack_avx2_fma \
        -lruy_pack_avx512 \
        -lruy_have_built_path_for_avx \
        -lruy_have_built_path_for_avx2_fma \
        -lruy_have_built_path_for_avx512 \
        -lfarmhash \
        -lXNNPACK \
        -lpthreadpool \
        -lcpuinfo \
        -lclog

CXX_FLAGS    := -Wall #-pedantic

LINK_FLAGS   :=

#Do not print the output of the commands
.SILENT:

#Phony targets do not represent actual files, so files with the following names are ignored
.PHONY: clean depend

#Link object files to form an executable file
$(EXE_FILE): $(OBJ_FILES)
        $(LINKER) $(LINK_FLAGS) $(OBJ_FILES) -o $(EXE_FILE) $(LIB_DIRS) $(LIBS)

#Compile cpp files to object files
%.o: %.cpp
        $(COMPILER) $(CXX_FLAGS) $(INCLUDE_DIRS) -c $<

#Remove object files, executable, and possible linkinfo files
clean:
        -rm -f $(OBJ_FILES) $(EXE_FILE)

#Generate dependency file
depend:
        $(COMPILER) $(CXX_FLAGS) $(INCLUDE_DIRS) -MM $(CXX_FILES) > make.dep

#Include dependency file
-include make.dep

构建并运行 MWE:

$ cd ~/my_tflite_project/my_dev_x64
$ make
$ ./app
Done

希望这可以帮助您或其他一些可怜的家伙让 TfLite C++ 工作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TensorFlow 静态 C API 库 - 如何链接 10 个子依赖项? 的相关文章

随机推荐

  • 移动应用程序时会重置用户设置

    我注意到 如果您将该应用程序 exe 文件移动到另一个位置 用户设置将重置 据我了解 发生这种情况是因为应用程序数据文件夹中的位置也基于 exe 的路径 在生成哈希时会考虑到这一点 我知道有不同的替代方案 可以使用注册表或手动创建自定义配置
  • 将 null 放置在列表末尾

    我需要将空对象放置在末尾List 这是我为此目的所做的示例 public static void main String args List
  • 如何显示ProgressBar并使其进度?(Xamarin.Android)

    我调用一个 Web 服务 它获取 4 个文件 在加载这些文件时 我想向用户显示进度 圆形或水平都没关系 我已按照互联网上的示例进行操作 但屏幕上没有显示任何内容 MobileSellReference Service1 service ne
  • 有没有办法分析 Chromecast 崩溃?

    显然 崩溃后 端口 9222 上的开发者工具没有任何用处 因为 远程调试已因原因终止 websocket close 例如 我如何检索记录的时间线 或获取调用堆栈 或者找到有关 Chromecast 决定自行重启的原因的任何信息 调试 Ch
  • 在 JS 中移动元素

    我正在学习 javascript 并尝试做一个简单的练习 我有一个文本框并想用键盘控制它 我的 HTML 如下 目前 我只是尝试 1 个方向 const myBox document querySelector h1 document ad
  • D3 节点半径取决于链接数量:权重属性

    我正在尝试使用 D3 创建力定向图 就目前而言 节点的半径取决于核心价值JSON 中的对 d 尺寸 我知道d3 权重属性可用于计算链接数量并关联圆的半径属性 但我不知何故无法让它工作 请在这件事上给予我帮助 找到下面的代码 d3 json
  • “合并”替换 Keras/Tensorflow/Python3

    Merge 未在 Keras Tensorflow Python3 版本上运行 在以前的版本中 合并正在运行 但现在 它没有运行 所以我想我应该用替换 合并 来转换此代码 新的 Keras Tensorflow Python3 版本中缺少
  • 给定一个数组,找出每个元素的下一个较小元素

    给定一个数组 在不改变元素原始顺序的情况下 为每个元素找到数组中下一个较小的元素 例如 假设给定数组为 4 2 1 5 3 结果数组将为 2 1 1 3 1 我在一次采访中被问到这个问题 但我想不出比简单的 O n 2 解决方案更好的解决方
  • SQLite是否支持“删除自”

    这是 Microsoft SQL Server 的 T SQL 上的有效语法 但在 SQLite 中无效 是否有在 SQLite 中执行相同操作的替代语法 DELETE FROM something FROM something INNER
  • HTML元素的id属性在整个页面中必须是唯一的吗?

    我正在使用 jQuery 我只是想知道 ID 在整个页面中是否必须始终是唯一的 我知道课程可以重复多次 那么 ID 呢 是的 它必须是独一无二的 HTML4 https www w3 org TR html4 struct global h
  • 如果循环正在运行,wifi.sta 模块会连接吗?

    我试图检测模块何时实际连接到我的 wifi AP 因为 connect 没有回调 我做了如下简单的事情 wifi sta config SSID password wifi sta connect tmr delay 1000000 i 0
  • 在 es6 中添加行而不推送反应状态

    我不确定我做的是正确的事情 我在 setState 之外改变变量 这很好 对吧 或者有更优雅的方法来做到这一点 state persons name jay age 10 addRow gt const temp this state te
  • 对 asp-route-parameter 使用隐藏字段值

    我在 PartialView 中有一个隐藏字段 其中包含我想要的值 jQuery 填充它 我需要在 foreach asp route parameter 中使用相同的值 div class js products list div
  • 通过Id查询Morphia

    我正在使用 Morphia MongoDB 的 Pojo 映射器 我发现一项在我看来应该非常简单的任务很困难 通过 id 获取对象 我能够找到集合中的所有对象 但无法弄清楚使用从列表中获得的 id 进行查询的简单任务 我实际上是在谈论 Ob
  • 如何保护PHP中的配置文件?

    我正在开发一个 PHP 项目 为其他程序员开发模板引擎 这个想法很简单 将有一个包含模板的模板文件夹和一个包含页面的页面文件夹 php 获取模板并使用当前 url 将页面插入其中 几年前我在没有面向对象的情况下完成了这个项目 但现在我正在尝
  • InvalidOperationException:类型“System.Linq.Queryable”上的方法“Where”与提供的参数不兼容

    下面的代码已更新并且可以正常工作 LinqPad 有动态 OrderBy 示例 我想做的只是简单地对此示例应用 Where 而不是 OrderBy 这是我的代码 IQueryable query from p in Purchases wh
  • 将 csv 文件读入结构数组

    我开始用C编写代码 我的代码如下 include
  • 在 Google 地图之外保存地图实例

    我制作了一个谷歌地图 API HTML 脚本 当用户单击地图时 它会创建标记 我还集成了 Google 登录功能 因此用户是独一无二的并且拥有个人资料 我现在想要做到这一点 以便用户可以在他们想要的位置上创建标记 然后保存地图 以便他们稍后
  • 如何从用户输入中收集信息并将其应用到其他地方

    您好 我是编程新手 我正在尝试编写一个代码来从输入中收集信息并确定它是否是有效的字母表 这是我到目前为止的代码 words word input Character while word if word not in words words
  • TensorFlow 静态 C API 库 - 如何链接 10 个子依赖项?

    我正在尝试链接 TensorFlow 库的静态 C API 版本 我使用以下命令构建了静态库 get the sources git clone https github com tensorflow tensorflow git tens