0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

第四章:在 PC 交叉編譯 aarch64 的 tensorflow 開(kāi)發(fā)環(huán)境并測(cè)試

Red Linux ? 來(lái)源:Red Linux ? 作者:Red Linux ? 2024-08-25 11:38 ? 次閱讀

前言

上一篇中,我們介紹了在 PC 如何使用 C++ 加載我們保存的模型并測(cè)試。這一篇,我們介紹在 PC 上交叉編譯 aarch64 平臺(tái)的 tensorflow 源碼過(guò)程,這個(gè)難度比我想象的要難太多了。(耗時(shí)10天不止,一把心酸一把淚),首先看一下官方在文檔介紹:

2024-08-21 11 01 27.png

這里,我選擇了 tensorflow 官方測(cè)試過(guò)支持 gcc 的最后版本 2.12.0。然后介紹下 PC 的配置:

2024-08-21 11 04 47.png

然后看下 python3 和 bazel 的版本:

? python3 --version
Python 3.11.9
? bazel-5.3.0-linux-x86_64  --version
bazel 5.3.0
? aarch64-linux-gcc -v
Using built-in specs.
COLLECT_GCC=/home/red/Samba/arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-linux-gcc
COLLECT_LTO_WRAPPER=/home/red/Samba/arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-linux-gnu/bin/../libexec/gcc/aarch64-none-linux-gnu/13.3.1/lto-wrapper
Target: aarch64-none-linux-gnu
Configured with: /data/jenkins/workspace/GNU-toolchain/arm-13/src/gcc/configure --target=aarch64-none-linux-gnu --prefix= --with-sysroot=/aarch64-none-linux-gnu/libc --with-build-sysroot=/data/jenkins/workspace/GNU-toolchain/arm-13/build-aarch64-none-linux-gnu/install//aarch64-none-linux-gnu/libc --with-bugurl=https://bugs.linaro.org/ --enable-gnu-indirect-function --enable-shared --disable-libssp --disable-libmudflap --enable-checking=release --enable-languages=c,c++,fortran --with-gmp=/data/jenkins/workspace/GNU-toolchain/arm-13/build-aarch64-none-linux-gnu/host-tools --with-mpfr=/data/jenkins/workspace/GNU-toolchain/arm-13/build-aarch64-none-linux-gnu/host-tools --with-mpc=/data/jenkins/workspace/GNU-toolchain/arm-13/build-aarch64-none-linux-gnu/host-tools --with-isl=/data/jenkins/workspace/GNU-toolchain/arm-13/build-aarch64-none-linux-gnu/host-tools --enable-fix-cortex-a53-843419 --with-pkgversion='Arm GNU Toolchain 13.3.Rel1 (Build arm-13.24)'
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 13.3.1 20240614 (Arm GNU Toolchain 13.3.Rel1 (Build arm-13.24))

特別要說(shuō)明的是,交叉編譯工具聯(lián)的版本也要選擇合適的,否則會(huì)出現(xiàn)莫名奇妙的問(wèn)題(現(xiàn)在這個(gè)版本都還存在問(wèn)題:在 tensorflow 的 logging.h 這里,嗚嗚嗚)。

基礎(chǔ)性的介紹完了之后,我們開(kāi)始正文。

構(gòu)建交叉編譯腳本

交叉編譯的目的是編譯出對(duì)應(yīng)的庫(kù)和引用頭文件,為什么選擇交叉編譯是因?yàn)?PC 性能強(qiáng)?。▽?shí)測(cè)在這臺(tái) PC 上一切順利編譯也要3h+,如果是本地編譯可想而知那要多久?。?。首先要說(shuō)明一下 tensorflow 使用 Bazel 構(gòu)建。而如何在 bazel 環(huán)境下選擇自己的交叉編譯工具鏈呢?不像 makefile 或者 cmake 直接指定就行了,bazel 有點(diǎn)類(lèi)似 GN,要配置好多東西,但是個(gè)人感覺(jué)比 GN 還要復(fù)雜,想哭。

