diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..335cc7f2197b4f3e80c61c24f86a5091fed5920d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,20 @@
+# ignore .a .o
+*.[ao]
+*.so
+*.ms
+
+# ignore build
+build/
+libs/
+obj/
+_ignore/
+
+# ignore schema
+jni/include/schema/
+
+# ignore vscode
+.vscode
+
+# ignore runtime file
+deploy.bat
+log.txt
\ No newline at end of file
diff --git a/BUILD.gn b/BUILD.gn
new file mode 100644
index 0000000000000000000000000000000000000000..36de2f911be63bc22a08c0277bf7e53ecae370e3
--- /dev/null
+++ b/BUILD.gn
@@ -0,0 +1,28 @@
+# Copyright (c) 2022 Huawei Device Co., Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//build/ohos.gni")
+
+group("nnrt_target") {
+ deps = [
+ "frameworks:libneural_network_runtime"
+ ]
+}
+
+group("nnrt_test_target") {
+ testonly = true
+ deps = [
+ "test/unittest:unittest",
+ "test/system_test:system_test"
+ ]
+}
diff --git a/LICENSE b/LICENSE
index 29f81d812f3e768fa89638d1f72920dbfd1413a8..4a459866a57c25462afad17f3fe0b50d440da080 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,3 +1,4 @@
+
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
@@ -173,29 +174,4 @@
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
+ END OF TERMS AND CONDITIONS
\ No newline at end of file
diff --git a/OAT.xml b/OAT.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8c1351e64115b03242d96e3fff2a722b1d4b5c11
--- /dev/null
+++ b/OAT.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/README.en.md b/README.en.md
deleted file mode 100644
index d2337089f2a3a14e80d163982b0ddb7d16e6ba67..0000000000000000000000000000000000000000
--- a/README.en.md
+++ /dev/null
@@ -1,36 +0,0 @@
-# neural_network_runtime
-
-#### Description
-{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
-
-#### Software Architecture
-Software architecture description
-
-#### Installation
-
-1. xxxx
-2. xxxx
-3. xxxx
-
-#### Instructions
-
-1. xxxx
-2. xxxx
-3. xxxx
-
-#### Contribution
-
-1. Fork the repository
-2. Create Feat_xxx branch
-3. Commit your code
-4. Create Pull Request
-
-
-#### Gitee Feature
-
-1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
-2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
-3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
-4. The most valuable open source project [GVP](https://gitee.com/gvp)
-5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
-6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
diff --git a/README.md b/README.md
deleted file mode 100644
index dc3cc3646c1b1d1fc42f2ee1ddc8a80a66d5592f..0000000000000000000000000000000000000000
--- a/README.md
+++ /dev/null
@@ -1,39 +0,0 @@
-# neural_network_runtime
-
-#### 介绍
-{**以下是 Gitee 平台说明,您可以替换此简介**
-Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台
-无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
-
-#### 软件架构
-软件架构说明
-
-
-#### 安装教程
-
-1. xxxx
-2. xxxx
-3. xxxx
-
-#### 使用说明
-
-1. xxxx
-2. xxxx
-3. xxxx
-
-#### 参与贡献
-
-1. Fork 本仓库
-2. 新建 Feat_xxx 分支
-3. 提交代码
-4. 新建 Pull Request
-
-
-#### 特技
-
-1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
-2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
-3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
-4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
-5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
-6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
diff --git a/README_zh.md b/README_zh.md
new file mode 100644
index 0000000000000000000000000000000000000000..720bf3c0e49f4386ff954a2d89550536df15772e
--- /dev/null
+++ b/README_zh.md
@@ -0,0 +1,26 @@
+# Neural Network Runtime
+
+Neural Network Runtime(神经网络运行时)是一套面向AI领域的运行时部件,适配上层AI推理引擎和底层加速芯片,为端侧AI推理引擎提供硬件加速的计算能力。
+
+## 基本概念
+
+在开发前,需要先了解以下概念,以便更好地理解全文内容:
+
+- Native API:Openharmony 面向应用开发者的C语言接口。
+- HDI:Hardware Device Interface,硬件设备接口,是OpenHarmony中系统组件与芯片组件通信的接口。关于更多HDI的细节,请浏览[驱动子系统](https://gitee.com/openharmony/docs/blob/master/zh-cn/readme/%E9%A9%B1%E5%8A%A8%E5%AD%90%E7%B3%BB%E7%BB%9F.md)。
+
+## 运作机制
+
+**图1** Neural Network Runtime架构图
+
+
+如图1所示,在OpenHarmony系统上,AI应用通常要经过AI推理引擎和Neural Network Runtime才能对接底层芯片驱动,进而加速推理计算。Neural Network Runtime和芯片驱动直接通过HDI接口交互,Neural Network Runtime将模型和数据传递给芯片驱动,通过HDI接口在加速芯片上执行推理计算,计算结果通过Neural Network Runtime、AI推理引擎逐层返回至AI应用。
+
+通常,AI应用、AI推理引擎、Neural Network Runtime处在同一个进程下,芯片驱动运行在另一个进程下,两者之间需要借助进程间通信(IPC)传递模型和计算数据。Neural Network Runtime根据HDI接口实现了HDI客户端,相应的,芯片厂商需要根据HDI接口实现并开放HDI服务。
+
+架构图中每层功能简单阐述如下:
+- AI应用:借助AI模型,提供丰富的应用能力,如:图像分类、人脸识别、文字识别等。
+- AI推理引擎:为AI应用提供模型搭建、模型优化、推理计算的能力。
+- Neural Network Runtime:作为AI推理引擎和底层加速芯片的桥梁,它开放了标准统一的HDI接口,不同的芯片都可以通过HDI接口接入Neural Network Runtime。
+- HDI服务端:HDI服务端接收Neural Network Runtime传入的模型,将模型转换为加速芯片驱动所使用模型格式,并调用芯片驱动的接口执行计算。
+- 加速芯片:加速芯片通常能够加速AI模型或者模型中部分算子的计算,提供优于CPU的性能。
\ No newline at end of file
diff --git a/bundle.json b/bundle.json
new file mode 100644
index 0000000000000000000000000000000000000000..9f69a3eb16e558ee5a8e3ba135a766e5d5fc7fd0
--- /dev/null
+++ b/bundle.json
@@ -0,0 +1,50 @@
+{
+ "name": "@ohos/neural_network_runtime",
+ "description": "The Neural Network Runtime that bridges the inference framework and the device accelerator.",
+ "version": "3.2",
+ "license": "MIT",
+ "publishAs": "code-segment",
+ "segment": {
+ "destPath": "foundation/ai/neural_network_runtime"
+ },
+ "dirs": {},
+ "scripts": {},
+ "licensePath": "COPYING",
+ "readmePath": {
+ "en": "README.rst"
+ },
+ "component": {
+ "name": "neural_network_runtime",
+ "subsystem": "ai",
+ "syscap": [],
+ "features": [],
+ "adapted_system_type": ["standard"],
+ "rom": "1024KB",
+ "ram": "2048KB",
+ "deps": {
+ "components": [
+ "hilog"
+ ],
+ "third_party": []
+ },
+ "build": {
+ "sub_component": [
+ "//foundation/ai/neural_network_runtime:nnrt_target"
+ ],
+ "inner_kits": [
+ {"type": "so",
+ "name": "//foundation/ai/neural_network_runtime:nnrt_target",
+ "header": {
+ "header_files": [
+ "neural_network_runtime_inner.h"
+ ],
+ "header_base":"//foundation/ai/neural_network_runtime/interfaces/innerkits/c"
+ }
+ }
+ ],
+ "test": [
+ "//foundation/ai/neural_network_runtime:nnrt_test_target"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/common/log.h b/common/log.h
new file mode 100644
index 0000000000000000000000000000000000000000..c75b3255fb8a98976afed0f7a02ce15c3dc9ad6b
--- /dev/null
+++ b/common/log.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NEURAL_NETWORK_RUNTIME_LOG_H
+#define NEURAL_NETWORK_RUNTIME_LOG_H
+
+#include
+#include
+#include "hilog/log_c.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef NNR_LOG_DOMAIN
+#define NNR_LOG_DOMAIN 0xD002101
+#endif
+
+#define LOGD(...) HiLogPrint(LOG_CORE, LOG_DEBUG, NNR_LOG_DOMAIN, "NNRt", __VA_ARGS__)
+#define LOGI(...) HiLogPrint(LOG_CORE, LOG_INFO, NNR_LOG_DOMAIN, "NNRt", __VA_ARGS__)
+#define LOGW(...) HiLogPrint(LOG_CORE, LOG_WARN, NNR_LOG_DOMAIN, "NNRt", __VA_ARGS__)
+#define LOGE(...) HiLogPrint(LOG_CORE, LOG_ERROR, NNR_LOG_DOMAIN, "NNRt", __VA_ARGS__)
+#define LOGF(...) HiLogPrint(LOG_CORE, LOG_FATAL, NNR_LOG_DOMAIN, "NNRt", __VA_ARGS__)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NEURAL_NETWORK_RUNTIME_LOG_H
diff --git a/common/scoped_trace.h b/common/scoped_trace.h
new file mode 100644
index 0000000000000000000000000000000000000000..650503e623a3f6b870c736673e78118c82274d95
--- /dev/null
+++ b/common/scoped_trace.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NEURAL_NETWORK_RUNTIME_SCOPED_TRACE_H
+#define NEURAL_NETWORK_RUNTIME_SCOPED_TRACE_H
+
+#include
+#include "hitrace/trace.h"
+
+#define NNRT_TRACE_NAME(name) ScopedTrace ___tracer(name)
+namespace OHOS {
+namespace NeuralNetworkRuntime {
+class ScopedTrace {
+public:
+ inline ScopedTrace(const std::string& name)
+ {
+ m_name = name;
+ HiviewDFX::HiTraceId traceId = HiviewDFX::HiTraceChain::GetId();
+ if (traceId.IsValid()) {
+ HiviewDFX::HiTraceChain::Tracepoint(HITRACE_TP_GENERAL, traceId, "NNRt Trace start: %s", name.c_str());
+ }
+ }
+
+ inline ~ScopedTrace()
+ {
+ HiviewDFX::HiTraceId traceId = HiviewDFX::HiTraceChain::GetId();
+ if (traceId.IsValid()) {
+ HiviewDFX::HiTraceChain::Tracepoint(HITRACE_TP_GENERAL, traceId, "NNRt Trace end: %s", m_name.c_str());
+ }
+ }
+
+private:
+ std::string m_name {};
+};
+} // namespace NeuralNetworkRuntime
+} // namespace OHOS
+
+#endif // NEURAL_NETWORK_RUNTIME_SCOPED_TRACE_H
diff --git a/common/utils.h b/common/utils.h
new file mode 100644
index 0000000000000000000000000000000000000000..7430ad085b5b92eb86e7b053ccf3cbf84f1cb050
--- /dev/null
+++ b/common/utils.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NEURAL_NETWORK_RUNTIME_UTILS_H
+#define NEURAL_NETWORK_RUNTIME_UTILS_H
+
+#include
+
+#include "log.h"
+
+namespace OHOS {
+namespace NeuralNetworkRuntime {
+template
+std::shared_ptr CreateSharedPtr(Args&&... args)
+{
+ std::shared_ptr tPtr = nullptr;
+ try {
+ tPtr = std::make_shared(args...);
+ } catch (const std::bad_alloc& except) {
+ LOGW("Create a new shared pointer failed. Error: %s", except.what());
+ return nullptr;
+ }
+ return tPtr;
+}
+
+} // namespace NeuralNetworkRuntime
+} // namespace OHOS
+#endif // NEURAL_NETWORK_RUNTIME_UTILS_H
diff --git a/example/deep_learning_framework/CMakeLists.txt b/example/deep_learning_framework/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c3dbaddb12183afeb6c431775ddafe983a896816
--- /dev/null
+++ b/example/deep_learning_framework/CMakeLists.txt
@@ -0,0 +1,29 @@
+#
+# Copyright (c) 2022 Huawei Device Co., Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# CMake lowest version requirement
+cmake_minimum_required(VERSION 3.16.5)
+
+# project information
+project(label_classification)
+
+set(CMAKE_C_FLAGS "-pthread -fstack-protector-all -fPIC -D_FORTIFY_SOURCE=2")
+
+# If the CPU architecture is 32-bit, -march=armv7-a
+set(CMAKE_CXX_FLAGS "-pthread -fstack-protector-all -fPIC -D_FORTIFY_SOURCE=2 -march=armv7-a")
+set(LOCAL_DIRECTORY_PATH ${PROJECT_SOURCE_DIR})
+
+add_subdirectory(${LOCAL_DIRECTORY_PATH}/tflite)
+
diff --git a/example/deep_learning_framework/Flowchart.png b/example/deep_learning_framework/Flowchart.png
new file mode 100644
index 0000000000000000000000000000000000000000..d6018c17a9116b72f2ebc10e38e39764d2ec0058
Binary files /dev/null and b/example/deep_learning_framework/Flowchart.png differ
diff --git a/example/deep_learning_framework/Principle.png b/example/deep_learning_framework/Principle.png
new file mode 100644
index 0000000000000000000000000000000000000000..0ef12d2b71f31949258eed17f55dd852f8307586
Binary files /dev/null and b/example/deep_learning_framework/Principle.png differ
diff --git a/example/deep_learning_framework/README_zh.md b/example/deep_learning_framework/README_zh.md
new file mode 100644
index 0000000000000000000000000000000000000000..ef8e58e655f3e6d25ef4f8aa871850551eca3007
--- /dev/null
+++ b/example/deep_learning_framework/README_zh.md
@@ -0,0 +1,218 @@
+# Tensorflow Lite 接入NNRt Delegate Demo开发指南
+
+## 概述
+
+### 功能简介
+- 神经网络运行时部件(NNRt)是跨设备的AI运行时框架,作为端侧推理框架和专用加速芯片的中间桥梁,为端侧推理框架提供了统一的Native接口;
+- 本demo旨在介绍上层AI业务如何利用NNRt在专有芯片上加速推理,使能OpenHarmony社区生态;
+- 本demo根据用户输入参数(模型、标签、模型输入shape、循环浮点推理次数、是否允许动态尺寸推理、以及是否打印结果等)完成标签分类模型推理,用户可通过打印信息观察在不同条件下的模型推理性能、精度等KIP。
+
+### 基本概念
+在开发前,开发者需要先了解以下概念,以便更好地理解全文内容:
+- NNRt: Neural Network Runtime,神经网络运行时,是本指导主要介绍的部件。
+- OHOS:OpenHarmony Operating System,开源鸿蒙操作系统。
+
+### 约束与限制
+- 系统版本:OpenHarmonyOS 3.2及以上
+- 开发环境:Ubuntu 18.04及以上
+- 接入设备:OpenHarmony定义的标准设备
+- 其他开发依赖:
+ - tensorflow-lite.so及其依赖库,目前完成在tensorflow lite 2.6版本上的测试;
+ - NNRt库libneural_network_runtime.z.so;
+ - TensorFlow Lite头文件:https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite;
+ - mobilenetv2.tflite模型(https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_1.4_224.tgz);
+ - 标签文件labels.txt;
+ - 测试图片grace_hopper.bmp;
+
+### 运作机制
+
+
+ - 用户调用TFLite的BuildFromFile接口完成初始构图;
+ - 用户设置自定义的参数options,应用于创建NnrtDelegate;
+ - 用户创建DelegateProviders,并调用DelegateProviders的CreateAllRankedDelegates接口创建NnrtDelegate,创建NnrtDelegate过程中dlopen打开NNRt的动态库,并加载API,返回delegate;
+ - 用户调用ModifyGraphWithDelegate接口完成Node替换,其中该步分四个步骤;
+ - Initalize初始化NnrtDelegate;
+ - 判断图中各node是否支持NnrtDelegate,返回支持的node集合;
+ - 调用TFLiteRegistration注册NnrtDelegate,并初始化init, prepare, invoke成员函数指针,指向delegateKernel的Init, Prepare和run函数方法;
+ - 替换TensorFlow Delegate的node为已注册的NNrt delegate kernel, 并调用Init完成构图步骤;
+ - 用户调用AllocateTensors,完成内存分配和图编译,其中支持delegate的node会转到delegateKernel的prepare完成编译,不支持delegate的会调用原有tflite node的prepare编译;
+ - 用户调用Invoke完成图执行;
+
+### 开发流程
+
+
+### 开发步骤
+本节主要描述NNRt接入TFLite的TFLite-delegate代理机制,重点对TFLite调用delegate的流程和delegate对接NNRt的方式进行了介绍。
+TensorFlow Lite Delegate有两个基类DelegateProvider、TfLiteDelegate, 本节主要描述继承这两个基类得到子类NnrtDelegate和NnrtDelegateProvider。
+
+本demo主要文件目录结构如下图:
+```text
+.
+├── CMakeLists.txt
+├── delegates
+│ └── nnrt_delegate
+│ ├── CMakeLists.txt
+│ ├── nnrt_delegate.cpp
+│ ├── nnrt_delegate.h
+│ ├── nnrt_delegate_kernel.cpp
+│ ├── nnrt_delegate_kernel.h
+│ ├── nnrt_delegate_provider.cpp
+│ ├── nnrt_op_builder.cpp
+│ ├── nnrt_op_builder.h
+│ ├── nnrt_utils.cpp
+│ ├── nnrt_utils.h
+│ └── tensor_mapping.h
+├── label_classify
+│ ├── CMakeLists.txt
+│ ├── label_classify.cpp
+│ └── label_classify.h
+├── nnrt
+│ ├── CMakeLists.txt
+│ ├── nnrt_implementation.cpp
+│ └── nnrt_implementation.h
+└── tools
+ ├── bitmap_helpers.cpp
+ ├── bitmap_helpers.h
+ ├── get_topn.h
+ ├── log.h
+ ├── utils.cpp
+ └── utils.h
+```
+1. 创建Tensorflow Lite NnrtDelegate类
+ - Tensorflow Lite NNRt Delegate 使TensorFlow Lite模型能够运行在NNRt框架(https://gitee.com/openharmony/neural_network_runtime)上,这导致了在OHOS设备上更快的模型推理
+ - nnrt_delegate依赖nnrt_delegate_kernel, nnrt_delegate_kernel(将支持替换的TensorFlow Lite模型中的operators替换成Nnrt中的operators)依赖nnrt_op_builder(给每个operators设置输入输出tensor和operation属性),完成nnrt_delegate的自定义。
+
+
+2. 创建NnrtDelegateProvider
+ - NnrtDelegateProvider依赖nnrt_implementation(用于加载libneural_network_runtime.z.so中的Api)和nnrt_delegate(用于创建子类NnrtDelegate对象),完成与TFLite的对接;
+
+ - 注册NnrtDelegateProvider
+ ```cpp
+ REGISTER_DELEGATE_PROVIDER(NnrtDelegateProvider);
+ ```
+
+ - 创建CreateTfLiteDelegate主要有以下几步
+ ```cpp
+ NnrtDelegate::Options options;
+
+ const auto* nnrtImpl = NnrtImplementation();
+ if (!nnrtImpl->nnrtExists) {
+ TFLITE_LOG(WARN) << "NNRT acceleration is unsupported on this platform.";
+ return delegate;
+ }
+
+ Interpreter::TfLiteDelegatePtr TfLiteDelegatePtr(new (std::nothrow) NnrtDelegate(nnrtImpl, options),
+ [](TfLiteDelegate* delegate) { delete reinterpret_cast(delegate); });
+ ```
+
+3. label_classify.cpp中加载Nnrt_Delegate
+ ```cpp
+ interpreter->ModifyGraphWithDelegate(std::move(delegate.delegate))
+ ```
+
+### 调测命令
+1. 编译生成Tensorflow Lite库及其依赖库
+ 请参考Tensorflow Lite交叉编译指南(https://www.tensorflow.org/lite/guide/build_cmake_arm), 同时在```tensorflow/lite/CMakeLists.txt```中增加以下内容:
+ ```text
+ # TODO: TFLite External Delegate
+ list(APPEND TFLITE_EXTERNAL_DELEGATE_SRC
+ ${TFLITE_SOURCE_DIR}/tools/delegates/delegate_provider.cc
+ # ${TFLITE_SOURCE_DIR}/tools/delegates/external_delegate_provider.cc
+ ${TFLITE_SOURCE_DIR}/tools/tool_params.cc
+ ${TFLITE_SOURCE_DIR}/tools/command_line_flags.cc
+ )
+ ```
+ ```text
+ target_link_libraries(tensorflow-lite
+ PUBLIC
+ Eigen3::Eigen
+ NEON_2_SSE
+ absl::flags
+ absl::hash
+ absl::status
+ absl::strings
+ absl::synchronization
+ absl::variant
+ farmhash
+ fft2d_fftsg2d
+ flatbuffers
+ gemmlowp
+ ruy
+ ${CMAKE_DL_LIBS}
+ ${TFLITE_TARGET_DEPENDENCIES}
+ )
+ ```
+2. 编译生成NNRt库libneural_network_runtime.z.so
+ 请参考编译指导(https://gitee.com/openharmony/build),编译命令如下
+ ```shell
+ ./build.sh --product-name rk3568 –ccache --jobs=16 --build-target=neural_network_runtime
+ ```
+3. 用cmake编译北向demo
+ - 将TensorFlow Lite头文件(https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite)和编译生成的TensorFlow Lite库,分别放在```deep_learning_framework/lib_3rd_nnrt_tflite/include/tensorflow/lite/```和```deep_learning_framework/lib_3rd_nnrt_tflite/com/arm64-v8a/lib/```下;
+ - 指定ohos的cmake, ohos.toolchain.cmake路径,在```foundation/ai/neural_network_runtime/example/cmake_build/build_ohos_tflite.sh```中替换以下两行;
+ ```shell
+ ./tool_chain/native/build-tools/cmake/bin/cmake \
+ -DCMAKE_TOOLCHAIN_FILE=./tool_chain/native/cmake_build/cmake/ohos.toolchain.cmake \
+ ```
+ - 进入```foundation/ai/neural_network_runtime/example/cmake_build```:
+ - 如果需要在arm32架构的CPU上运行:
+ - 修改```tflite/CMakeLists.txt```
+ ```text
+ set(CMAKE_CXX_FLAGS "-pthread -fstack-protector-all -fPIC -D_FORTIFY_SOURCE=2 -march=armv7-a")
+ ```
+ - 执行编译命令
+ ```shell
+ bash build_ohos_tflite.sh armeabi-v7a
+ ```
+ - 如果需要在arm64架构的CPU上运行:
+ - 修改```tflite/CMakeLists.txt```
+ ```text
+ set(CMAKE_CXX_FLAGS "-pthread -fstack-protector-all -fPIC -D_FORTIFY_SOURCE=2 -march=armv8-a")
+ ```
+ - 执行编译命令
+ ```shell
+ bash build_ohos_tflite.sh arm64-v8a
+ ```
+ - 在```example/deep_learning_framework/```目录下创建lib和output两个文件夹:
+ ```shell
+ mkdir lib output
+ ```
+ - 进入```foundation/ai/neural_network_runtime/example/cmake_build```, 执行链接命令:
+ ```shell
+ make
+ ```
+ - 北向demo成功编译完成后会在```deep_learning_framework/lib```生成libnnrt_delegate.so和libnnrt_implementation.so, 在```deep_learning_framework/output```下生成label_classify可执行文件,目录结构体如下所示。
+
+ ```text
+ deep_learning_framework
+ ├── lib
+ │ ├── libnnrt_delegate.so # 生成的TensorFlow Lite nnrt delegate库
+ │ └── libnnrt_implementation.so # 生成的nnrt在TensorFlow Lite中接口实现库
+ └── output
+ └── label_classify # 生成的可执行文件
+ ```
+
+4. 在开发板上运行北向demo
+ - 将步骤1生成的libnnrt_implementation.so, libnnrt_delegate.so和可执行文件label_classify, libneural_network_runtime.z.so, tensorflow-lite.so及其依赖的库, mobilenetv2.tflite模型, 标签labels.txt, 测试图片grace_hopper.bmp推送到开发板上:
+ ```shell
+ # 假设上述待推送文件均放在push_files/文件夹下
+ hdc_std file send push_files/ /data/demo/
+ ```
+ - 进入开发板,执行demo前需要添加环境变量,文件执行权限等:
+ ```shell
+ # 进入开发板
+ hdc_std shell
+
+ # 进入推送文件目录,并增加可执行文件权限
+ cd /data/demo
+ chmod +x ./label_classify
+
+ # 添加环境变量
+ export LD_LIBRARY_PATH=/data/demo:$LD_LIBRARY_PATH
+
+ # 执行demo,-m tflite模型, -i 测试图片, -l 数据标签, -a 1表示使用nnrt, 0表示不使用nnrt推理,-z 1 表示打印输出张量大小的结果
+ ./label_classify -m mobilenetv2.tflite -i grace_hopper.bmp -l labels.txt -a 1 -z 1
+ ```
+
+### 开发实例
+完整[Demo实例](xxx, Demo暂时还在黄区代码仓,超链接需等Demo开源后补充)可以参考社区实现。
diff --git a/example/deep_learning_framework/cmake_build/build_ohos_tflite.sh b/example/deep_learning_framework/cmake_build/build_ohos_tflite.sh
new file mode 100644
index 0000000000000000000000000000000000000000..3dcc0ead0e81fcc6a85ef9eccae6630b7ea6f10d
--- /dev/null
+++ b/example/deep_learning_framework/cmake_build/build_ohos_tflite.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+#
+# Copyright (c) 2022 Huawei Device Co., Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+set -e
+
+function help_info() {
+ echo "arm64-v8a(armeabi-v7a) means the CPU architecture is 64-bit(32-bit), the compile command like the following:"
+ echo "bash build_ohos_tflite.sh arm64-v8a"
+}
+
+function build() {
+ echo "$1"
+ ./tool_chain/native/build-tools/cmake/bin/cmake \
+ -DCMAKE_TOOLCHAIN_FILE=./tool_chain/native/build/cmake/ohos.toolchain.cmake \
+ -DOHOS_ARCH=$1 \
+ -DOHOS_PLATFORM=OHOS \
+ -DCMAKE_BUILD_TYPE=RELEASE \
+ -DBUILD_SHARED_LIBS=true \
+ -DOHOS_STL=c++_static \
+ -DCMAKE_BUILD_TYPE=Debug \
+ ..
+}
+
+if [ "$#" != 1 ]; then
+ echo "Incorrect command, please pass the correct number of parameters to the compile command."
+ help_info
+ exit 1;
+fi
+
+if [ "$1" == "arm64-v8a" ]; then
+ build arm64-v8a
+elif [ "$1" == "armeabi-v7a" ]; then
+ build armeabi-v7a
+else
+ echo "Incorrect CPU architecture parameter or missing setting it, please pass the correct compile command."
+ help_info
+fi
+
diff --git a/example/deep_learning_framework/tflite/CMakeLists.txt b/example/deep_learning_framework/tflite/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e89cbbaa62c585053263341b70b2e4919e58bc5c
--- /dev/null
+++ b/example/deep_learning_framework/tflite/CMakeLists.txt
@@ -0,0 +1,25 @@
+#
+# Copyright (c) 2022 Huawei Device Co., Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+set(NNRT_INTERFACE_HOME ${LOCAL_DIRECTORY_PATH}/tflite/nnrt)
+set(NNRT_DELEGATE_HOME ${LOCAL_DIRECTORY_PATH}/tflite/delegates/nnrt_delegate)
+set(NNRT_DEMO_HOME ${LOCAL_DIRECTORY_PATH}/tflite/label_classify)
+set(TFLITE_LIB_PATH ${LOCAL_DIRECTORY_PATH}/lib_3rd_nnrt_tflite)
+
+add_subdirectory(${NNRT_INTERFACE_HOME})
+add_subdirectory(${NNRT_DELEGATE_HOME})
+add_subdirectory(${NNRT_DEMO_HOME})
+
+
diff --git a/example/deep_learning_framework/tflite/delegates/nnrt_delegate/CMakeLists.txt b/example/deep_learning_framework/tflite/delegates/nnrt_delegate/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ee5fa7f5f0972b3f4998bb186ff95486b725ab53
--- /dev/null
+++ b/example/deep_learning_framework/tflite/delegates/nnrt_delegate/CMakeLists.txt
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2022 Huawei Device Co., Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+set(TFLITE_PATH ${LOCAL_DIRECTORY_PATH}/lib_3rd_nnrt_tflite)
+
+LINK_DIRECTORIES(${TFLITE_PATH}/com/arm64-v8a/lib/)
+
+# Header path
+set(OHOS_INC ${LOCAL_DIRECTORY_PATH}/../../interfaces/kits/c)
+set(TOOLS_INC ${LOCAL_DIRECTORY_PATH}/tflite/tools)
+set(TFLITE_INC ${LOCAL_DIRECTORY_PATH}/lib_3rd_nnrt_tflite/include)
+include_directories(${LOCAL_DIRECTORY_PATH} ${NNRT_DELEGATE_HOME} ${TFLITE_INC} ${OHOS_INC} ${TOOLS_INC})
+
+# Scr path
+file(GLOB NNRT_DELEGATE_SRCS "${NNRT_DELEGATE_HOME}/*.cpp")
+
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LOCAL_DIRECTORY_PATH}/lib)
+
+add_library(nnrt_delegate SHARED ${NNRT_DELEGATE_SRCS})
+target_link_libraries(nnrt_delegate -ltensorflow-lite nnrt_implementation)
+
+
diff --git a/example/deep_learning_framework/tflite/delegates/nnrt_delegate/nnrt_delegate.cpp b/example/deep_learning_framework/tflite/delegates/nnrt_delegate/nnrt_delegate.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9528d7513740b759f75a429173305494adbff750
--- /dev/null
+++ b/example/deep_learning_framework/tflite/delegates/nnrt_delegate/nnrt_delegate.cpp
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "nnrt_delegate.h"
+
+#include "tensorflow/lite/util.h"
+#include "tensorflow/lite/context_util.h"
+#include "tensorflow/lite/minimal_logging.h"
+
+#include "nnrt_utils.h"
+#include "nnrt_delegate_kernel.h"
+
+namespace tflite {
+const char* g_tfliteNnrtDelegateName = "TfLiteNnrtDelegate";
+constexpr int32_t TFLITE_NNRT_DELEGATE_VERSION = 1;
+
+NnrtDelegate::Data::Data(const NnrtApi* nnrt) : nnrt(nnrt) {}
+
+NnrtDelegate::Data::~Data() {}
+
+void NnrtDelegate::NnrtDelegateConstructorImpl(const Options& options)
+{
+ m_delegateData.acceleratorName = options.acceleratorName;
+ m_delegateData.cacheDir = options.cacheDir;
+ m_delegateData.modelToken = options.modelToken;
+ m_delegateData.enableFp16 = options.enableFp16;
+ m_delegateData.executionPriority = options.executionPriority;
+ m_delegateData.executionPerformance = options.executionPerformance;
+ m_delegateData.allowDynamicDimensions = options.allowDynamicDimensions;
+ m_delegateData.maxNumberDelegatedPartitions = options.maxNumberDelegatedPartitions;
+ m_delegateData.maxCompilationTimeoutDurationNs = options.maxCompilationTimeoutDurationNs;
+ m_delegateData.maxExecutionTimeoutDurationNs = options.maxExecutionTimeoutDurationNs;
+ m_delegateData.maxExecutionLoopTimeoutDurationNs = options.maxExecutionLoopTimeoutDurationNs;
+
+ Prepare = DoPrepare;
+ CopyFromBufferHandle = DoCopyFromBufferHandle;
+ CopyToBufferHandle = DoCopyToBufferHandle;
+ FreeBufferHandle = DoFreeBufferHandle;
+ data_ = &m_delegateData;
+
+ // NNRT support dynamic shape feature.
+ flags |= kTfLiteDelegateFlagsAllowDynamicTensors;
+ flags |= kTfLiteDelegateFlagsRequirePropagatedShapes;
+}
+
+NnrtDelegate::NnrtDelegate(const NnrtApi* nnrt) : NnrtDelegate(nnrt, Options()) {}
+
+NnrtDelegate::NnrtDelegate(const Options& options) : NnrtDelegate(NnrtImplementation(), options) {}
+
+NnrtDelegate::NnrtDelegate(const NnrtApi* nnrt, const Options& options)
+ : TfLiteDelegate(TfLiteDelegateCreate()), m_delegateData(nnrt)
+{
+ NnrtDelegateConstructorImpl(options);
+}
+
+NnrtDelegate::NnrtDelegate() : NnrtDelegate(Options()) {}
+
+TfLiteStatus NnrtDelegate::GetOptions(const TfLiteDelegate* pDelegate, Options& options)
+{
+ // Caller guarantees that parameters are legal
+ auto pDelegateData = static_cast(pDelegate->data_);
+ options.acceleratorName = pDelegateData->acceleratorName;
+ options.cacheDir = pDelegateData->cacheDir;
+ options.modelToken = pDelegateData->modelToken;
+ options.enableFp16 = pDelegateData->enableFp16;
+ options.executionPriority = pDelegateData->executionPriority;
+ options.executionPerformance = pDelegateData->executionPerformance;
+ options.allowDynamicDimensions = pDelegateData->allowDynamicDimensions;
+ options.maxNumberDelegatedPartitions = pDelegateData->maxNumberDelegatedPartitions;
+ options.maxCompilationTimeoutDurationNs = pDelegateData->maxCompilationTimeoutDurationNs;
+ options.maxExecutionTimeoutDurationNs = pDelegateData->maxExecutionTimeoutDurationNs;
+ options.maxExecutionLoopTimeoutDurationNs = pDelegateData->maxExecutionLoopTimeoutDurationNs;
+ options.version = pDelegateData->version;
+
+ return kTfLiteOk;
+}
+
+TfLiteStatus NnrtDelegate::DoCopyFromBufferHandle(TfLiteContext* context,
+ TfLiteDelegate* delegate, TfLiteBufferHandle bufferHandle, TfLiteTensor* tensor)
+{
+ return kTfLiteError;
+}
+
+TfLiteStatus NnrtDelegate::DoCopyToBufferHandle(TfLiteContext* context,
+ TfLiteDelegate* delegate, TfLiteBufferHandle bufferHandle, TfLiteTensor* tensor)
+{
+ return kTfLiteError;
+}
+
+void NnrtDelegate::DoFreeBufferHandle(TfLiteContext* context,
+ TfLiteDelegate* delegate, TfLiteBufferHandle* handle)
+{
+ return;
+}
+
+TfLiteStatus NnrtDelegate::LimitDelegatedPartitions(int32_t maxPartitions,
+ std::vector partitionParamsArray, std::vector& nodesToDelegate)
+{
+ int32_t numPartitions = partitionParamsArray.size();
+ if ((maxPartitions <= 0) || (numPartitions <= maxPartitions)) { // no limit or not exceed limit
+ return kTfLiteOk;
+ }
+
+ int32_t numberDelegatedPartitions = std::count_if(
+ partitionParamsArray.begin(), partitionParamsArray.end(),
+ [nodesToDelegate](const TfLiteDelegateParams& partitionParams) {
+ return std::find(nodesToDelegate.begin(), nodesToDelegate.end(),
+ partitionParams.nodes_to_replace->data[0]) != nodesToDelegate.end();
+ });
+ // Adapt maxPartitions to limit delegate paritions, sort and abandon the low-ranking nodes.
+ if (numberDelegatedPartitions > maxPartitions) {
+ std::sort(partitionParamsArray.begin(), partitionParamsArray.end(),
+ [](const TfLiteDelegateParams& left, const TfLiteDelegateParams& right) -> bool {
+ return left.nodes_to_replace->size > right.nodes_to_replace->size;
+ });
+
+ nodesToDelegate.clear();
+
+ for (int32_t i = 0; i < maxPartitions; ++i) {
+ const TfLiteDelegateParams& partitionParams = partitionParamsArray[i];
+ nodesToDelegate.insert(nodesToDelegate.end(),
+ partitionParams.nodes_to_replace->data,
+ partitionParams.nodes_to_replace->data +
+ partitionParams.nodes_to_replace->size);
+ }
+ }
+
+ return kTfLiteOk;
+}
+
+TfLiteStatus NnrtDelegate::GetSupportedNodes(TfLiteContext* context,
+ TfLiteDelegate* delegate, std::vector& supportedNodes)
+{
+ // Caller guarantees that parameters are legal
+ TfLiteIntArray* executionPlan = nullptr;
+ TF_LITE_ENSURE_STATUS(context->GetExecutionPlan(context, &executionPlan));
+ TF_LITE_ENSURE_EQ(context, executionPlan != nullptr, true);
+
+ // Check for every node if it is supported
+ TfLiteNode* node = nullptr;
+ TfLiteRegistration* registration = nullptr;
+ for (auto nodeIndex : TfLiteIntArrayView(executionPlan)) {
+ node = nullptr;
+ registration = nullptr;
+ TF_LITE_ENSURE_STATUS(context->GetNodeAndRegistration(context, nodeIndex, &node, ®istration));
+ if (NnrtDelegateKernel::Validate(registration->builtin_code)) {
+ supportedNodes.emplace_back(nodeIndex);
+ } else {
+ TFLITE_LOG_PROD(TFLITE_LOG_WARNING,
+ "[NNRT-DELEGATE] Get unsupportted node: %d.", registration->builtin_code);
+ }
+ }
+
+ return kTfLiteOk;
+}
+
+void NnrtDelegate::GetDelegateKernelRegistration(TfLiteDelegate* delegate, TfLiteRegistration& nnrtDelegateKernel)
+{
+ // Caller guarantees that parameters are legal
+ nnrtDelegateKernel.profiling_string = nullptr;
+ nnrtDelegateKernel.builtin_code = kTfLiteBuiltinDelegate;
+ nnrtDelegateKernel.custom_name = g_tfliteNnrtDelegateName;
+ nnrtDelegateKernel.version = TFLITE_NNRT_DELEGATE_VERSION;
+
+ nnrtDelegateKernel.init = [](TfLiteContext* context, const char* buffer, size_t length) -> void* {
+ if (buffer == nullptr) {
+ return nullptr;
+ }
+
+ const TfLiteDelegateParams* params = reinterpret_cast(buffer);
+ auto* delegateData = static_cast(params->delegate->data_);
+ NnrtDelegateKernel* state = new (std::nothrow) NnrtDelegateKernel(delegateData->nnrt);
+ if (state == nullptr) {
+ TFLITE_LOG_PROD(TFLITE_LOG_ERROR, "Failed to create NnrtDelegateKernel instance.");
+ return state;
+ }
+
+ TfLiteStatus status = state->Init(context, params);
+ if (status != kTfLiteOk) {
+ TFLITE_LOG_PROD(TFLITE_LOG_ERROR, "Failed to init NnrtDelegateKernel.");
+ delete state;
+ state = nullptr;
+ }
+ return state;
+ };
+
+ nnrtDelegateKernel.free = [](TfLiteContext* context, void* buffer) -> void {
+ if (buffer != nullptr) {
+ delete static_cast(buffer);
+ buffer = nullptr;
+ }
+ };
+
+ nnrtDelegateKernel.prepare = [](TfLiteContext* context, TfLiteNode* node) -> TfLiteStatus {
+ if (node == nullptr) {
+ TFLITE_LOG_PROD(TFLITE_LOG_ERROR, "Failed to prepare delegate kernels, the node is nullptr.");
+ return kTfLiteError;
+ }
+
+ NnrtDelegateKernel* state = reinterpret_cast(node->user_data);
+ return state->Prepare(context, node);
+ };
+
+ nnrtDelegateKernel.invoke = [](TfLiteContext* context, TfLiteNode* node) -> TfLiteStatus {
+ if (node == nullptr) {
+ TFLITE_LOG_PROD(TFLITE_LOG_ERROR, "Failed to invoke delegate kernels, the node is nullptr.");
+ return kTfLiteError;
+ }
+
+ NnrtDelegateKernel* state = reinterpret_cast(node->user_data);
+ return state->Invoke(context, node);
+ };
+}
+
+TfLiteStatus NnrtDelegate::CheckDeviceValid(TfLiteContext* context, TfLiteDelegate* delegate)
+{
+ // Caller guarantees that parameters are legal
+ auto* delegateData = static_cast(delegate->data_);
+ if (delegateData == nullptr) {
+ TFLITE_LOG_PROD(TFLITE_LOG_ERROR, "Delegate data not be found.");
+ return kTfLiteDelegateDataNotFound;
+ }
+
+ const NnrtApi* nnrt = delegateData->nnrt;
+ if (nnrt == nullptr) {
+ TFLITE_LOG_PROD(TFLITE_LOG_ERROR, "Failed to get nnrt instance.");
+ return kTfLiteError;
+ }
+
+ NnrtDelegate::Options delegateOptions;
+ TF_LITE_ENSURE_STATUS(NnrtDelegate::GetOptions(delegate, delegateOptions));
+
+ if (tflite::IsUseTargetDevice(delegateOptions)) {
+ size_t nnrtDevice;
+ TF_LITE_ENSURE_STATUS(GetTargetDevice(context, delegate, nnrt, nnrtDevice));
+ }
+
+ return kTfLiteOk;
+}
+
+TfLiteStatus NnrtDelegate::DoPrepare(TfLiteContext* context, TfLiteDelegate* delegate)
+{
+ if ((context == nullptr) || (delegate == nullptr)) {
+ TFLITE_LOG_PROD(TFLITE_LOG_ERROR, "[NNRT-DELEGATE] Input TFLite-Context or TFLite-Delegate is nullptr.");
+ return kTfLiteError;
+ }
+
+ auto* delegateData = static_cast(delegate->data_);
+ const NnrtApi* nnrt = delegateData->nnrt;
+
+ // Do not delegate nodes_ if NN API is unavailable.
+ if (!nnrt->nnrtExists) {
+ return kTfLiteOk;
+ }
+
+ // Check devices validity
+ TF_LITE_ENSURE_STATUS(CheckDeviceValid(context, delegate));
+
+ // Get supportted nodes by tflite.
+ // We don't care about all nodes_, we only care about ones in the current plan.
+ std::vector supportedNodes;
+ GetSupportedNodes(context, delegate, supportedNodes);
+
+ // If there are no delegated nodes, short-circuit node replacement.
+ if (supportedNodes.empty()) {
+ TFLITE_LOG_PROD(TFLITE_LOG_INFO, "[NNRT-DELEGATE] supportted node list is empty.");
+ return kTfLiteOk;
+ }
+
+ static TfLiteRegistration nnrtDelegateKernel;
+ GetDelegateKernelRegistration(delegate, nnrtDelegateKernel);
+
+ std::vector nodesToDelegate(supportedNodes);
+ int32_t numPartitions;
+ TfLiteDelegateParams* paramsArray = nullptr;
+ auto supportedNodesArray = BuildTfLiteIntArray(supportedNodes);
+ TF_LITE_ENSURE_STATUS(context->PreviewDelegatePartitioning(
+ context, supportedNodesArray.get(), ¶msArray, &numPartitions));
+
+ NnrtDelegate::Options delegateOptions;
+ TF_LITE_ENSURE_STATUS(NnrtDelegate::GetOptions(delegate, delegateOptions));
+ const auto partitionParamsArray = std::vector(paramsArray, paramsArray + numPartitions);
+ TF_LITE_ENSURE_STATUS(LimitDelegatedPartitions(
+ delegateOptions.maxNumberDelegatedPartitions, partitionParamsArray, nodesToDelegate));
+
+ auto nodesToDelegateArray = BuildTfLiteIntArray(nodesToDelegate);
+ if (nodesToDelegateArray->size == 0) {
+ TFLITE_LOG_PROD(TFLITE_LOG_INFO, "[NNRT-DELEGATE] No node to delegate.");
+ return kTfLiteOk;
+ } else {
+ // Request TFLite to partition the graph and make kernels
+ // for each independent node sub set a new nnrtDelegateKernel.
+ return context->ReplaceNodeSubsetsWithDelegateKernels(context,
+ nnrtDelegateKernel, nodesToDelegateArray.get(), delegate);
+ }
+}
+
+// Return a singleton NNRT Delegate that can check ops supported.
+TfLiteDelegate* NnrtDelegateSingleton()
+{
+ static NnrtDelegate delegate;
+ return &delegate;
+}
+} // namespace tflite
\ No newline at end of file
diff --git a/example/deep_learning_framework/tflite/delegates/nnrt_delegate/nnrt_delegate.h b/example/deep_learning_framework/tflite/delegates/nnrt_delegate/nnrt_delegate.h
new file mode 100644
index 0000000000000000000000000000000000000000..681e0699d5d53ff8781538de7ce9cf03525dba2f
--- /dev/null
+++ b/example/deep_learning_framework/tflite/delegates/nnrt_delegate/nnrt_delegate.h
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TENSORFLOW_LITE_DELEGATES_NNRT_DELEGATE_H
+#define TENSORFLOW_LITE_DELEGATES_NNRT_DELEGATE_H
+
+#include
+#include
+
+#include "neural_network_runtime.h"
+
+#include "tensorflow/lite/c/common.h"
+#include "tensorflow/lite/delegates/serialization.h"
+
+#include "../nnrt/nnrt_implementation.h"
+
+namespace tflite {
+namespace delegate {
+namespace nnrt {
+class NnrtDelegateKernel;
+} // namespace nnrt
+} // namespace delegate
+
+using tflite::delegate::nnrt::NnrtDelegateKernel;
+
+// TFliteDelegate to interface with NNRT.
+class NnrtDelegate : public TfLiteDelegate {
+public:
+ struct Options {
+ OH_NN_PerformanceMode executionPerformance = OH_NN_PERFORMANCE_NONE;
+ std::string acceleratorName;
+ std::string cacheDir;
+ std::string modelToken;
+ OH_NN_Priority executionPriority = OH_NN_PRIORITY_MEDIUM;
+ int32_t maxNumberDelegatedPartitions = -1;
+ uint64_t maxCompilationTimeoutDurationNs = 0;
+ uint64_t maxExecutionTimeoutDurationNs = 0;
+ uint64_t maxExecutionLoopTimeoutDurationNs = 0;
+ // allow fp32 compuation to be run in fp16.
+ bool enableFp16 = false;
+ bool allowDynamicDimensions = false;
+
+ uint32_t version {0};
+ };
+
+ // Uses default options.
+ NnrtDelegate();
+
+ // The ownership of the NNRT instance is left to the caller of the
+ // NnrtDelegate constructor; the caller must ensure that the lifetime
+ // of the NNRT instance exceeds the lifetime of the NnrtDelegate.
+ explicit NnrtDelegate(const NnrtApi* nnrt);
+
+ // The constructor that accepts options from user.
+ // This makes a copy of any data that it needs from Options, so
+ // the caller can safely deallocate any storage pointed to by
+ // the 'const char *' members of Options immediately after calling this.
+ explicit NnrtDelegate(const Options& options);
+
+ // Constructor that accepts both an NNRT instance and options.
+ // The ownership of the NNRT instance is left to the caller of the
+ // NnrtDelegate constructor; the caller must ensure that the lifetime
+ // of the NNRT instance exceeds the lifetime of the NnrtDelegate.
+ // This constructor makes a copy of any data that it needs from Options, so
+ // the caller can safely deallocate any storage pointed to by
+ // the 'const char *' members of Options immediately after calling this.
+ NnrtDelegate(const NnrtApi* nnrt, const Options& options);
+
+ ~NnrtDelegate() = default;
+
+ // Returns the delegate options.
+ // The lifetime of the storage pointed to by the 'const char *' members of the
+ // returned Options object is the same as the lifetime of the supplied
+ // TfLiteDelegate instance.
+ static TfLiteStatus GetOptions(const TfLiteDelegate* pDelegate, Options& options);
+
+private:
+ struct Data {
+ const NnrtApi* nnrt = nullptr;
+
+ // Preferred Power/perf trade-off.
+ OH_NN_PerformanceMode executionPerformance = OH_NN_PERFORMANCE_NONE;
+
+ // Selected NNRT accelerator name.
+ std::string acceleratorName;
+
+ // The cache dir for NNRT model.
+ std::string cacheDir;
+
+ // The unique token string for NNRT model.
+ std::string modelToken;
+
+ // Maximum number of NNRT partition to delegate. Zero or negative means
+ // no limit.
+ int32_t maxNumberDelegatedPartitions = -1;
+
+ // Specifies the relative priority for executions of the model.
+ OH_NN_Priority executionPriority = OH_NN_PRIORITY_MEDIUM;
+
+ // Specifies the maximum expected duration in nanosecond for compiling the
+ // model.
+ uint64_t maxCompilationTimeoutDurationNs = 0;
+
+ // Specifies the maximum expected duration in nanosecond for executing the
+ // model.
+ uint64_t maxExecutionTimeoutDurationNs = 0;
+
+ // Specifies the maximum expected duration in nanosecond for WHILE loops in
+ // the execution
+ uint64_t maxExecutionLoopTimeoutDurationNs = 0;
+
+ // allow fp32 compuation to be run in fp16.
+ bool enableFp16 = false;
+
+ // Whether to allow dynamic dimension sizes without re-compilation.
+ bool allowDynamicDimensions = false;
+
+ uint32_t version {0};
+
+ explicit Data(const NnrtApi* nnrt);
+ ~Data();
+ };
+
+ static TfLiteStatus DoPrepare(TfLiteContext* context, TfLiteDelegate* delegate);
+
+ static TfLiteStatus DoCopyFromBufferHandle(TfLiteContext* context,
+ TfLiteDelegate* delegate, TfLiteBufferHandle bufferHandle, TfLiteTensor* tensor);
+
+ static TfLiteStatus DoCopyToBufferHandle(TfLiteContext* context,
+ TfLiteDelegate* delegate, TfLiteBufferHandle bufferHandle, TfLiteTensor* tensor);
+
+ static void DoFreeBufferHandle(TfLiteContext* context,
+ TfLiteDelegate* delegate, TfLiteBufferHandle* handle);
+
+ static TfLiteStatus LimitDelegatedPartitions(int32_t maxPartitions,
+ std::vector partitionParamsArray, std::vector& nodesToDelegate);
+
+ static TfLiteStatus GetSupportedNodes(TfLiteContext* context,
+ TfLiteDelegate* delegate, std::vector& supportedNodes);
+
+ static void GetDelegateKernelRegistration(TfLiteDelegate* delegate, TfLiteRegistration& nnrtDelegateKernel);
+
+ static TfLiteStatus CheckDeviceValid(TfLiteContext* context, TfLiteDelegate* delegate);
+
+ void NnrtDelegateConstructorImpl(const Options& options);
+
+private:
+ // Delegate data presented through TfLiteDelegate::data_.
+ Data m_delegateData;
+};
+
+TfLiteDelegate* NnrtDelegateSingleton();
+} // namespace tflite
+
+#endif // TENSORFLOW_LITE_DELEGATES_NNRT_DELEGATE_H
diff --git a/example/deep_learning_framework/tflite/delegates/nnrt_delegate/nnrt_delegate_kernel.cpp b/example/deep_learning_framework/tflite/delegates/nnrt_delegate/nnrt_delegate_kernel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..05933aeea2daba081ed6a9af0266a3967d32abc3
--- /dev/null
+++ b/example/deep_learning_framework/tflite/delegates/nnrt_delegate/nnrt_delegate_kernel.cpp
@@ -0,0 +1,420 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "nnrt_delegate_kernel.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include