1be168c0dSopenharmony_ciFrom 3793994296c2ede3f79544d613acd8f6600ec9fb Mon Sep 17 00:00:00 2001
2be168c0dSopenharmony_ciFrom: chengfeng27 <chengfeng27@huawei.com>
3be168c0dSopenharmony_ciDate: Fri, 7 Jun 2024 15:31:09 +0800
4be168c0dSopenharmony_ciSubject: fix lite_graph dequant crash
5be168c0dSopenharmony_ci
6be168c0dSopenharmony_ci---
7be168c0dSopenharmony_ci .../delegate/nnrt/checker/primitive_check.cc  | 115 -----------
8be168c0dSopenharmony_ci .../delegate/nnrt/checker/primitive_check.h   |   1 -
9be168c0dSopenharmony_ci .../litert/delegate/nnrt/nnrt_allocator.cc    |  64 +++---
10be168c0dSopenharmony_ci .../src/litert/delegate/nnrt/nnrt_allocator.h |  20 +-
11be168c0dSopenharmony_ci .../src/litert/delegate/nnrt/nnrt_delegate.cc |  32 +--
12be168c0dSopenharmony_ci .../src/litert/delegate/nnrt/nnrt_delegate.h  |   1 +
13be168c0dSopenharmony_ci .../litert/delegate/nnrt/nnrt_model_kernel.cc | 190 ++++++++++--------
14be168c0dSopenharmony_ci .../litert/delegate/nnrt/nnrt_model_kernel.h  |  17 +-
15be168c0dSopenharmony_ci mindspore/lite/src/tensor.h                   |   2 +
16be168c0dSopenharmony_ci 9 files changed, 186 insertions(+), 256 deletions(-)
17be168c0dSopenharmony_ci
18be168c0dSopenharmony_cidiff --git a/mindspore/lite/src/litert/delegate/nnrt/checker/primitive_check.cc b/mindspore/lite/src/litert/delegate/nnrt/checker/primitive_check.cc
19be168c0dSopenharmony_ciindex 6b191c8e..67d60f1b 100644
20be168c0dSopenharmony_ci--- a/mindspore/lite/src/litert/delegate/nnrt/checker/primitive_check.cc
21be168c0dSopenharmony_ci+++ b/mindspore/lite/src/litert/delegate/nnrt/checker/primitive_check.cc
22be168c0dSopenharmony_ci@@ -7,121 +7,6 @@
23be168c0dSopenharmony_ci #include "src/common/utils.h"
24be168c0dSopenharmony_ci namespace mindspore {
25be168c0dSopenharmony_ci namespace lite {
26be168c0dSopenharmony_ci-
27be168c0dSopenharmony_ci-Status CheckPrimitiveSupported(const schema::Primitive *primitive) {
28be168c0dSopenharmony_ci-  if (primitive != nullptr) {
29be168c0dSopenharmony_ci-    auto prim = primitive;
30be168c0dSopenharmony_ci-    auto type = prim->value_type();
31be168c0dSopenharmony_ci-    switch (type) {
32be168c0dSopenharmony_ci-      case schema::PrimitiveType_Activation:
33be168c0dSopenharmony_ci-        return mindspore::kSuccess;
34be168c0dSopenharmony_ci-      case schema::PrimitiveType_AddFusion:
35be168c0dSopenharmony_ci-        return mindspore::kSuccess;
36be168c0dSopenharmony_ci-      case schema::PrimitiveType_ArgMaxFusion:
37be168c0dSopenharmony_ci-        return mindspore::kSuccess;
38be168c0dSopenharmony_ci-      case schema::PrimitiveType_AvgPoolFusion:
39be168c0dSopenharmony_ci-        return mindspore::kSuccess;
40be168c0dSopenharmony_ci-      case schema::PrimitiveType_BatchToSpaceND:
41be168c0dSopenharmony_ci-        return mindspore::kSuccess;
42be168c0dSopenharmony_ci-      case schema::PrimitiveType_BiasAdd:
43be168c0dSopenharmony_ci-        return mindspore::kSuccess;
44be168c0dSopenharmony_ci-      case schema::PrimitiveType_Cast:
45be168c0dSopenharmony_ci-        return mindspore::kSuccess;
46be168c0dSopenharmony_ci-      case schema::PrimitiveType_Concat:
47be168c0dSopenharmony_ci-        return mindspore::kSuccess;
48be168c0dSopenharmony_ci-      case schema::PrimitiveType_Conv2DFusion:
49be168c0dSopenharmony_ci-        return mindspore::kSuccess;
50be168c0dSopenharmony_ci-      case schema::PrimitiveType_Conv2dTransposeFusion:
51be168c0dSopenharmony_ci-        return mindspore::kSuccess;
52be168c0dSopenharmony_ci-      case schema::PrimitiveType_DivFusion:
53be168c0dSopenharmony_ci-        return mindspore::kSuccess;
54be168c0dSopenharmony_ci-      case schema::PrimitiveType_Eltwise:
55be168c0dSopenharmony_ci-        return mindspore::kSuccess;
56be168c0dSopenharmony_ci-      case schema::PrimitiveType_ExpandDims:
57be168c0dSopenharmony_ci-        return mindspore::kSuccess;
58be168c0dSopenharmony_ci-      case schema::PrimitiveType_Fill:
59be168c0dSopenharmony_ci-        return mindspore::kSuccess;
60be168c0dSopenharmony_ci-      case schema::PrimitiveType_FullConnection:
61be168c0dSopenharmony_ci-        return mindspore::kSuccess;
62be168c0dSopenharmony_ci-      case schema::PrimitiveType_FusedBatchNorm:
63be168c0dSopenharmony_ci-        return mindspore::kSuccess;
64be168c0dSopenharmony_ci-      case schema::PrimitiveType_Gather:
65be168c0dSopenharmony_ci-        return mindspore::kSuccess;
66be168c0dSopenharmony_ci-      case schema::PrimitiveType_LayerNormFusion:
67be168c0dSopenharmony_ci-        return mindspore::kSuccess;
68be168c0dSopenharmony_ci-      case schema::PrimitiveType_LessEqual:
69be168c0dSopenharmony_ci-        return mindspore::kSuccess;
70be168c0dSopenharmony_ci-      case schema::PrimitiveType_MatMulFusion:
71be168c0dSopenharmony_ci-        return mindspore::kSuccess;
72be168c0dSopenharmony_ci-      case schema::PrimitiveType_Maximum:
73be168c0dSopenharmony_ci-        return mindspore::kSuccess;
74be168c0dSopenharmony_ci-      case schema::PrimitiveType_MaxPoolFusion:
75be168c0dSopenharmony_ci-        return mindspore::kSuccess;
76be168c0dSopenharmony_ci-      case schema::PrimitiveType_MulFusion:
77be168c0dSopenharmony_ci-        return mindspore::kSuccess;
78be168c0dSopenharmony_ci-      case schema::PrimitiveType_OneHot:
79be168c0dSopenharmony_ci-        return mindspore::kSuccess;
80be168c0dSopenharmony_ci-      case schema::PrimitiveType_PadFusion:
81be168c0dSopenharmony_ci-        return mindspore::kSuccess;
82be168c0dSopenharmony_ci-      case schema::PrimitiveType_PowFusion:
83be168c0dSopenharmony_ci-        return mindspore::kSuccess;
84be168c0dSopenharmony_ci-      case schema::PrimitiveType_PReLUFusion:
85be168c0dSopenharmony_ci-        return mindspore::kSuccess;
86be168c0dSopenharmony_ci-      case schema::PrimitiveType_QuantDTypeCast:
87be168c0dSopenharmony_ci-        return mindspore::kSuccess;
88be168c0dSopenharmony_ci-      case schema::PrimitiveType_ReduceFusion:
89be168c0dSopenharmony_ci-        return mindspore::kSuccess;
90be168c0dSopenharmony_ci-      case schema::PrimitiveType_Reshape:
91be168c0dSopenharmony_ci-        return mindspore::kSuccess;
92be168c0dSopenharmony_ci-      case schema::PrimitiveType_Resize:
93be168c0dSopenharmony_ci-        return mindspore::kSuccess;
94be168c0dSopenharmony_ci-      case schema::PrimitiveType_Rsqrt:
95be168c0dSopenharmony_ci-        return mindspore::kSuccess;
96be168c0dSopenharmony_ci-      case schema::PrimitiveType_ScaleFusion:
97be168c0dSopenharmony_ci-        return mindspore::kSuccess;
98be168c0dSopenharmony_ci-      case schema::PrimitiveType_Shape:
99be168c0dSopenharmony_ci-        return mindspore::kSuccess;
100be168c0dSopenharmony_ci-      case schema::PrimitiveType_SliceFusion:
101be168c0dSopenharmony_ci-        return mindspore::kSuccess;
102be168c0dSopenharmony_ci-      case schema::PrimitiveType_Softmax:
103be168c0dSopenharmony_ci-        return mindspore::kSuccess;
104be168c0dSopenharmony_ci-      case schema::PrimitiveType_SpaceToBatchND:
105be168c0dSopenharmony_ci-        return mindspore::kSuccess;
106be168c0dSopenharmony_ci-      case schema::PrimitiveType_Split:
107be168c0dSopenharmony_ci-        return mindspore::kSuccess;
108be168c0dSopenharmony_ci-      case schema::PrimitiveType_Sqrt:
109be168c0dSopenharmony_ci-        return mindspore::kSuccess;
110be168c0dSopenharmony_ci-      case schema::PrimitiveType_SquaredDifference:
111be168c0dSopenharmony_ci-        return mindspore::kSuccess;
112be168c0dSopenharmony_ci-      case schema::PrimitiveType_Squeeze:
113be168c0dSopenharmony_ci-        return mindspore::kSuccess;
114be168c0dSopenharmony_ci-      case schema::PrimitiveType_Stack:
115be168c0dSopenharmony_ci-        return mindspore::kSuccess;
116be168c0dSopenharmony_ci-      case schema::PrimitiveType_StridedSlice:
117be168c0dSopenharmony_ci-        return mindspore::kSuccess;
118be168c0dSopenharmony_ci-      case schema::PrimitiveType_SubFusion:
119be168c0dSopenharmony_ci-        return mindspore::kSuccess;
120be168c0dSopenharmony_ci-      case schema::PrimitiveType_TileFusion:
121be168c0dSopenharmony_ci-        return mindspore::kSuccess;
122be168c0dSopenharmony_ci-      case schema::PrimitiveType_TopKFusion:
123be168c0dSopenharmony_ci-        return mindspore::kSuccess;
124be168c0dSopenharmony_ci-      case schema::PrimitiveType_Transpose:
125be168c0dSopenharmony_ci-        return mindspore::kSuccess;
126be168c0dSopenharmony_ci-      case schema::PrimitiveType_Unsqueeze:
127be168c0dSopenharmony_ci-        return mindspore::kSuccess;
128be168c0dSopenharmony_ci-      case schema::PrimitiveType_Custom:
129be168c0dSopenharmony_ci-        return mindspore::kSuccess;
130be168c0dSopenharmony_ci-      default: {
131be168c0dSopenharmony_ci-        MS_LOG(WARNING) << "No primitive type :" << (int)(type);
132be168c0dSopenharmony_ci-        return mindspore::kLiteSuccessExit;
133be168c0dSopenharmony_ci-      }
134be168c0dSopenharmony_ci-    }
135be168c0dSopenharmony_ci-    return mindspore::kSuccess;
136be168c0dSopenharmony_ci-  } else {
137be168c0dSopenharmony_ci-    MS_LOG(ERROR) << "primitive is nullptr.";
138be168c0dSopenharmony_ci-    return mindspore::kLiteError;
139be168c0dSopenharmony_ci-  }
140be168c0dSopenharmony_ci-}
141be168c0dSopenharmony_ci namespace {
142be168c0dSopenharmony_ci bool NeedBitUppackCheck(const schema::Tensor &src_tensor) {
143be168c0dSopenharmony_ci   if (src_tensor.enableHuffmanCode()) {
144be168c0dSopenharmony_cidiff --git a/mindspore/lite/src/litert/delegate/nnrt/checker/primitive_check.h b/mindspore/lite/src/litert/delegate/nnrt/checker/primitive_check.h
145be168c0dSopenharmony_ciindex dbdd812c..46b812c0 100644
146be168c0dSopenharmony_ci--- a/mindspore/lite/src/litert/delegate/nnrt/checker/primitive_check.h
147be168c0dSopenharmony_ci+++ b/mindspore/lite/src/litert/delegate/nnrt/checker/primitive_check.h
148be168c0dSopenharmony_ci@@ -4,7 +4,6 @@
149be168c0dSopenharmony_ci #include "include/api/status.h"
150be168c0dSopenharmony_ci namespace mindspore {
151be168c0dSopenharmony_ci namespace lite {
152be168c0dSopenharmony_ci-Status CheckPrimitiveSupported(const schema::Primitive *primitive);
153be168c0dSopenharmony_ci Status CheckTensorSupported(const schema::Tensor *primitive);
154be168c0dSopenharmony_ci }  // namespace lite
155be168c0dSopenharmony_ci }  // namespace mindspore
156be168c0dSopenharmony_cidiff --git a/mindspore/lite/src/litert/delegate/nnrt/nnrt_allocator.cc b/mindspore/lite/src/litert/delegate/nnrt/nnrt_allocator.cc
157be168c0dSopenharmony_ciindex f79c1682..b38fff62 100644
158be168c0dSopenharmony_ci--- a/mindspore/lite/src/litert/delegate/nnrt/nnrt_allocator.cc
159be168c0dSopenharmony_ci+++ b/mindspore/lite/src/litert/delegate/nnrt/nnrt_allocator.cc
160be168c0dSopenharmony_ci@@ -21,7 +21,6 @@
161be168c0dSopenharmony_ci #include <mutex>
162be168c0dSopenharmony_ci #include "src/litert/delegate/nnrt/nnrt_allocator.h"
163be168c0dSopenharmony_ci #include "src/common/log.h"
164be168c0dSopenharmony_ci-#include "interfaces/kits/c/neural_network_runtime/neural_network_runtime.h"
165be168c0dSopenharmony_ci 
166be168c0dSopenharmony_ci namespace mindspore {
167be168c0dSopenharmony_ci namespace lite {
168be168c0dSopenharmony_ci@@ -29,23 +28,17 @@ NNRTAllocator::~NNRTAllocator() {
169be168c0dSopenharmony_ci   std::lock_guard<std::mutex> locker(mutex_);
170be168c0dSopenharmony_ci   for (auto &it : allocated_list_) {
171be168c0dSopenharmony_ci     auto membuf = it.second;
172be168c0dSopenharmony_ci-    if (memory_category_ == NNRT_INPUT) {
173be168c0dSopenharmony_ci-      OH_NNExecutor_DestroyInputMemory(executor_, index_, &(membuf->memory_));
174be168c0dSopenharmony_ci-    } else {
175be168c0dSopenharmony_ci-      OH_NNExecutor_DestroyOutputMemory(executor_, index_, &(membuf->memory_));
176be168c0dSopenharmony_ci-    }
177be168c0dSopenharmony_ci-    free(membuf);
178be168c0dSopenharmony_ci+    OH_NNTensor_Destroy(&membuf->tensor_);
179be168c0dSopenharmony_ci+    OH_NNTensorDesc_Destroy(&membuf->tensor_desc_);
180be168c0dSopenharmony_ci+    delete membuf;
181be168c0dSopenharmony_ci   }
182be168c0dSopenharmony_ci   allocated_list_.clear();
183be168c0dSopenharmony_ci 
184be168c0dSopenharmony_ci   for (auto &it : free_list_) {
185be168c0dSopenharmony_ci     auto membuf = it.second;
186be168c0dSopenharmony_ci-    if (memory_category_ == NNRT_INPUT) {
187be168c0dSopenharmony_ci-      OH_NNExecutor_DestroyInputMemory(executor_, index_, &(membuf->memory_));
188be168c0dSopenharmony_ci-    } else {
189be168c0dSopenharmony_ci-      OH_NNExecutor_DestroyOutputMemory(executor_, index_, &(membuf->memory_));
190be168c0dSopenharmony_ci-    }
191be168c0dSopenharmony_ci-    free(membuf);
192be168c0dSopenharmony_ci+    OH_NNTensor_Destroy(&membuf->tensor_);
193be168c0dSopenharmony_ci+    OH_NNTensorDesc_Destroy(&membuf->tensor_desc_);
194be168c0dSopenharmony_ci+    delete membuf;
195be168c0dSopenharmony_ci   }
196be168c0dSopenharmony_ci   free_list_.clear();
197be168c0dSopenharmony_ci }
198be168c0dSopenharmony_ci@@ -57,8 +50,8 @@ void *NNRTAllocator::Malloc(size_t size) {
199be168c0dSopenharmony_ci     auto membuf = iter->second;
200be168c0dSopenharmony_ci     membuf->ref_count_ = 0;
201be168c0dSopenharmony_ci     (void)free_list_.erase(iter);
202be168c0dSopenharmony_ci-    allocated_list_[membuf->memory_->data] = membuf;
203be168c0dSopenharmony_ci-    return membuf->memory_->data;
204be168c0dSopenharmony_ci+    allocated_list_[membuf->data] = membuf;
205be168c0dSopenharmony_ci+    return membuf->data;
206be168c0dSopenharmony_ci   }
207be168c0dSopenharmony_ci 
208be168c0dSopenharmony_ci   auto membuf = new (std::nothrow) MemBuf();
209be168c0dSopenharmony_ci@@ -66,30 +59,36 @@ void *NNRTAllocator::Malloc(size_t size) {
210be168c0dSopenharmony_ci     MS_LOG(ERROR) << "new Membuf failed.";
211be168c0dSopenharmony_ci     return nullptr;
212be168c0dSopenharmony_ci   }
213be168c0dSopenharmony_ci-
214be168c0dSopenharmony_ci   membuf->ref_count_ = 0;
215be168c0dSopenharmony_ci   if (memory_category_ == NNRT_INPUT) {
216be168c0dSopenharmony_ci-    membuf->memory_ = OH_NNExecutor_AllocateInputMemory(executor_, index_, size);
217be168c0dSopenharmony_ci+    membuf->tensor_desc_ = OH_NNExecutor_CreateInputTensorDesc(executor_, index_);
218be168c0dSopenharmony_ci   } else {
219be168c0dSopenharmony_ci-    membuf->memory_ = OH_NNExecutor_AllocateOutputMemory(executor_, index_, size);
220be168c0dSopenharmony_ci+    membuf->tensor_desc_ = OH_NNExecutor_CreateOutputTensorDesc(executor_, index_);
221be168c0dSopenharmony_ci   }
222be168c0dSopenharmony_ci-
223be168c0dSopenharmony_ci-  if (membuf->memory_ == nullptr) {
224be168c0dSopenharmony_ci-    MS_LOG(ERROR) << "malloc OH_NN_Memory return nullptr";
225be168c0dSopenharmony_ci+  if (membuf->tensor_desc_ == nullptr) {
226be168c0dSopenharmony_ci+    MS_LOG(ERROR) << "OH_NNExecutor_CreateInput/OutputTensorDesc failed, i = " << index_;
227be168c0dSopenharmony_ci+    delete membuf;
228be168c0dSopenharmony_ci+    return nullptr;
229be168c0dSopenharmony_ci+  }
230be168c0dSopenharmony_ci+  membuf->tensor_ = OH_NNTensor_CreateWithSize(device_id_, membuf->tensor_desc_, size);
231be168c0dSopenharmony_ci+  if (membuf->tensor_ == nullptr) {
232be168c0dSopenharmony_ci+    MS_LOG(ERROR) << "OH_NNTensor_CreateWithSize failed, i = " << index_;
233be168c0dSopenharmony_ci+    OH_NNTensorDesc_Destroy(&membuf->tensor_desc_);
234be168c0dSopenharmony_ci+    delete membuf;
235be168c0dSopenharmony_ci     return nullptr;
236be168c0dSopenharmony_ci   }
237be168c0dSopenharmony_ci-  if (membuf->memory_->data == nullptr) {
238be168c0dSopenharmony_ci-    MS_LOG(ERROR) << "malloc OH_NN_Memory return nullptr";
239be168c0dSopenharmony_ci-    if (memory_category_ == NNRT_INPUT) {
240be168c0dSopenharmony_ci-      OH_NNExecutor_DestroyInputMemory(executor_, index_, &(membuf->memory_));
241be168c0dSopenharmony_ci-    } else {
242be168c0dSopenharmony_ci-      OH_NNExecutor_DestroyOutputMemory(executor_, index_, &(membuf->memory_));
243be168c0dSopenharmony_ci-    }
244be168c0dSopenharmony_ci+  membuf->data = OH_NNTensor_GetDataBuffer(membuf->tensor_);
245be168c0dSopenharmony_ci+  if (membuf->data == nullptr) {
246be168c0dSopenharmony_ci+    MS_LOG(ERROR) << "OH_NNTensor_GetDataBuffer failed, i = " << index_;
247be168c0dSopenharmony_ci+    OH_NNTensor_Destroy(&membuf->tensor_);
248be168c0dSopenharmony_ci+    OH_NNTensorDesc_Destroy(&membuf->tensor_desc_);
249be168c0dSopenharmony_ci+    delete membuf;
250be168c0dSopenharmony_ci     return nullptr;
251be168c0dSopenharmony_ci   }
252be168c0dSopenharmony_ci 
253be168c0dSopenharmony_ci-  allocated_list_[membuf->memory_->data] = membuf;
254be168c0dSopenharmony_ci-  return membuf->memory_->data;
255be168c0dSopenharmony_ci+  membuf->size = size;
256be168c0dSopenharmony_ci+  allocated_list_[membuf->data] = membuf;
257be168c0dSopenharmony_ci+  return membuf->data;
258be168c0dSopenharmony_ci }
259be168c0dSopenharmony_ci 
260be168c0dSopenharmony_ci void NNRTAllocator::Free(void *ptr) {
261be168c0dSopenharmony_ci@@ -105,12 +104,12 @@ void NNRTAllocator::Free(void *ptr) {
262be168c0dSopenharmony_ci   auto membuf = iter->second;
263be168c0dSopenharmony_ci   membuf->ref_count_ = 0;
264be168c0dSopenharmony_ci   (void)allocated_list_.erase(iter);
265be168c0dSopenharmony_ci-  (void)free_list_.insert(std::make_pair(membuf->memory_->length, membuf));
266be168c0dSopenharmony_ci+  (void)free_list_.insert(std::make_pair(membuf->size, membuf));
267be168c0dSopenharmony_ci }
268be168c0dSopenharmony_ci 
269be168c0dSopenharmony_ci int NNRTAllocator::RefCount(void *ptr) {
270be168c0dSopenharmony_ci   if (ptr == nullptr) {
271be168c0dSopenharmony_ci-    return -1;
272be168c0dSopenharmony_ci+    return NNRT_ALLOCATION;
273be168c0dSopenharmony_ci   }
274be168c0dSopenharmony_ci   std::lock_guard<std::mutex> locker(mutex_);
275be168c0dSopenharmony_ci   auto iter = allocated_list_.find(ptr);
276be168c0dSopenharmony_ci@@ -163,6 +162,5 @@ int NNRTAllocator::IncRefCount(void *ptr, int ref_count) {
277be168c0dSopenharmony_ci   }
278be168c0dSopenharmony_ci   return -1;
279be168c0dSopenharmony_ci }
280be168c0dSopenharmony_ci-
281be168c0dSopenharmony_ci }  // namespace lite
282be168c0dSopenharmony_ci }  // namespace mindspore
283be168c0dSopenharmony_ci\ No newline at end of file
284be168c0dSopenharmony_cidiff --git a/mindspore/lite/src/litert/delegate/nnrt/nnrt_allocator.h b/mindspore/lite/src/litert/delegate/nnrt/nnrt_allocator.h
285be168c0dSopenharmony_ciindex f6721369..52e6def7 100644
286be168c0dSopenharmony_ci--- a/mindspore/lite/src/litert/delegate/nnrt/nnrt_allocator.h
287be168c0dSopenharmony_ci+++ b/mindspore/lite/src/litert/delegate/nnrt/nnrt_allocator.h
288be168c0dSopenharmony_ci@@ -23,6 +23,9 @@
289be168c0dSopenharmony_ci #include <map>
290be168c0dSopenharmony_ci #include <mutex>
291be168c0dSopenharmony_ci #include "include/api/allocator.h"
292be168c0dSopenharmony_ci+#include "src/tensor.h"
293be168c0dSopenharmony_ci+#include "interfaces/kits/c/neural_network_runtime/neural_network_runtime.h"
294be168c0dSopenharmony_ci+
295be168c0dSopenharmony_ci struct OH_NN_Memory;
296be168c0dSopenharmony_ci struct OH_NNExecutor;
297be168c0dSopenharmony_ci 
298be168c0dSopenharmony_ci@@ -32,8 +35,8 @@ enum MemoryCategory { NNRT_INPUT, NNRT_OUTPUT };
299be168c0dSopenharmony_ci 
300be168c0dSopenharmony_ci class NNRTAllocator : public Allocator {
301be168c0dSopenharmony_ci  public:
302be168c0dSopenharmony_ci-  NNRTAllocator(OH_NNExecutor *executor, int index, MemoryCategory memory_category)
303be168c0dSopenharmony_ci-      : index_(index), memory_category_(memory_category), executor_(executor) {}
304be168c0dSopenharmony_ci+  NNRTAllocator(OH_NNExecutor *executor, int index, size_t device_id, MemoryCategory memory_category)
305be168c0dSopenharmony_ci+      : index_(index), device_id_(device_id), memory_category_(memory_category), executor_(executor) {}
306be168c0dSopenharmony_ci   ~NNRTAllocator() override;
307be168c0dSopenharmony_ci 
308be168c0dSopenharmony_ci   void *Malloc(size_t size) override;
309be168c0dSopenharmony_ci@@ -42,14 +45,25 @@ class NNRTAllocator : public Allocator {
310be168c0dSopenharmony_ci   int SetRefCount(void *ptr, int ref_count) override;
311be168c0dSopenharmony_ci   int DecRefCount(void *ptr, int ref_count) override;
312be168c0dSopenharmony_ci   int IncRefCount(void *ptr, int ref_count) override;
313be168c0dSopenharmony_ci+  NN_Tensor *GetNNTensor(void *ptr) {
314be168c0dSopenharmony_ci+    auto iter = allocated_list_.find(ptr);
315be168c0dSopenharmony_ci+    if (iter != allocated_list_.end()) {
316be168c0dSopenharmony_ci+      return iter->second->tensor_;
317be168c0dSopenharmony_ci+    }
318be168c0dSopenharmony_ci+    return nullptr;
319be168c0dSopenharmony_ci+  }
320be168c0dSopenharmony_ci 
321be168c0dSopenharmony_ci  private:
322be168c0dSopenharmony_ci   struct MemBuf {
323be168c0dSopenharmony_ci     std::atomic_int ref_count_{0};
324be168c0dSopenharmony_ci-    OH_NN_Memory *memory_{nullptr};
325be168c0dSopenharmony_ci+    NN_TensorDesc *tensor_desc_{nullptr};
326be168c0dSopenharmony_ci+    NN_Tensor *tensor_{nullptr};
327be168c0dSopenharmony_ci+    void *data{nullptr};
328be168c0dSopenharmony_ci+    size_t size{0};
329be168c0dSopenharmony_ci   };
330be168c0dSopenharmony_ci 
331be168c0dSopenharmony_ci   int index_{0};
332be168c0dSopenharmony_ci+  size_t device_id_{0};
333be168c0dSopenharmony_ci   MemoryCategory memory_category_{NNRT_INPUT};
334be168c0dSopenharmony_ci   OH_NNExecutor *executor_{nullptr};
335be168c0dSopenharmony_ci   std::mutex mutex_;
336be168c0dSopenharmony_cidiff --git a/mindspore/lite/src/litert/delegate/nnrt/nnrt_delegate.cc b/mindspore/lite/src/litert/delegate/nnrt/nnrt_delegate.cc
337be168c0dSopenharmony_ciindex d8450141..a949c910 100644
338be168c0dSopenharmony_ci--- a/mindspore/lite/src/litert/delegate/nnrt/nnrt_delegate.cc
339be168c0dSopenharmony_ci+++ b/mindspore/lite/src/litert/delegate/nnrt/nnrt_delegate.cc
340be168c0dSopenharmony_ci@@ -169,7 +169,7 @@ Status NNRTDelegate::CreateFullModelKernel(DelegateModel<schema::Primitive> *mod
341be168c0dSopenharmony_ci   }
342be168c0dSopenharmony_ci   OH_NNCompilation_Destroy(&nn_compilation);
343be168c0dSopenharmony_ci 
344be168c0dSopenharmony_ci-  auto nnrt_model_kernel = new (std::nothrow)NNRTModelKernel(nn_executor, model->inputs(), model->outputs());
345be168c0dSopenharmony_ci+  auto nnrt_model_kernel = new (std::nothrow)NNRTModelKernel(nn_executor, nnrt_device_info_.device_id_, model->inputs(), model->outputs());
346be168c0dSopenharmony_ci   if (nnrt_model_kernel == nullptr) {
347be168c0dSopenharmony_ci     OH_NNExecutor_Destroy(&nn_executor);
348be168c0dSopenharmony_ci     MS_LOG(ERROR) << "new NNRTModelKernel failed";
349be168c0dSopenharmony_ci@@ -581,7 +581,7 @@ Status NNRTDelegate::CreateNNRTSubgraphKernels(DelegateModel<schema::Primitive>
350be168c0dSopenharmony_ci       continue ;
351be168c0dSopenharmony_ci     }
352be168c0dSopenharmony_ci 
353be168c0dSopenharmony_ci-    auto nnrt_model_kernel = new (std::nothrow)NNRTModelKernel(nn_executor, in_tensors, out_tensors);
354be168c0dSopenharmony_ci+    auto nnrt_model_kernel = new (std::nothrow)NNRTModelKernel(nn_executor, nnrt_device_info_.device_id_, in_tensors, out_tensors);
355be168c0dSopenharmony_ci     if (nnrt_model_kernel == nullptr) {
356be168c0dSopenharmony_ci       MS_LOG(ERROR) << "new NNRTModelKernel failed";
357be168c0dSopenharmony_ci       return kLiteError;
358be168c0dSopenharmony_ci@@ -760,6 +760,15 @@ schema::Tensor *NNRTDelegate::TensorToSchemaTensor(Tensor *lite_tensor, schema::
359be168c0dSopenharmony_ci   memcpy(tensor_buf, buf, fbb.GetSize());
360be168c0dSopenharmony_ci   auto tensor = flatbuffers::GetRoot<schema::Tensor>(tensor_buf);
361be168c0dSopenharmony_ci   fbb.Clear();
362be168c0dSopenharmony_ci+  if (tensor != nullptr) {
363be168c0dSopenharmony_ci+    // use to free tensor_buf
364be168c0dSopenharmony_ci+    auto iter = dequant_schema_tensors_buffer_map_.find(const_cast<schema::Tensor *>(tensor));
365be168c0dSopenharmony_ci+    if (iter != dequant_schema_tensors_buffer_map_.end()) {
366be168c0dSopenharmony_ci+      MS_LOG(ERROR) << "schema tensor is duplicated.";
367be168c0dSopenharmony_ci+      return nullptr;
368be168c0dSopenharmony_ci+    }
369be168c0dSopenharmony_ci+    dequant_schema_tensors_buffer_map_[const_cast<schema::Tensor *>(tensor)] = tensor_buf;
370be168c0dSopenharmony_ci+  }
371be168c0dSopenharmony_ci   return const_cast<schema::Tensor *>(tensor);
372be168c0dSopenharmony_ci }
373be168c0dSopenharmony_ci 
374be168c0dSopenharmony_ci@@ -813,14 +822,6 @@ Status NNRTDelegate::DequantLiteGraph(LiteGraph *lite_graph) {
375be168c0dSopenharmony_ci }
376be168c0dSopenharmony_ci 
377be168c0dSopenharmony_ci void NNRTDelegate::ShallowCopyLiteGraph(const lite::LiteGraph &lite_graph) {
378be168c0dSopenharmony_ci-  Status ret;
379be168c0dSopenharmony_ci-  for (auto node : lite_graph.all_nodes_) {
380be168c0dSopenharmony_ci-    ret = lite::CheckPrimitiveSupported(static_cast<const schema::Primitive *>(node->primitive_));
381be168c0dSopenharmony_ci-    if (ret == kLiteError) {
382be168c0dSopenharmony_ci-      MS_LOG(ERROR) << " primitive supported check failed.";
383be168c0dSopenharmony_ci-      return;
384be168c0dSopenharmony_ci-    }
385be168c0dSopenharmony_ci-  }
386be168c0dSopenharmony_ci   std::vector<LiteGraph::Node *> node_list;
387be168c0dSopenharmony_ci   node_list.reserve(lite_graph.all_nodes_.size());
388be168c0dSopenharmony_ci   // copy node
389be168c0dSopenharmony_ci@@ -856,7 +857,7 @@ void NNRTDelegate::ShallowCopyLiteGraph(const lite::LiteGraph &lite_graph) {
390be168c0dSopenharmony_ci     subgraph_list.emplace_back(new_subgraph);
391be168c0dSopenharmony_ci   }
392be168c0dSopenharmony_ci   for (auto tensor : lite_graph.all_tensors_) {
393be168c0dSopenharmony_ci-    ret = lite::CheckTensorSupported(static_cast<const schema::Tensor *>(tensor));
394be168c0dSopenharmony_ci+    Status ret = lite::CheckTensorSupported(static_cast<const schema::Tensor *>(tensor));
395be168c0dSopenharmony_ci     if (ret == kLiteError) {
396be168c0dSopenharmony_ci       MS_LOG(ERROR) << "tensor supported check failed.";
397be168c0dSopenharmony_ci       return;
398be168c0dSopenharmony_ci@@ -921,10 +922,13 @@ NNRTDelegate::~NNRTDelegate() {
399be168c0dSopenharmony_ci   if (lite_graph_ != nullptr) {
400be168c0dSopenharmony_ci     MS_LOG(ERROR) << "Delete NNRTDelegate.";
401be168c0dSopenharmony_ci   }
402be168c0dSopenharmony_ci-  for (auto iter : dequant_schema_tensors_) {
403be168c0dSopenharmony_ci-    delete iter.second;
404be168c0dSopenharmony_ci-    iter.second = nullptr;
405be168c0dSopenharmony_ci+  for (auto iter : dequant_schema_tensors_buffer_map_) {
406be168c0dSopenharmony_ci+    if (iter.second != nullptr) {
407be168c0dSopenharmony_ci+      free(iter.second);
408be168c0dSopenharmony_ci+      iter.second = nullptr;
409be168c0dSopenharmony_ci+    }
410be168c0dSopenharmony_ci   }
411be168c0dSopenharmony_ci+  dequant_schema_tensors_buffer_map_.clear();
412be168c0dSopenharmony_ci }
413be168c0dSopenharmony_ci }  // namespace lite
414be168c0dSopenharmony_ci }  // namespace mindspore
415be168c0dSopenharmony_cidiff --git a/mindspore/lite/src/litert/delegate/nnrt/nnrt_delegate.h b/mindspore/lite/src/litert/delegate/nnrt/nnrt_delegate.h
416be168c0dSopenharmony_ciindex 778553ef..db2f0ee7 100644
417be168c0dSopenharmony_ci--- a/mindspore/lite/src/litert/delegate/nnrt/nnrt_delegate.h
418be168c0dSopenharmony_ci+++ b/mindspore/lite/src/litert/delegate/nnrt/nnrt_delegate.h
419be168c0dSopenharmony_ci@@ -95,6 +95,7 @@ class NNRTDelegate : public Delegate {
420be168c0dSopenharmony_ci   std::vector<OH_NNExecutor *> nn_executor_list_;
421be168c0dSopenharmony_ci   std::vector<Tensor *> *dequant_src_tensors_;
422be168c0dSopenharmony_ci   std::map<uint32_t, schema::Tensor *> dequant_schema_tensors_;
423be168c0dSopenharmony_ci+  std::map<schema::Tensor *, void *> dequant_schema_tensors_buffer_map_;
424be168c0dSopenharmony_ci   std::vector<schema::Tensor *> replaced_schema_tensors_;
425be168c0dSopenharmony_ci };
426be168c0dSopenharmony_ci }  // namespace lite
427be168c0dSopenharmony_cidiff --git a/mindspore/lite/src/litert/delegate/nnrt/nnrt_model_kernel.cc b/mindspore/lite/src/litert/delegate/nnrt/nnrt_model_kernel.cc
428be168c0dSopenharmony_ciindex f83632dd..2a66d133 100644
429be168c0dSopenharmony_ci--- a/mindspore/lite/src/litert/delegate/nnrt/nnrt_model_kernel.cc
430be168c0dSopenharmony_ci+++ b/mindspore/lite/src/litert/delegate/nnrt/nnrt_model_kernel.cc
431be168c0dSopenharmony_ci@@ -19,7 +19,7 @@
432be168c0dSopenharmony_ci #include "litert/cxx_api/tensor/tensor_impl.h"
433be168c0dSopenharmony_ci int mindspore::NNRTModelKernel::Prepare() {
434be168c0dSopenharmony_ci   for (size_t i = 0; i < inputs_.size(); i++) {
435be168c0dSopenharmony_ci-    auto nnrt_allocator = std::make_shared<lite::NNRTAllocator>(oh_nn_executor, i, lite::NNRT_INPUT);
436be168c0dSopenharmony_ci+    auto nnrt_allocator = std::make_shared<lite::NNRTAllocator>(oh_nn_executor, i, device_id_, lite::NNRT_INPUT);
437be168c0dSopenharmony_ci     if (nnrt_allocator == nullptr) {
438be168c0dSopenharmony_ci       MS_LOG(ERROR) << "Create NNRTAllocator failed";
439be168c0dSopenharmony_ci       return lite::RET_NULL_PTR;
440be168c0dSopenharmony_ci@@ -27,7 +27,7 @@ int mindspore::NNRTModelKernel::Prepare() {
441be168c0dSopenharmony_ci     inputs_[i].SetAllocator(nnrt_allocator);
442be168c0dSopenharmony_ci   }
443be168c0dSopenharmony_ci   for (size_t i = 0; i < outputs_.size(); i++) {
444be168c0dSopenharmony_ci-    auto nnrt_allocator = std::make_shared<lite::NNRTAllocator>(oh_nn_executor, i, lite::NNRT_OUTPUT);
445be168c0dSopenharmony_ci+    auto nnrt_allocator = std::make_shared<lite::NNRTAllocator>(oh_nn_executor, i, device_id_, lite::NNRT_OUTPUT);
446be168c0dSopenharmony_ci     if (nnrt_allocator == nullptr) {
447be168c0dSopenharmony_ci       MS_LOG(ERROR) << "Create NNRTAllocator failed";
448be168c0dSopenharmony_ci       return lite::RET_NULL_PTR;
449be168c0dSopenharmony_ci@@ -39,25 +39,33 @@ int mindspore::NNRTModelKernel::Prepare() {
450be168c0dSopenharmony_ci 
451be168c0dSopenharmony_ci int mindspore::NNRTModelKernel::Execute() {
452be168c0dSopenharmony_ci   MS_CHECK_TRUE_RET(this->outputs().empty() != true, lite::RET_ERROR);
453be168c0dSopenharmony_ci-  zero_copy_ = this->outputs()[Index0].allocator() != nullptr;
454be168c0dSopenharmony_ci+  zero_copy_ = IS_NNRT_ALLOCATOR(this->outputs()[Index0].allocator());
455be168c0dSopenharmony_ci 
456be168c0dSopenharmony_ci+  if (!zero_copy_) {
457be168c0dSopenharmony_ci+    FreeNNTensor();
458be168c0dSopenharmony_ci+  }
459be168c0dSopenharmony_ci+  nn_input_tensors_.clear();
460be168c0dSopenharmony_ci+  nn_output_tensors_.clear();
461be168c0dSopenharmony_ci+  nn_input_tensor_descs_.clear();
462be168c0dSopenharmony_ci+  nn_output_tensor_descs_.clear();
463be168c0dSopenharmony_ci 
464be168c0dSopenharmony_ci-  lite::STATUS ret_val = PrepareInputs();
465be168c0dSopenharmony_ci+  lite::STATUS ret_val = SetInputs();
466be168c0dSopenharmony_ci   if (ret_val != lite::RET_OK) {
467be168c0dSopenharmony_ci-    MS_LOG(ERROR) << "NNRTModelKernel PrepareInputs failed, STATUS is " << ret_val;
468be168c0dSopenharmony_ci+    MS_LOG(ERROR) << "NNRTModelKernel SetInputs failed, STATUS is " << ret_val;
469be168c0dSopenharmony_ci     return ret_val;
470be168c0dSopenharmony_ci   }
471be168c0dSopenharmony_ci-  ret_val = TransferOutputs();
472be168c0dSopenharmony_ci+  ret_val = SetOutputs();
473be168c0dSopenharmony_ci   if (ret_val != lite::RET_OK) {
474be168c0dSopenharmony_ci-    MS_LOG(ERROR) << "NNRTModelKernel TransferOutputs failed, STATUS is " << ret_val;
475be168c0dSopenharmony_ci+    MS_LOG(ERROR) << "NNRTModelKernel SetOutputs failed, STATUS is " << ret_val;
476be168c0dSopenharmony_ci     return ret_val;
477be168c0dSopenharmony_ci   }
478be168c0dSopenharmony_ci   MS_LOG(INFO) << "Running NNRtModel Kernel...";
479be168c0dSopenharmony_ci   OH_NN_ReturnCode ret_code;
480be168c0dSopenharmony_ci-  ret_code = OH_NNExecutor_Run(this->oh_nn_executor);
481be168c0dSopenharmony_ci+  ret_code = OH_NNExecutor_RunSync(oh_nn_executor, nn_input_tensors_.data(), nn_input_tensors_.size(),
482be168c0dSopenharmony_ci+                                   nn_output_tensors_.data(), nn_output_tensors_.size());
483be168c0dSopenharmony_ci 
484be168c0dSopenharmony_ci   if (ret_code != OH_NN_SUCCESS) {
485be168c0dSopenharmony_ci-    MS_LOG(ERROR) << "NNExecutor Run failed, OH_NN_ReturnCode = " << ret_code;
486be168c0dSopenharmony_ci+    MS_LOG(ERROR) << "OH_NNExecutor_RunSync Run failed, OH_NN_ReturnCode = " << ret_code;
487be168c0dSopenharmony_ci     return lite::RET_ERROR;
488be168c0dSopenharmony_ci   }
489be168c0dSopenharmony_ci   MS_LOG(INFO) << "Run NNRtModel Kernel success.";
490be168c0dSopenharmony_ci@@ -120,97 +128,107 @@ OH_NN_DataType mindspore::NNRTModelKernel::ConvertDataType(mindspore::DataType d
491be168c0dSopenharmony_ci   }
492be168c0dSopenharmony_ci   return oh_data_type;
493be168c0dSopenharmony_ci }
494be168c0dSopenharmony_ci-int mindspore::NNRTModelKernel::PrepareInputs() {
495be168c0dSopenharmony_ci-  auto input_tensors = this->inputs();
496be168c0dSopenharmony_ci-  for (size_t i = 0; i < input_tensors.size(); i++) {
497be168c0dSopenharmony_ci-    auto tensor = input_tensors[i];
498be168c0dSopenharmony_ci-    auto tensor_shape = tensor.Shape();
499be168c0dSopenharmony_ci-    auto tmp_quant_param = tensor.QuantParams();
500be168c0dSopenharmony_ci-    OH_NN_QuantParam *quant_param = nullptr;
501be168c0dSopenharmony_ci-    std::vector<uint32_t> bit_num;
502be168c0dSopenharmony_ci-    std::vector<double> scale;
503be168c0dSopenharmony_ci-    std::vector<int32_t> zero_point;
504be168c0dSopenharmony_ci-    if (!tmp_quant_param.empty()) {
505be168c0dSopenharmony_ci-      quant_param = (new (std::nothrow) OH_NN_QuantParam);
506be168c0dSopenharmony_ci-      if (quant_param == nullptr) {
507be168c0dSopenharmony_ci-        MS_LOG(ERROR) << "new OH_NN_QuantParam failed.";
508be168c0dSopenharmony_ci-        return lite::RET_NULL_PTR;
509be168c0dSopenharmony_ci-      }
510be168c0dSopenharmony_ci-      for (auto qparam : tmp_quant_param) {
511be168c0dSopenharmony_ci-        bit_num.emplace_back(qparam.bit_num);
512be168c0dSopenharmony_ci-        scale.emplace_back(qparam.scale);
513be168c0dSopenharmony_ci-        zero_point.emplace_back(qparam.zero_point);
514be168c0dSopenharmony_ci-      }
515be168c0dSopenharmony_ci-      quant_param->quantCount = tmp_quant_param.size();
516be168c0dSopenharmony_ci-      quant_param->numBits = bit_num.data();
517be168c0dSopenharmony_ci-      quant_param->scale = scale.data();
518be168c0dSopenharmony_ci-      quant_param->zeroPoint = zero_point.data();
519be168c0dSopenharmony_ci+
520be168c0dSopenharmony_ci+int mindspore::NNRTModelKernel::SetInputs() {
521be168c0dSopenharmony_ci+  if (!zero_copy_) {
522be168c0dSopenharmony_ci+    OH_NN_ReturnCode ret{OH_NN_FAILED};
523be168c0dSopenharmony_ci+    size_t nn_input_count = 0;
524be168c0dSopenharmony_ci+    ret = OH_NNExecutor_GetInputCount(oh_nn_executor, &nn_input_count);
525be168c0dSopenharmony_ci+    if (ret != OH_NN_SUCCESS) {
526be168c0dSopenharmony_ci+      MS_LOG(ERROR) << "OH_NNExecutor_GetInputCount failed.";
527be168c0dSopenharmony_ci+      return lite::RET_ERROR;
528be168c0dSopenharmony_ci     }
529be168c0dSopenharmony_ci-    auto oprend = new (std::nothrow) OH_NN_Tensor;
530be168c0dSopenharmony_ci-    if (oprend == nullptr) {
531be168c0dSopenharmony_ci-      MS_LOG(ERROR) << "new OH_NN_Tensor Failed";
532be168c0dSopenharmony_ci+    if (nn_input_count != inputs_.size()) {
533be168c0dSopenharmony_ci+      MS_LOG(ERROR) << "input count is not equal between ms and nnrt.";
534be168c0dSopenharmony_ci       return lite::RET_ERROR;
535be168c0dSopenharmony_ci     }
536be168c0dSopenharmony_ci-    oprend->dataType = ConvertDataType(tensor.DataType());
537be168c0dSopenharmony_ci-    oprend->dimensionCount = tensor_shape.size();
538be168c0dSopenharmony_ci-
539be168c0dSopenharmony_ci-    std::vector<int32_t> dimensions_list;
540be168c0dSopenharmony_ci-    for (auto shape : tensor_shape) {
541be168c0dSopenharmony_ci-      if (shape < INT32_MAX) {
542be168c0dSopenharmony_ci-        dimensions_list.emplace_back(static_cast<int32_t>(shape));
543be168c0dSopenharmony_ci-      } else {
544be168c0dSopenharmony_ci-        MS_LOG(ERROR) << "NNExecutor SetInput failed,tensor dimension is is too large, max dim = " << INT32_MAX
545be168c0dSopenharmony_ci-                      << ", but get dimension = " << shape;
546be168c0dSopenharmony_ci+    for (size_t i = 0; i < nn_input_count; i++) {
547be168c0dSopenharmony_ci+      NN_TensorDesc *tensor_desc_tmp = OH_NNExecutor_CreateInputTensorDesc(oh_nn_executor, i);
548be168c0dSopenharmony_ci+      if (tensor_desc_tmp == nullptr) {
549be168c0dSopenharmony_ci+        MS_LOG(ERROR) << "OH_NNExecutor_CreateInputTensorDesc failed, i = " << i;
550be168c0dSopenharmony_ci         return lite::RET_ERROR;
551be168c0dSopenharmony_ci       }
552be168c0dSopenharmony_ci+      nn_input_tensor_descs_.emplace_back(tensor_desc_tmp);
553be168c0dSopenharmony_ci+      NN_Tensor *tensor_tmp = OH_NNTensor_Create(device_id_, tensor_desc_tmp);
554be168c0dSopenharmony_ci+      if (tensor_tmp == nullptr) {
555be168c0dSopenharmony_ci+        MS_LOG(ERROR) << "OH_NNTensor_Create input failed, i = " << i;
556be168c0dSopenharmony_ci+        return lite::RET_ERROR;
557be168c0dSopenharmony_ci+      }
558be168c0dSopenharmony_ci+      nn_input_tensors_.emplace_back(tensor_tmp);
559be168c0dSopenharmony_ci+      void *nn_data = OH_NNTensor_GetDataBuffer(nn_input_tensors_[i]);
560be168c0dSopenharmony_ci+      size_t tensor_size;
561be168c0dSopenharmony_ci+      ret = OH_NNTensorDesc_GetByteSize(tensor_desc_tmp, &tensor_size);
562be168c0dSopenharmony_ci+      if (ret != OH_NN_SUCCESS || tensor_size != inputs_[i].DataSize()) {
563be168c0dSopenharmony_ci+        MS_LOG(ERROR) << "NN_Tensor size is not equal to MSTensor, i = " << i;
564be168c0dSopenharmony_ci+        return lite::RET_ERROR;
565be168c0dSopenharmony_ci+      }
566be168c0dSopenharmony_ci+      memcpy(nn_data, inputs_[i].MutableData(), inputs_[i].DataSize());
567be168c0dSopenharmony_ci     }
568be168c0dSopenharmony_ci-    oprend->dimensions = dimensions_list.data();
569be168c0dSopenharmony_ci-    oprend->quantParam = quant_param;
570be168c0dSopenharmony_ci-    oprend->type = OH_NN_TENSOR;
571be168c0dSopenharmony_ci-    MS_LOG_INFO << "input tensor: " << tensor.Name() << ", data: " << (void *)tensor.MutableData()
572be168c0dSopenharmony_ci-                << ", size: " << tensor.DataSize();
573be168c0dSopenharmony_ci-
574be168c0dSopenharmony_ci-    OH_NN_ReturnCode ret_code;
575be168c0dSopenharmony_ci-    if (zero_copy_) {
576be168c0dSopenharmony_ci-      OH_NN_Memory mem{tensor.MutableData(), tensor.DataSize()};
577be168c0dSopenharmony_ci-      ret_code = OH_NNExecutor_SetInputWithMemory(oh_nn_executor, i, oprend, &mem);
578be168c0dSopenharmony_ci-    } else {
579be168c0dSopenharmony_ci-      ret_code = OH_NNExecutor_SetInput(oh_nn_executor, i, oprend, tensor.MutableData(), tensor.DataSize());
580be168c0dSopenharmony_ci-    }
581be168c0dSopenharmony_ci-
582be168c0dSopenharmony_ci-    delete (oprend);
583be168c0dSopenharmony_ci-
584be168c0dSopenharmony_ci-    if (!tmp_quant_param.empty()) {
585be168c0dSopenharmony_ci-      free(quant_param);
586be168c0dSopenharmony_ci-      quant_param = nullptr;
587be168c0dSopenharmony_ci-    }
588be168c0dSopenharmony_ci-
589be168c0dSopenharmony_ci-    if (ret_code != OH_NN_SUCCESS) {
590be168c0dSopenharmony_ci-      MS_LOG(ERROR) << "NNExecutor SetInput failed, current input tensor is" << tensor.Name()
591be168c0dSopenharmony_ci-                    << "OH_NN_ReturnCode = " << ret_code;
592be168c0dSopenharmony_ci-      return lite::RET_ERROR;
593be168c0dSopenharmony_ci+  } else {
594be168c0dSopenharmony_ci+    for (size_t i = 0; i < inputs_.size(); i++) {
595be168c0dSopenharmony_ci+      void *data = inputs_[i].MutableData();
596be168c0dSopenharmony_ci+      NN_Tensor *tensor_tmp = reinterpret_cast<lite::NNRTAllocator *>(inputs_[i].allocator().get())->GetNNTensor(data);
597be168c0dSopenharmony_ci+      if (tensor_tmp == nullptr) {
598be168c0dSopenharmony_ci+        MS_LOG(ERROR) << "NNRTAllocator GetNNTensor failed, i = " << i;
599be168c0dSopenharmony_ci+        return lite::RET_ERROR;
600be168c0dSopenharmony_ci+      }
601be168c0dSopenharmony_ci+      nn_input_tensors_.emplace_back(tensor_tmp);
602be168c0dSopenharmony_ci     }
603be168c0dSopenharmony_ci   }
604be168c0dSopenharmony_ci-
605be168c0dSopenharmony_ci   return lite::RET_OK;
606be168c0dSopenharmony_ci }
607be168c0dSopenharmony_ci-int mindspore::NNRTModelKernel::TransferOutputs() {
608be168c0dSopenharmony_ci-  auto output_tensors = this->outputs();
609be168c0dSopenharmony_ci-  for (size_t i = 0; i < output_tensors.size(); i++) {
610be168c0dSopenharmony_ci-    auto tensor = output_tensors[i];
611be168c0dSopenharmony_ci 
612be168c0dSopenharmony_ci-    OH_NN_ReturnCode ret_code;
613be168c0dSopenharmony_ci-    if (zero_copy_) {
614be168c0dSopenharmony_ci-      OH_NN_Memory mem{tensor.MutableData(), tensor.DataSize()};
615be168c0dSopenharmony_ci-      ret_code = OH_NNExecutor_SetOutputWithMemory(oh_nn_executor, i, &mem);
616be168c0dSopenharmony_ci-    } else {
617be168c0dSopenharmony_ci-      ret_code = OH_NNExecutor_SetOutput(oh_nn_executor, i, tensor.MutableData(), tensor.DataSize());
618be168c0dSopenharmony_ci+int mindspore::NNRTModelKernel::SetOutputs() {
619be168c0dSopenharmony_ci+  if (!zero_copy_) {
620be168c0dSopenharmony_ci+    OH_NN_ReturnCode ret{OH_NN_FAILED};
621be168c0dSopenharmony_ci+    size_t nn_output_count = 0;
622be168c0dSopenharmony_ci+    ret = OH_NNExecutor_GetOutputCount(oh_nn_executor, &nn_output_count);
623be168c0dSopenharmony_ci+    if (ret != OH_NN_SUCCESS) {
624be168c0dSopenharmony_ci+      MS_LOG(ERROR) << "OH_NNExecutor_GetOutputCount failed.";
625be168c0dSopenharmony_ci+      return lite::RET_ERROR;
626be168c0dSopenharmony_ci     }
627be168c0dSopenharmony_ci-    if (ret_code != OH_NN_SUCCESS) {
628be168c0dSopenharmony_ci-      MS_LOG(ERROR) << "NNExecutor SetOutput failed, current out tensor is" << tensor.Name()
629be168c0dSopenharmony_ci-                    << ", OH_NN_ReturnCode = " << ret_code;
630be168c0dSopenharmony_ci+    if (nn_output_count != outputs_.size()) {
631be168c0dSopenharmony_ci+      MS_LOG(ERROR) << "output count is not equal between ms and nnrt.";
632be168c0dSopenharmony_ci       return lite::RET_ERROR;
633be168c0dSopenharmony_ci     }
634be168c0dSopenharmony_ci+    for (size_t i = 0; i < nn_output_count; i++) {
635be168c0dSopenharmony_ci+      NN_TensorDesc *tensor_desc_tmp = OH_NNExecutor_CreateOutputTensorDesc(oh_nn_executor, i);
636be168c0dSopenharmony_ci+      if (tensor_desc_tmp == nullptr) {
637be168c0dSopenharmony_ci+        MS_LOG(ERROR) << "OH_NNExecutor_CreateOutputTensorDesc failed, i = " << i;
638be168c0dSopenharmony_ci+        return lite::RET_ERROR;
639be168c0dSopenharmony_ci+      }
640be168c0dSopenharmony_ci+      nn_output_tensor_descs_.emplace_back(tensor_desc_tmp);
641be168c0dSopenharmony_ci+      NN_Tensor *tensor_tmp = OH_NNTensor_Create(device_id_, tensor_desc_tmp);
642be168c0dSopenharmony_ci+      if (tensor_tmp == nullptr) {
643be168c0dSopenharmony_ci+        MS_LOG(ERROR) << "OH_NNTensor_Create output failed, i = " << i;
644be168c0dSopenharmony_ci+        return lite::RET_ERROR;
645be168c0dSopenharmony_ci+      }
646be168c0dSopenharmony_ci+      nn_output_tensors_.emplace_back(tensor_tmp);
647be168c0dSopenharmony_ci+      auto data = OH_NNTensor_GetDataBuffer(nn_output_tensors_[i]);
648be168c0dSopenharmony_ci+      reinterpret_cast<LiteTensorImpl *>(outputs_[i].impl().get())->lite_tensor()->FreeData();
649be168c0dSopenharmony_ci+      outputs_[i].SetData(data, false);
650be168c0dSopenharmony_ci+    }
651be168c0dSopenharmony_ci+  } else {
652be168c0dSopenharmony_ci+    for (size_t i = 0; i < outputs_.size(); i++) {
653be168c0dSopenharmony_ci+      void *data = outputs_[i].MutableData();
654be168c0dSopenharmony_ci+      NN_Tensor *tensor_tmp = reinterpret_cast<lite::NNRTAllocator *>(outputs_[i].allocator().get())->GetNNTensor(data);
655be168c0dSopenharmony_ci+      if (tensor_tmp == nullptr) {
656be168c0dSopenharmony_ci+        MS_LOG(ERROR) << "NNRTAllocator GetNNTensor failed, i = " << i;
657be168c0dSopenharmony_ci+        return lite::RET_ERROR;
658be168c0dSopenharmony_ci+      }
659be168c0dSopenharmony_ci+      nn_output_tensors_.emplace_back(tensor_tmp);
660be168c0dSopenharmony_ci+    }
661be168c0dSopenharmony_ci   }
662be168c0dSopenharmony_ci   return lite::RET_OK;
663be168c0dSopenharmony_ci }
664be168c0dSopenharmony_ci+
665be168c0dSopenharmony_ci+void mindspore::NNRTModelKernel::FreeNNTensor() {
666be168c0dSopenharmony_ci+  for (size_t i = 0; i < nn_input_tensors_.size(); i++) {
667be168c0dSopenharmony_ci+    OH_NNTensor_Destroy(&nn_input_tensors_[i]);
668be168c0dSopenharmony_ci+    OH_NNTensorDesc_Destroy(&nn_input_tensor_descs_[i]);
669be168c0dSopenharmony_ci+  }
670be168c0dSopenharmony_ci+  for (size_t i = 0; i < nn_output_tensors_.size(); i++) {
671be168c0dSopenharmony_ci+    OH_NNTensor_Destroy(&nn_output_tensors_[i]);
672be168c0dSopenharmony_ci+    OH_NNTensorDesc_Destroy(&nn_output_tensor_descs_[i]);
673be168c0dSopenharmony_ci+  }
674be168c0dSopenharmony_ci+}
675be168c0dSopenharmony_cidiff --git a/mindspore/lite/src/litert/delegate/nnrt/nnrt_model_kernel.h b/mindspore/lite/src/litert/delegate/nnrt/nnrt_model_kernel.h
676be168c0dSopenharmony_ciindex 33df925c..40800a2a 100644
677be168c0dSopenharmony_ci--- a/mindspore/lite/src/litert/delegate/nnrt/nnrt_model_kernel.h
678be168c0dSopenharmony_ci+++ b/mindspore/lite/src/litert/delegate/nnrt/nnrt_model_kernel.h
679be168c0dSopenharmony_ci@@ -31,9 +31,9 @@ class NNRTModelKernel : public kernel::Kernel {
680be168c0dSopenharmony_ci    * Because nnr can't run single op, but the whole model. So we decide to make the whole model into one kernel.
681be168c0dSopenharmony_ci    * */
682be168c0dSopenharmony_ci  public:
683be168c0dSopenharmony_ci-  NNRTModelKernel(OH_NNExecutor *oh_nn_executor, const std::vector<mindspore::MSTensor> &inputs,
684be168c0dSopenharmony_ci+  NNRTModelKernel(OH_NNExecutor *oh_nn_executor, size_t device_id, const std::vector<mindspore::MSTensor> &inputs,
685be168c0dSopenharmony_ci                   const std::vector<mindspore::MSTensor> &outputs)
686be168c0dSopenharmony_ci-      : kernel::Kernel(inputs, outputs, nullptr, nullptr), oh_nn_executor(oh_nn_executor) {}
687be168c0dSopenharmony_ci+      : kernel::Kernel(inputs, outputs, nullptr, nullptr), device_id_(device_id), oh_nn_executor(oh_nn_executor) {}
688be168c0dSopenharmony_ci   int Prepare() override;
689be168c0dSopenharmony_ci   int Execute() override;
690be168c0dSopenharmony_ci   int ReSize() override {
691be168c0dSopenharmony_ci@@ -41,14 +41,23 @@ class NNRTModelKernel : public kernel::Kernel {
692be168c0dSopenharmony_ci     return lite::RET_ERROR;
693be168c0dSopenharmony_ci   };
694be168c0dSopenharmony_ci   OH_NN_DataType ConvertDataType(mindspore::DataType data_type);
695be168c0dSopenharmony_ci-  int PrepareInputs();
696be168c0dSopenharmony_ci-  int TransferOutputs();
697be168c0dSopenharmony_ci+  int SetInputs();
698be168c0dSopenharmony_ci+  int SetOutputs();
699be168c0dSopenharmony_ci+  void FreeNNTensor();
700be168c0dSopenharmony_ci   ~NNRTModelKernel() override {
701be168c0dSopenharmony_ci+    if (!zero_copy_) {
702be168c0dSopenharmony_ci+      FreeNNTensor();
703be168c0dSopenharmony_ci+    }
704be168c0dSopenharmony_ci     MS_LOG(INFO) << "NNRTModelKernel Destroy.";
705be168c0dSopenharmony_ci   }
706be168c0dSopenharmony_ci 
707be168c0dSopenharmony_ci  protected:
708be168c0dSopenharmony_ci+  size_t device_id_;
709be168c0dSopenharmony_ci   OH_NNExecutor *oh_nn_executor = nullptr;
710be168c0dSopenharmony_ci+  std::vector<NN_Tensor *> nn_input_tensors_;
711be168c0dSopenharmony_ci+  std::vector<NN_TensorDesc *> nn_input_tensor_descs_;
712be168c0dSopenharmony_ci+  std::vector<NN_Tensor *> nn_output_tensors_;
713be168c0dSopenharmony_ci+  std::vector<NN_TensorDesc *> nn_output_tensor_descs_;
714be168c0dSopenharmony_ci 
715be168c0dSopenharmony_ci  private:
716be168c0dSopenharmony_ci   bool zero_copy_{false};
717be168c0dSopenharmony_cidiff --git a/mindspore/lite/src/tensor.h b/mindspore/lite/src/tensor.h
718be168c0dSopenharmony_ciindex f2eb4d1a..501e28e5 100644
719be168c0dSopenharmony_ci--- a/mindspore/lite/src/tensor.h
720be168c0dSopenharmony_ci+++ b/mindspore/lite/src/tensor.h
721be168c0dSopenharmony_ci@@ -38,10 +38,12 @@ namespace lite {
722be168c0dSopenharmony_ci #define STATIC_ALLOCATION -271964
723be168c0dSopenharmony_ci #define RUNTIME_REFCOUNT 0x9999
724be168c0dSopenharmony_ci #define OPENCL_ALLOCATOR_REFCOUNT -10000
725be168c0dSopenharmony_ci+#define NNRT_ALLOCATION -10001
726be168c0dSopenharmony_ci #define IS_STATIC_ALLOCATOR(allocator) ((allocator != nullptr) && (allocator->RefCount(nullptr) == STATIC_ALLOCATION))
727be168c0dSopenharmony_ci #define IS_RUNTIME_ALLOCATOR(allocator) ((allocator != nullptr) && (allocator->RefCount(nullptr) == RUNTIME_REFCOUNT))
728be168c0dSopenharmony_ci #define IS_OPENCL_ALLOCATOR(allocator) \
729be168c0dSopenharmony_ci   ((allocator != nullptr) && (allocator->RefCount(nullptr) == OPENCL_ALLOCATOR_REFCOUNT))
730be168c0dSopenharmony_ci+#define IS_NNRT_ALLOCATOR(allocator) ((allocator != nullptr) && (allocator->RefCount(nullptr) == NNRT_ALLOCATION))
731be168c0dSopenharmony_ci 
732be168c0dSopenharmony_ci struct LiteQuantParam {
733be168c0dSopenharmony_ci   double scale;
734be168c0dSopenharmony_ci-- 
735be168c0dSopenharmony_ci2.17.1
736be168c0dSopenharmony_ci
737