剛開(kāi)始,我走了好多彎路,一通晚上亂搜,最后搜的文章水平參差不齊導(dǎo)致徒勞浪費(fèi)了不少時(shí)間,還對(duì)自己的能力產(chǎn)生了懷疑。最后還是根據(jù)官方文檔,一點(diǎn)一點(diǎn)查漏補(bǔ)缺搭建好的交叉編譯工具鏈的配置文件。首先,附上官方的指導(dǎo)文檔連接 [Bazel Tutorial: Configure C++ Toolchains](Configuring C++ toolchains - Bazel 5.3.0)。

最后創(chuàng)建的涉及到交叉編譯工具鏈的文檔有兩個(gè):

  • toolchain/BUILD
  • toolchain/cc_toolchain_config.bzl

這里要簡(jiǎn)單介紹下 bazel 構(gòu)建工具的一些基本概念:

  • workspace(工作區(qū)):文件系統(tǒng)中包含待構(gòu)建工程的源碼目錄,每一個(gè)工作區(qū)目錄都有一個(gè)名為 WORKSPACE 的文件,可以是空的,也可以是包含有外部依賴(lài)。包含有 WORKSPACE 文件的目錄就被認(rèn)為是一個(gè)工作區(qū)的根,如果一個(gè)工作區(qū)根目錄下有其他目錄也包含有 WORKSPACE 文件,那么這個(gè)目錄會(huì)被認(rèn)為是另一個(gè)工作區(qū)而非當(dāng)前工作區(qū),特別地,WORKSPACE.bazel 是 WORKSPACE 文件的別名,且優(yōu)先級(jí)要比 WORKSPACE 要高;
  • repository(倉(cāng)庫(kù)):存儲(chǔ)代碼的地方叫做倉(cāng)庫(kù),包含 WORKSPACE 文件的目錄被認(rèn)為是主倉(cāng)庫(kù)的根,也被稱(chēng)作@;
  • package(包):倉(cāng)庫(kù)中代碼組織的最小單元是 package,包是相關(guān)文件的集合和他們之間的依賴(lài)關(guān)系。包是位于頂層倉(cāng)庫(kù)下的目錄,目錄中要含有 BUILD 或者 BUILD.bazel 文件;
  • target(目標(biāo)):目標(biāo)是一個(gè)容器,包中的元素被稱(chēng)作目標(biāo)。大多數(shù)的目標(biāo)都是文件或者規(guī)則類(lèi)型的。**文件類(lèi)型 **又可以進(jìn)一步劃分為兩種類(lèi)型:源文件(開(kāi)發(fā)者寫(xiě)出來(lái)的文件)和生成文件(根據(jù)源文件和指定的規(guī)則生成的文件)。規(guī)則類(lèi)型的文件 描述的是輸入集合和輸出集合之間的關(guān)系,包含了從輸入到輸出這個(gè)過(guò)程的步驟。此外,這里也有另外的一些類(lèi)型的目標(biāo),比如說(shuō) package group(包組),這些很少用到;
  • label(標(biāo)簽):所有的目標(biāo)都?xì)w屬一個(gè)包,目標(biāo)的名字被稱(chēng)為它的標(biāo)簽,每一個(gè)標(biāo)簽唯一對(duì)應(yīng)一個(gè)目標(biāo),比如 @myrepo//my/app/main:app_binary 這個(gè)標(biāo)簽,前半部分 @myrepo 表示倉(cāng)庫(kù)的名字是 myrepo 倉(cāng)庫(kù),如果本來(lái)就是在這個(gè)倉(cāng)庫(kù)下,那么可以進(jìn)一步簡(jiǎn)寫(xiě)為//,另外標(biāo)簽的第二部分 my/app/main 表示這個(gè)包的名字,如果本來(lái)就在 @myrepo//my/app/main 包下,可以簡(jiǎn)寫(xiě)為 :app_binary ,進(jìn)一步地,如果是文件類(lèi)型的可以間寫(xiě)為 app_binary 但是規(guī)則類(lèi)型的還是要保留這個(gè)符號(hào) :。
  • rule(規(guī)則):規(guī)則描述了輸入和輸出之間的關(guān)系,以及構(gòu)建輸出的步驟;規(guī)則有很多種,可以生成復(fù)雜的可執(zhí)行文件、庫(kù)、測(cè)試程序以及其他支持的輸出(特殊的輸出可以使用擴(kuò)展性極強(qiáng)的函數(shù): genrule())。每一個(gè)規(guī)則都有一個(gè)字符串類(lèi)型的名字屬性。srcs 字段是一個(gè) label 的 list,每一項(xiàng)都是這個(gè)規(guī)則對(duì)應(yīng)輸入的 target 名字。

至此,簡(jiǎn)單概括了 bazel 中涉及到的關(guān)鍵概念,下面結(jié)合配置交叉編譯工具鏈添加的文件,我們可以知道在根倉(cāng)庫(kù)下新建了一個(gè) toolchain 的包。看下這個(gè)包的 BUILD 文件:

package(default_visibility = ["http://visibility:public"])

# 定義了一個(gè)名字是 cross_gcc_suite 的 target,這個(gè) target 是 C++ 工具鏈的集合
cc_toolchain_suite(
# name 和 toolchains 是必須項(xiàng)
   name = "cross_gcc_suite",
   # 聲明 aarch64 平臺(tái)對(duì)應(yīng)的工具鏈名字是當(dāng)前 package 下的 aarch64_toolchain 目標(biāo)
   # 根據(jù) --cpu 和 --compiler 選項(xiàng)選擇工具鏈
   toolchains = {
       "aarch64": ":aarch64_toolchain",
   },
)

# 定義一個(gè)名字為 empty 的空 target
filegroup(name = "empty")

# 定義了一個(gè)名字是 aarch64_toolchain 的 c++ 工具鏈 target
cc_toolchain(
   name = "aarch64_toolchain",
   toolchain_identifier = "aarch64-toolchain",
   # 工具聯(lián)的配置項(xiàng)
   toolchain_config = ":aarch64_toolchain_config",
   all_files = ":empty",
   compiler_files = ":empty",
   dwp_files = ":empty",
   linker_files = ":empty",
   objcopy_files = ":empty",
   strip_files = ":empty",
   supports_param_files = 0,
)

# 在當(dāng)前 package 下的 cc_toolchain_config.bzl 中,導(dǎo)入 cc_toolchain_config 函數(shù)
load(":cc_toolchain_config.bzl", "cc_toolchain_config")

# 通過(guò) cc_toolchain_config 函數(shù),定義一個(gè)名為 aarch64_toolchain_config 的 target
cc_toolchain_config(name = "aarch64_toolchain_config")

下面我們看下 toolchain 包下的 cc_toolchain_config.bzl 文件內(nèi)容:

# toolchain/cc_toolchain_config.bzl:
# 加載一些函數(shù)
load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
load("@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl", "feature", "flag_group", "flag_set", "tool_path")

# 定義變量
all_link_actions = [ # NEW
      ACTION_NAMES.cpp_link_executable,
      ACTION_NAMES.cpp_link_dynamic_library,
      ACTION_NAMES.cpp_link_nodeps_dynamic_library,
  ]

all_compile_actions = [
   ACTION_NAMES.assemble,
   ACTION_NAMES.c_compile,
   ACTION_NAMES.clif_match,
   ACTION_NAMES.cpp_compile,
   ACTION_NAMES.cpp_header_parsing,
   ACTION_NAMES.cpp_module_codegen,
   ACTION_NAMES.cpp_module_compile,
   ACTION_NAMES.linkstamp_compile,
   ACTION_NAMES.lto_backend,
   ACTION_NAMES.preprocess_assemble,
]

all_cpp_compile_actions = [
   ACTION_NAMES.cpp_compile,
   ACTION_NAMES.cpp_header_parsing,
   ACTION_NAMES.cpp_module_codegen,
   ACTION_NAMES.cpp_module_compile,
]

# 定義函數(shù)
def _impl(ctx):
   tool_paths = [ # NEW
       tool_path(
           name = "gcc",
           # 如下替換為指定的工具鏈的路徑
           path = "/home/red/Samba/arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-linux-gcc",
       ),
       tool_path(
           name = "g++",
           path = "/home/red/Samba/arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-linux-g++",
       ),
       tool_path(
           name = "ld",
           path = "/home/red/Samba/arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-linux-ld",
       ),
       tool_path(
           name = "ar",
           path = "/home/red/Samba/arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-linux-ar",
       ),
       tool_path(
           name = "cpp",
           path = "/home/red/Samba/arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-linux-cpp",
       ),
       tool_path(
           name = "gcov",
           path = "/home/red/Samba/arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-linux-gcov",
       ),
       tool_path(
           name = "nm",
           path = "/home/red/Samba/arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-linux-nm",
       ),
       tool_path(
           name = "objdump",
           path = "/home/red/Samba/arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-linux-objdump",
       ),
       tool_path(
           name = "strip",
           path = "/home/red/Samba/arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-linux-strip",
       ),
   ]

   features= [ # NEW
          feature(
              name = "default_linker_flags",
              enabled = True,
              flag_sets = [
                  flag_set(
                      actions = all_link_actions,
                      flag_groups = ([
                          flag_group(
                              flags = [
                                  "-static", #建議交叉編譯還是帶上這個(gè)參數(shù),要不然無(wú)法在 PC 簡(jiǎn)單地正常執(zhí)行 aarch64 elf 格式的工具
                                  "-lstdc++",
                              ],
                          ),
                      ]),
                  ),
              ],
          ),
       feature(
           name = "default_compiler_flags",
           enabled = True,
           flag_sets = [
               flag_set(
                   actions = all_cpp_compile_actions,
                   flag_groups = ([
                       flag_group(
                           flags = [
                                "-fpermissive",
                           ],
                       ),
                   ]),
               ),
           ],
       ),
      ]

   return cc_common.create_cc_toolchain_config_info(
       ctx = ctx,
       features = features,
       cxx_builtin_include_directories = [ # NEW
       # 替換自己相關(guān)的頭文件,這部分可以先空起來(lái),在編譯過(guò)程中提示缺少頭文件的時(shí)候會(huì)告訴我們?nèi)鄙倌男綍r(shí)候再追加也可以
       "/home/red/Samba/arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/include/c++/13.3.1/bits",
       "/home/red/Samba/arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/include/c++/13.3.1",
       "/home/red/Samba/arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc/usr/include",
       "/home/red/Samba/arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-linux-gnu/lib/gcc/aarch64-none-linux-gnu/13.3.1/include",
       "/home/red/Samba/arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-linux-gnu/lib/gcc/aarch64-none-linux-gnu/13.3.1/include-fixed",
     ],
       toolchain_identifier = "aarch64-linux",
       host_system_name = "x86_64",
       target_system_name = "aarch64",
       target_cpu = "aarch64",
       target_libc = "unknown",
       compiler = "g++",
       abi_version = "unknown",
       abi_libc_version = "unknown",
       tool_paths = tool_paths, # NEW
   )

# 定義了一個(gè)新的規(guī)則
cc_toolchain_config = rule(
# 規(guī)則的實(shí)現(xiàn)函數(shù)
   implementation = _impl,
   attrs = {},
   provides = [CcToolchainConfigInfo],
)

有了這兩個(gè)文件,交叉編譯工具鏈就配置好了。下面為了方便使用,修改 .bazelrc 文件,追加如下兩行,可以看到使用 :

build:elinux_aarch64 --crosstool_top=//toolchain:cross_gcc_suite
build:elinux_aarch64 --host_crosstool_top=@bazel_tools//tools/cpp:toolchain

這里使用的 --crosstool_top 和 --host_crosstool_top 是 Bazel 中用于指定交叉編譯工具和主機(jī)編譯工具鏈配置的重要參數(shù),這里要注意必須要使用 --host_crosstool_top 選項(xiàng)指定一個(gè)默認(rèn)的 PC(或者 k8)平臺(tái)的工具鏈,要不然會(huì)報(bào)錯(cuò)的。
然后和 PC 端那樣,首先是 ./configure 然后就是觸發(fā)構(gòu)建了,具體命令如下:

bazel build --config=elinux_aarch64 --copt="-fPIC" --cxxopt="-fPIC" --verbose_failures //tensorflow:libtensorflow.so //tensorflow:install_headers

在編譯過(guò)程中,我使用的工具鏈需要修改如下地方:

diff --git a/tensorflow/tsl/platform/default/logging.h b/tensorflow/tsl/platform/default/logging.h
index 3578bedf0f1..24c74607a96 100644
--- a/tensorflow/tsl/platform/default/logging.h
+++ b/tensorflow/tsl/platform/default/logging.h
@@ -310,7 +310,7 @@ inline uint64 GetReferenceableValue(uint64 t) { return t; }
// it uses the definition for operator< < , with a few special cases below.
template < typename T >
inline void MakeCheckOpValueString(std::ostream* os, const T& v) {
-  // (*os) < < v;
+  //(*os) < < v;
}

// Overrides for char types provide readable values for unprintable

這部分后續(xù)應(yīng)該可以不用這么修改(暫時(shí)還沒(méi)有解決)。
然后最重要的是在后期,靜態(tài)連接 libtensorflow_framework.so.2.12.0 的時(shí)候會(huì)提示錯(cuò)誤:
1181265996.jpg

這時(shí)候需要強(qiáng)制動(dòng)態(tài)鏈接才行,怎么做呢? diff 文件是:

diff --git a/tensorflow/BUILD b/tensorflow/BUILD
index 0d27a8294f5..adcdef8f8a9 100644
--- a/tensorflow/BUILD
+++ b/tensorflow/BUILD
@@ -1100,6 +1100,8 @@ tf_cc_shared_library(
        ],
        "http://conditions:default": [
            "-Wl,--version-script,$(location //tensorflow:tf_framework_version_script.lds)",
+            "-Wl,-Bdynamic",
        ],
    }),
    linkstatic = 1,

下面構(gòu)建的時(shí)候又出現(xiàn)新的錯(cuò)誤,動(dòng)態(tài)鏈接交叉編譯出來(lái)的工具無(wú)法正常生成一些鏈接 libtensorflow 庫(kù)的文件,這時(shí)候我通過(guò) sudo chrpath -r xxxx 進(jìn)行處理一下,記得要提前將需要的庫(kù)放在一個(gè)指定的目錄,還是很復(fù)雜的。
具體集合到 tensorflow 的編譯環(huán)境的 diff 文件是:

diff --git a/tensorflow/tensorflow.bzl b/tensorflow/tensorflow.bzl
index 115ff76b414..2fb733de643 100644
--- a/tensorflow/tensorflow.bzl
+++ b/tensorflow/tensorflow.bzl
@@ -1113,12 +1113,13 @@ def tf_gen_op_wrapper_cc(
        ],
        srcs = srcs,
        tools = [":" + tool] + tf_binary_additional_srcs(),
-        cmd = ("$(location :" + tool + ") $(location :" + out_ops_file + ".h) " +
+        cmd = ("echo "xxx" | sudo -S chrpath -r  /home/red/Rcc/lib64 " + "$(location :" + tool + ")"  + ";" + "$(location :" + tool + ") $(location :" + out_ops_file + ".h) " +
               "$(location :" + out_ops_file + ".cc) " +
               str(include_internal_ops) + " " + api_def_args_str),
        compatible_with = compatible_with,

至此,關(guān)鍵的修改就是這些了,其他編譯過(guò)程中需要的修改,根據(jù)提示改一下就好了。
看一下最后編譯成功的截圖:
Screenshot from 2024-08-21 11-10-51.png

至此就有了開(kāi)發(fā) aarch64 平臺(tái) tensorflow 開(kāi)發(fā)相關(guān)的庫(kù)和頭文件了:
2024-08-21 18 22 09.png

這個(gè)庫(kù)文件真夠大的,哈哈。然后我們測(cè)試下,例程還是用上一篇的一個(gè)加載光照度模型并打印預(yù)測(cè)值的C++代碼:

#include < tensorflow/cc/saved_model/loader.h >

using namespace tensorflow;
using namespace std;

int main() {
 SessionOptions options;
 RunOptions run_options;

 SavedModelBundle bundle;
 Status status = LoadSavedModel(options, run_options, "/home/red/Downloads/fivek_dataset/test_mark_illuminance_level/illu_v03", {"serve"}, &bundle);
 if (!status.ok()) {
   std::cerr < < "Error loading model: " < < status.ToString() < < std::endl;
   return 1;
 }

 // Access the session
 Session* session = bundle.session.get();

 // Create input tensor
 Tensor input_tensor(DT_FLOAT, TensorShape({1, 255, 255, 3}));
 // Fill input tensor with data
 auto input_tensor_flat = input_tensor.flat< float >();
 std::cout < < "size of input tensor is " < < input_tensor_flat.size() < < std::endl;
   for (int i = 0; i < input_tensor_flat.size(); ++i) {
       input_tensor_flat(i) = 255.0;
   }

 // Run inference
 std::vector< Tensor > outputs;
 Status run_status = session- >Run({{"serving_default_rescaling_input", input_tensor}}, {"StatefulPartitionedCall"}, {}, &outputs);
 if (!run_status.ok()) {
   std::cerr < < "Error running model: " < < run_status.ToString() < < std::endl;
   return 1;
 }

const Eigen::TensorMap< Eigen::Tensor< float, 1, Eigen::RowMajor >, Eigen::Aligned >& prediction = outputs[0].flat< float >();
const long count = prediction.size();
for (int i = 0; i < count; ++i) {
const float value = prediction(i);
// value是該張量以一維數(shù)組表示時(shí)在索引i處的值。
   std::cout < < "hey hey " < < value < < std::endl;
}
 // Process output tensor
 Tensor ans = outputs[0];
 // auto ans_value = ans.tensor< float, 1 >();
 auto ans_value = ans.tensor< float, 2 >();
 std::cout < < ans_value(0,0) < < std::endl;
 return 0;
}

對(duì)應(yīng)的 Makefile 文件要改一下:

CROSS_COMPILE:=/home/red/Samba/arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-linux-
TARGET=tfcpp

CFLAGS:=-I/home/red/.cache/bazel/_bazel_red/81f6b3978d226a63c6d017ab1c0efa9f/execroot/org_tensorflow/bazel-out/aarch64-opt/bin/tensorflow/include/
CFLAGS+=-I/home/red/.cache/bazel/_bazel_red/81f6b3978d226a63c6d017ab1c0efa9f/execroot/org_tensorflow/bazel-out/aarch64-opt/bin/tensorflow/include/src
CFLAGS+=-I/home/red/.cache/bazel/_bazel_red/81f6b3978d226a63c6d017ab1c0efa9f/execroot/org_tensorflow/bazel-out/aarch64-opt/bin/tensorflow/include/_virtual_includes/float8/
CFLAGS+=-I/home/red/.cache/bazel/_bazel_red/81f6b3978d226a63c6d017ab1c0efa9f/execroot/org_tensorflow/bazel-out/aarch64-opt/bin/tensorflow/include/_virtual_includes/int4/

LDFLAGS:=-L/home/red/.cache/bazel/_bazel_red/81f6b3978d226a63c6d017ab1c0efa9f/execroot/org_tensorflow/bazel-out/aarch64-opt/bin/tensorflow -ltensorflow_framework
LDFLAGS+=-L/home/red/.cache/bazel/_bazel_red/81f6b3978d226a63c6d017ab1c0efa9f/execroot/org_tensorflow/bazel-out/aarch64-opt/bin/tensorflow -ltensorflow

$(TARGET):$(TARGET).cpp
       $(CROSS_COMPILE)g++ $(CFLAGS) $(LDFLAGS) $^ -o $@

clean:
       rm -frv $(TARGET)

編譯生成測(cè)試程序并測(cè)試對(duì)一個(gè)全白色圖片的測(cè)試結(jié)果
2024-08-21 18 28 39.png

可以看到和上一篇 PC 端對(duì)比的結(jié)果還是很一致的。
2024-08-21 18 30 59.png

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • PC
    PC
    +關(guān)注

    關(guān)注

    9

    文章

    2095

    瀏覽量

    154387
  • 交叉編譯
    +關(guān)注

    關(guān)注

    0

    文章

    32

    瀏覽量

    12661
  • 開(kāi)發(fā)環(huán)境

    關(guān)注

    1

    文章

    226

    瀏覽量

    16655
  • tensorflow
    +關(guān)注

    關(guān)注

    13

    文章

    329

    瀏覽量

    60557
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    【飛騰派4G版免費(fèi)試用】第四章:部署模型到飛騰派的嘗試

    /minimal/README.md交叉編譯出 minimal 例程進(jìn)行測(cè)試。 ? aarch64-none-linux-gnu-readelf -d minimal | head -
    發(fā)表于 12-20 21:10

    第四章嵌入式結(jié)構(gòu)設(shè)計(jì)2

    第四章嵌入式結(jié)構(gòu)設(shè)計(jì)2
    發(fā)表于 09-26 13:58

    《測(cè)控電路》習(xí)題完整參考答案(第四章

    《測(cè)控電路》習(xí)題完整參考答案(第四章
    發(fā)表于 05-06 23:46

    如何在x86環(huán)境下基于Qemu和Docker快速搭建AARCH64開(kāi)發(fā)環(huán)境

    內(nèi)容都是 AARCH64 開(kāi)發(fā)環(huán)境中的操作,AARCH64 基本匯編編譯運(yùn)行切換到目錄 ~/w
    發(fā)表于 07-11 15:18

    高頻電子線路第四章答案

    高頻電子線路第四章答案.
    發(fā)表于 06-05 10:38 ?32次下載

    PCB布線設(shè)計(jì)經(jīng)驗(yàn)談附原理圖(第四章)

    PCB布線設(shè)計(jì)經(jīng)驗(yàn)談附原理圖(第四章) AD轉(zhuǎn)換器的精度和分辨率增加時(shí)使用的布線技巧。   最初,模數(shù)(A/D)
    發(fā)表于 05-12 10:06 ?2455次閱讀
    PCB布線設(shè)計(jì)經(jīng)驗(yàn)談附原理圖(<b class='flag-5'>第四章</b>)

    射頻電路-第四章發(fā)送、接收機(jī)結(jié)構(gòu)

    無(wú)線通信的基本概念,射頻常用計(jì)算單位簡(jiǎn)介,射頻常用概念辨析第四章射頻系統(tǒng)介紹
    發(fā)表于 08-17 10:36 ?0次下載

    自動(dòng)控制原理第四章_根軌跡法

    自動(dòng)控制原理第四章_根軌跡法課件,學(xué)習(xí)的基礎(chǔ)資料。
    發(fā)表于 09-02 16:54 ?0次下載

    《測(cè)控電路》習(xí)題完整參考答案(第四章

    《測(cè)控電路》習(xí)題完整參考答案(第四章
    發(fā)表于 02-14 17:11 ?0次下載

    數(shù)字信號(hào)處理 第四章

    數(shù)字信號(hào)處理 第四章
    發(fā)表于 10-19 09:31 ?7次下載
    數(shù)字信號(hào)處理 <b class='flag-5'>第四章</b>

    靜噪基礎(chǔ)第四章_空間傳導(dǎo)及其應(yīng)對(duì)措施

    靜噪基礎(chǔ)第四章,空間傳導(dǎo)及其應(yīng)對(duì)措施
    發(fā)表于 01-24 16:16 ?2次下載

    計(jì)算機(jī)網(wǎng)絡(luò)第四章網(wǎng)絡(luò)層課件下載

    計(jì)算機(jī)網(wǎng)絡(luò)第四章網(wǎng)絡(luò)層課件下載
    發(fā)表于 05-17 10:44 ?0次下載

    數(shù)字信號(hào)處理第四章IFFT算法PPT課件下載

    數(shù)字信號(hào)處理第四章IFFT算法PPT課件下載
    發(fā)表于 08-31 09:22 ?4次下載

    電路理論的基礎(chǔ)知識(shí)第四章電路定理

    電路理論的基礎(chǔ)知識(shí)第四章電路定理
    發(fā)表于 01-13 13:48 ?0次下載

    如何使用預(yù)裝程序創(chuàng)建分發(fā)AArch64容器

    本文我們將探討如何使用預(yù)裝程序創(chuàng)建分發(fā) AArch64 容器。
    的頭像 發(fā)表于 09-30 10:57 ?1243次閱讀