• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1From b2e69d2509f71037bf66d0007ebc502fad07bcae Mon Sep 17 00:00:00 2001
2From: chengfeng27 <chengfeng27@huawei.com>
3Date: Fri, 12 Jul 2024 18:37:24 +0800
4Subject: [PATCH] fix npu memory frequently malloc/free
5
6---
7 .../core/mindrt/src/thread/core_affinity.cc   |   2 +-
8 .../core/mindrt/src/thread/threadpool.cc      |   2 +-
9 mindspore/lite/BUILD.gn                       |   1 +
10 mindspore/lite/src/common/context_util.cc     |   3 +-
11 mindspore/lite/src/litert/c_api/context_c.cc  |  11 +-
12 mindspore/lite/src/litert/c_api/tensor_c.cc   |   2 +-
13 .../delegate/nnrt/extension_options_parser.cc |   6 +-
14 .../delegate/nnrt/extension_options_parser.h  |   4 +-
15 .../delegate/nnrt/hiai_foundation_wrapper.cc  |   1 +
16 .../litert/delegate/nnrt/nnrt_allocator.cc    |  61 ++++++++--
17 .../src/litert/delegate/nnrt/nnrt_allocator.h |   4 +
18 .../src/litert/delegate/nnrt/nnrt_delegate.cc |  43 ++++---
19 .../litert/delegate/nnrt/nnrt_model_kernel.cc | 112 +++++++-----------
20 .../litert/delegate/nnrt/nnrt_model_kernel.h  |  15 +--
21 .../src/litert/delegate/nnrt/nnrt_utils.cc    | 110 +++++++++++++++++
22 .../src/litert/delegate/nnrt/nnrt_utils.h     |  29 +++++
23 mindspore/lite/src/litert/infer_manager.cc    |   5 +-
24 mindspore/lite/src/tensor.cc                  |  16 ++-
25 18 files changed, 307 insertions(+), 120 deletions(-)
26 create mode 100644 mindspore/lite/src/litert/delegate/nnrt/nnrt_utils.cc
27 create mode 100644 mindspore/lite/src/litert/delegate/nnrt/nnrt_utils.h
28
29diff --git a/mindspore/core/mindrt/src/thread/core_affinity.cc b/mindspore/core/mindrt/src/thread/core_affinity.cc
30index a3478dff..6886f743 100644
31--- a/mindspore/core/mindrt/src/thread/core_affinity.cc
32+++ b/mindspore/core/mindrt/src/thread/core_affinity.cc
33@@ -349,7 +349,7 @@ int CoreAffinity::SetAffinity(const pthread_t &thread_id, cpu_set_t *cpu_set) {
34   THREAD_INFO("thread: %d, mask: %lu", pthread_gettid_np(thread_id), cpu_set->__bits[0]);
35   int ret = sched_setaffinity(pthread_gettid_np(thread_id), sizeof(cpu_set_t), cpu_set);
36   if (ret != THREAD_OK) {
37-    THREAD_ERROR("bind thread %d to cpu failed. ERROR %{public}d", pthread_gettid_np(thread_id), ret);
38+    THREAD_ERROR("bind thread %d to cpu failed. ERROR %d", pthread_gettid_np(thread_id), ret);
39     return THREAD_ERROR;
40   }
41 #endif
42diff --git a/mindspore/core/mindrt/src/thread/threadpool.cc b/mindspore/core/mindrt/src/thread/threadpool.cc
43index f166a104..e3856c26 100644
44--- a/mindspore/core/mindrt/src/thread/threadpool.cc
45+++ b/mindspore/core/mindrt/src/thread/threadpool.cc
46@@ -72,7 +72,7 @@ void Worker::SetAffinity() {
47   THREAD_INFO("thread: %d, mask: %lu", gettid(), mask_.__bits[0]);
48   int ret = sched_setaffinity(gettid(), sizeof(cpu_set_t), &mask_);
49   if (ret != THREAD_OK) {
50-    THREAD_ERROR("bind thread %d to cpu failed. ERROR %{public}d", gettid(), errno);
51+    THREAD_ERROR("bind thread %d to cpu failed. ERROR %d", gettid(), errno);
52   }
53   return;
54 #else
55diff --git a/mindspore/lite/BUILD.gn b/mindspore/lite/BUILD.gn
56index 124c84c9..acee9733 100644
57--- a/mindspore/lite/BUILD.gn
58+++ b/mindspore/lite/BUILD.gn
59@@ -447,6 +447,7 @@ ohos_shared_library("mindspore_lib") {
60       "src/litert/delegate/nnrt/nnrt_model_kernel.cc",
61       "src/litert/delegate/nnrt/nnrt_allocator.cc",
62       "src/litert/delegate/nnrt/extension_options_parser.cc",
63+      "src/litert/delegate/nnrt/nnrt_utils.cc",
64     ]
65     include_dirs += [
66       "src/delegate/nnrt/include",
67diff --git a/mindspore/lite/src/common/context_util.cc b/mindspore/lite/src/common/context_util.cc
68index 0fa4ebd0..dae3a7cc 100644
69--- a/mindspore/lite/src/common/context_util.cc
70+++ b/mindspore/lite/src/common/context_util.cc
71@@ -185,8 +185,7 @@ bool DeviceTypePriority(const InnerContext *context, int device_type1, int devic
72   if (context == nullptr) {
73     return false;
74   }
75-  std::vector<DeviceContext> device_infos = context->device_list_;
76-  for (DeviceContext device_info : device_infos) {
77+  for (const DeviceContext& device_info : context->device_list_) {
78     if (device_info.device_type_ == device_type1) {
79       return true;
80     }
81diff --git a/mindspore/lite/src/litert/c_api/context_c.cc b/mindspore/lite/src/litert/c_api/context_c.cc
82index 6b6a50d5..2fe3b055 100644
83--- a/mindspore/lite/src/litert/c_api/context_c.cc
84+++ b/mindspore/lite/src/litert/c_api/context_c.cc
85@@ -25,6 +25,10 @@
86 #include "interfaces/kits/c/neural_network_runtime/neural_network_runtime.h"
87 #endif
88
89+namespace {
90+const auto kNpuNamePrefixLen = 4;
91+}
92+
93 // ================ Context ================
94 OH_AI_ContextHandle OH_AI_ContextCreate() {
95   auto impl = new (std::nothrow) mindspore::Context();
96@@ -308,7 +312,6 @@ NNRTDeviceDesc *OH_AI_GetAllNNRTDeviceDescs(size_t *num) {
97   auto ret_load = mindspore::lite::LoadHiaiFLibraryFromPath(&hiai_handle_);
98   if (!ret_load || hiai_handle_ == nullptr) {
99     MS_LOG(ERROR) << "Load HiAI_Foundation so failed.";
100-    return nullptr;
101   }
102 #endif
103   *num = 0;
104@@ -420,7 +423,7 @@ OH_AI_DeviceInfoHandle OH_AI_CreateNNRTDeviceInfoByType(OH_AI_NNRTDeviceType typ
105
106   OH_AI_DeviceInfoHandle handle = nullptr;
107   for (size_t i = 0; i < num; i++) {
108-    if (desc[i].device_type == type) {
109+    if (desc[i].device_type == type && strncmp(desc[i].device_name, "NPU_", kNpuNamePrefixLen) == 0) {
110       handle = OH_AI_DeviceInfoCreate(OH_AI_DEVICETYPE_NNRT);
111       OH_AI_DeviceInfoSetDeviceId(handle, desc[i].device_id);
112       break;
113@@ -514,6 +517,10 @@ OH_AI_API OH_AI_Status OH_AI_DeviceInfoAddExtension(OH_AI_DeviceInfoHandle devic
114     MS_LOG(ERROR) << "device info is null";
115     return OH_AI_STATUS_LITE_NULLPTR;
116   }
117+  if (name == nullptr || value == nullptr || value_size < 0) {
118+    MS_LOG(ERROR) << "name/value/value_size is not valid";
119+    return OH_AI_STATUS_LITE_NULLPTR;
120+  }
121   if (OH_AI_DeviceInfoGetDeviceType(device_info) != OH_AI_DEVICETYPE_NNRT) {
122     MS_LOG(ERROR) << "Add extension to non-NNRT device is not allowable, ignored";
123     return OH_AI_STATUS_LITE_ERROR;
124diff --git a/mindspore/lite/src/litert/c_api/tensor_c.cc b/mindspore/lite/src/litert/c_api/tensor_c.cc
125index fc3814dd..b0eea5cd 100644
126--- a/mindspore/lite/src/litert/c_api/tensor_c.cc
127+++ b/mindspore/lite/src/litert/c_api/tensor_c.cc
128@@ -231,7 +231,7 @@ OH_AI_Status OH_AI_TensorSetAllocator(OH_AI_TensorHandle tensor, void *allocator
129   return OH_AI_STATUS_SUCCESS;
130 }
131
132-void *OH_AI_TensorGetAllocator(const OH_AI_TensorHandle tensor) {
133+void *OH_AI_TensorGetAllocator(OH_AI_TensorHandle tensor) {
134   if (tensor == nullptr) {
135     MS_LOG(ERROR) << "param is nullptr.";
136     return nullptr;
137diff --git a/mindspore/lite/src/litert/delegate/nnrt/extension_options_parser.cc b/mindspore/lite/src/litert/delegate/nnrt/extension_options_parser.cc
138index 98343898..e35cc2a5 100644
139--- a/mindspore/lite/src/litert/delegate/nnrt/extension_options_parser.cc
140+++ b/mindspore/lite/src/litert/delegate/nnrt/extension_options_parser.cc
141@@ -38,7 +38,7 @@ int ExtensionOptionsParser::Parse(const std::vector<Extension> &extensions, Exte
142   DoParseCachePath(extensions, &param->cache_path_);
143   DoParseCacheVersion(extensions, &param->cache_version_);
144   DoParseBondMode(extensions, &param->band_mode);
145-  DoParseQuantConfig(extensions, &param->quant_config, &param->quant_config_size);
146+  DoParseQuantConfig(extensions, &param->quant_config, &param->quant_config_size, &param->is_optional_quant_setted);
147   return RET_OK;
148 }
149
150@@ -76,7 +76,8 @@ void ExtensionOptionsParser::DoParseBondMode(const std::vector<Extension> &exten
151   }
152 }
153
154-void ExtensionOptionsParser::DoParseQuantConfig(const std::vector<Extension> &extensions, void **quant_config, size_t *num) {
155+void ExtensionOptionsParser::DoParseQuantConfig(const std::vector<Extension> &extensions,
156+                                                void **quant_config, size_t *num, bool *quant_setted) {
157   MS_CHECK_TRUE_RET_VOID(quant_config != nullptr);
158   MS_CHECK_TRUE_RET_VOID(num != nullptr);
159   auto iter_config = std::find_if(extensions.begin(), extensions.end(), [](const Extension &extension) {
160@@ -85,6 +86,7 @@ void ExtensionOptionsParser::DoParseQuantConfig(const std::vector<Extension> &ex
161   if (iter_config != extensions.end()) {
162     *quant_config = static_cast<void *>(const_cast<uint8_t *>(iter_config->value.data()));
163     *num = iter_config->value.size();
164+    *quant_setted = true;
165   }
166 }
167 }  // mindspore::lite::nnrt
168\ No newline at end of file
169diff --git a/mindspore/lite/src/litert/delegate/nnrt/extension_options_parser.h b/mindspore/lite/src/litert/delegate/nnrt/extension_options_parser.h
170index 792805a4..f24682ce 100644
171--- a/mindspore/lite/src/litert/delegate/nnrt/extension_options_parser.h
172+++ b/mindspore/lite/src/litert/delegate/nnrt/extension_options_parser.h
173@@ -28,6 +28,7 @@ struct ExtensionOptions {
174   mindspore::lite::HiAI_BandMode band_mode{HIAI_BANDMODE_UNSET};
175   void *quant_config;
176   size_t quant_config_size = 0;
177+  bool is_optional_quant_setted = false;
178 };
179
180 class ExtensionOptionsParser {
181@@ -36,7 +37,8 @@ public:
182
183 private:
184   static void DoParseBondMode(const std::vector<Extension> &extensions, mindspore::lite::HiAI_BandMode *band_mode);
185-  static void DoParseQuantConfig(const std::vector<Extension> &extensions, void **quant_config, size_t *num);
186+  static void DoParseQuantConfig(const std::vector<Extension> &extensions, void **quant_config, size_t *num,
187+                                 bool *quant_setted);
188   static void DoParseCachePath(const std::vector<Extension> &extensions, std::string *cache_path);
189   static void DoParseCacheVersion(const std::vector<Extension> &extensions, uint32_t *cache_version);
190 };
191diff --git a/mindspore/lite/src/litert/delegate/nnrt/hiai_foundation_wrapper.cc b/mindspore/lite/src/litert/delegate/nnrt/hiai_foundation_wrapper.cc
192index e7a52827..a155b761 100644
193--- a/mindspore/lite/src/litert/delegate/nnrt/hiai_foundation_wrapper.cc
194+++ b/mindspore/lite/src/litert/delegate/nnrt/hiai_foundation_wrapper.cc
195@@ -39,6 +39,7 @@ bool LoadHiaiFLibraryFromPath(void **handle_ptr) {
196
197   *handle_ptr = dlopen(HIAI_F_LIB, RTLD_NOW | RTLD_LOCAL);
198   if (*handle_ptr == nullptr) {
199+    MS_LOG(WARNING) << "dlopen failed, error: " << dlerror();
200     return false;
201   }
202
203diff --git a/mindspore/lite/src/litert/delegate/nnrt/nnrt_allocator.cc b/mindspore/lite/src/litert/delegate/nnrt/nnrt_allocator.cc
204index b38fff62..4910343f 100644
205--- a/mindspore/lite/src/litert/delegate/nnrt/nnrt_allocator.cc
206+++ b/mindspore/lite/src/litert/delegate/nnrt/nnrt_allocator.cc
207@@ -20,6 +20,7 @@
208 #include <map>
209 #include <mutex>
210 #include "src/litert/delegate/nnrt/nnrt_allocator.h"
211+#include "src/litert/delegate/nnrt/nnrt_utils.h"
212 #include "src/common/log.h"
213
214 namespace mindspore {
215@@ -43,7 +44,42 @@ NNRTAllocator::~NNRTAllocator() {
216   free_list_.clear();
217 }
218
219-void *NNRTAllocator::Malloc(size_t size) {
220+NN_TensorDesc *NNRTAllocator::CreateNNRtTensorDesc(const std::vector<int> &shape, const TypeId data_type,
221+                                                   const Format format, const std::string &name) {
222+  auto tensor_desc = OH_NNTensorDesc_Create();
223+  if (tensor_desc == nullptr) {
224+    MS_LOG(ERROR) << "OH_NNTensorDesc_Create failed, i = " << index_;
225+    return nullptr;
226+  }
227+  OH_NN_ReturnCode ret = OH_NNTensorDesc_SetShape(tensor_desc, shape.data(), shape.size());
228+  if (ret != OH_NN_SUCCESS) {
229+    MS_LOG(ERROR) << "OH_NNTensorDesc_SetShape failed, i = " << index_ << ", shape: " << shape;
230+    OH_NNTensorDesc_Destroy(&tensor_desc);
231+    return nullptr;
232+  }
233+  ret = OH_NNTensorDesc_SetDataType(tensor_desc, CastToNNRtDataType(data_type));
234+  if (ret != OH_NN_SUCCESS) {
235+    MS_LOG(ERROR) << "OH_NNTensorDesc_SetDataType failed, i = " << index_ << ", data_type: " << data_type;
236+    OH_NNTensorDesc_Destroy(&tensor_desc);
237+    return nullptr;
238+  }
239+  ret = OH_NNTensorDesc_SetFormat(tensor_desc, CastToNNRtFormat(format));
240+  if (ret != OH_NN_SUCCESS) {
241+    MS_LOG(ERROR) << "OH_NNTensorDesc_SetFormat failed, i = " << index_ << ", format: " << format;
242+    OH_NNTensorDesc_Destroy(&tensor_desc);
243+    return nullptr;
244+  }
245+  ret = OH_NNTensorDesc_SetName(tensor_desc, name.c_str());
246+  if (ret != OH_NN_SUCCESS) {
247+    MS_LOG(ERROR) << "OH_NNTensorDesc_SetName failed, i = " << index_ << ", name: " << name;
248+    OH_NNTensorDesc_Destroy(&tensor_desc);
249+    return nullptr;
250+  }
251+  return tensor_desc;
252+}
253+
254+void *NNRTAllocator::MallocByDesc(size_t size, const std::vector<int> &shape, const TypeId data_type,
255+                                  const Format format, const std::string &name) {
256   std::lock_guard<std::mutex> locker(mutex_);
257   auto iter = free_list_.lower_bound(size);
258   if (iter != free_list_.end()) {
259@@ -60,17 +96,13 @@ void *NNRTAllocator::Malloc(size_t size) {
260     return nullptr;
261   }
262   membuf->ref_count_ = 0;
263-  if (memory_category_ == NNRT_INPUT) {
264-    membuf->tensor_desc_ = OH_NNExecutor_CreateInputTensorDesc(executor_, index_);
265-  } else {
266-    membuf->tensor_desc_ = OH_NNExecutor_CreateOutputTensorDesc(executor_, index_);
267-  }
268+  membuf->tensor_desc_ = CreateNNRtTensorDesc(shape, data_type, format, name);
269   if (membuf->tensor_desc_ == nullptr) {
270-    MS_LOG(ERROR) << "OH_NNExecutor_CreateInput/OutputTensorDesc failed, i = " << index_;
271+    MS_LOG(ERROR) << "create NN_TensorDesc failed.";
272     delete membuf;
273     return nullptr;
274   }
275-  membuf->tensor_ = OH_NNTensor_CreateWithSize(device_id_, membuf->tensor_desc_, size);
276+  membuf->tensor_ = OH_NNTensor_Create(device_id_, membuf->tensor_desc_);
277   if (membuf->tensor_ == nullptr) {
278     MS_LOG(ERROR) << "OH_NNTensor_CreateWithSize failed, i = " << index_;
279     OH_NNTensorDesc_Destroy(&membuf->tensor_desc_);
280@@ -91,6 +123,11 @@ void *NNRTAllocator::Malloc(size_t size) {
281   return membuf->data;
282 }
283
284+void *NNRTAllocator::Malloc(size_t size) {
285+  MS_LOG(ERROR) << "NNRt Allocator is not support malloc by size.";
286+  return nullptr;
287+}
288+
289 void NNRTAllocator::Free(void *ptr) {
290   if (ptr == nullptr) {
291     return;
292@@ -143,8 +180,8 @@ int NNRTAllocator::DecRefCount(void *ptr, int ref_count) {
293   auto iter = allocated_list_.find(ptr);
294   if (iter != allocated_list_.end()) {
295     auto membuf = iter->second;
296-    auto ref = std::atomic_fetch_sub(&membuf->ref_count_, ref_count);
297-    return ref;
298+    std::atomic_fetch_sub(&membuf->ref_count_, ref_count);
299+    return membuf->ref_count_;
300   }
301   return -1;
302 }
303@@ -157,8 +194,8 @@ int NNRTAllocator::IncRefCount(void *ptr, int ref_count) {
304   auto iter = allocated_list_.find(ptr);
305   if (iter != allocated_list_.end()) {
306     auto membuf = iter->second;
307-    auto ref = std::atomic_fetch_add(&membuf->ref_count_, ref_count);
308-    return ref;
309+    std::atomic_fetch_add(&membuf->ref_count_, ref_count);
310+    return membuf->ref_count_;
311   }
312   return -1;
313 }
314diff --git a/mindspore/lite/src/litert/delegate/nnrt/nnrt_allocator.h b/mindspore/lite/src/litert/delegate/nnrt/nnrt_allocator.h
315index 52e6def7..ef27f307 100644
316--- a/mindspore/lite/src/litert/delegate/nnrt/nnrt_allocator.h
317+++ b/mindspore/lite/src/litert/delegate/nnrt/nnrt_allocator.h
318@@ -40,6 +40,10 @@ class NNRTAllocator : public Allocator {
319   ~NNRTAllocator() override;
320
321   void *Malloc(size_t size) override;
322+  void *MallocByDesc(size_t size, const std::vector<int> &shape, const TypeId data_type, const Format format,
323+                     const std::string &name);
324+  NN_TensorDesc *CreateNNRtTensorDesc(const std::vector<int> &shape, const TypeId data_type, const Format format,
325+                                      const std::string &name);
326   void Free(void *ptr) override;
327   int RefCount(void *ptr) override;
328   int SetRefCount(void *ptr, int ref_count) override;
329diff --git a/mindspore/lite/src/litert/delegate/nnrt/nnrt_delegate.cc b/mindspore/lite/src/litert/delegate/nnrt/nnrt_delegate.cc
330index 17abd0ed..a49e7449 100644
331--- a/mindspore/lite/src/litert/delegate/nnrt/nnrt_delegate.cc
332+++ b/mindspore/lite/src/litert/delegate/nnrt/nnrt_delegate.cc
333@@ -33,8 +33,7 @@ Status NNRTDelegate::Init() {
334 #ifdef SUPPORT_NNRT_METAGRAPH
335   auto ret = mindspore::lite::LoadHiaiFLibraryFromPath(&hiai_handle_);
336   if (!ret || hiai_handle_ == nullptr) {
337-    MS_LOG(ERROR) << "Load HiAI_Foundation so failed.";
338-    return kLiteError;
339+    MS_LOG(WARNING) << "Load HiAI_Foundation so failed.";
340   }
341 #endif
342   return kSuccess;
343@@ -194,7 +193,7 @@ Status NNRTDelegate::BuildOfflineModel(DelegateModel<schema::Primitive> *model)
344   }
345   OH_NNCompilation_Destroy(&nn_compilation);
346
347-  auto nnrt_model_kernel = new (std::nothrow) NNRTModelKernel(nn_executor, nnrt_device_info_.device_id_, model->inputs(), model->outputs());
348+  auto nnrt_model_kernel = new (std::nothrow) NNRTModelKernel(nn_executor, nnrt_device_info_, model->inputs(), model->outputs());
349   if (nnrt_model_kernel == nullptr) {
350     OH_NNExecutor_Destroy(&nn_executor);
351     MS_LOG(ERROR) << "new NNRTModelKernel failed";
352@@ -233,7 +232,7 @@ Status NNRTDelegate::CreateFullModelKernel(DelegateModel<schema::Primitive> *mod
353   }
354   OH_NNCompilation_Destroy(&nn_compilation);
355
356-  auto nnrt_model_kernel = new (std::nothrow)NNRTModelKernel(nn_executor, nnrt_device_info_.device_id_, model->inputs(), model->outputs());
357+  auto nnrt_model_kernel = new (std::nothrow) NNRTModelKernel(nn_executor, nnrt_device_info_, model->inputs(), model->outputs());
358   if (nnrt_model_kernel == nullptr) {
359     OH_NNExecutor_Destroy(&nn_executor);
360     MS_LOG(ERROR) << "new NNRTModelKernel failed";
361@@ -547,20 +546,30 @@ Status NNRTDelegate::InitNNCompilation(OH_NNCompilation *nn_compilation) const {
362   }
363
364 #ifdef SUPPORT_NNRT_METAGRAPH
365-  ret_code = mindspore::lite::HMS_HiAIOptions_SetBandMode(nn_compilation, extension_options_.band_mode);
366-  if ((ret_code != OH_NN_SUCCESS) && (ret_code != OH_NN_OPERATION_FORBIDDEN)) {
367-    MS_LOG(ERROR) << "NNCompilation set BandMode failed, ret: " << ret_code;
368-    return kLiteError;
369-  }
370+  if (hiai_handle_ != nullptr) {
371+    if (extension_options_.band_mode != mindspore::lite::HIAI_BANDMODE_UNSET) {
372+      ret_code = mindspore::lite::HMS_HiAIOptions_SetBandMode(nn_compilation, extension_options_.band_mode);
373+      if ((ret_code != OH_NN_SUCCESS) && (ret_code != OH_NN_OPERATION_FORBIDDEN)) {
374+        MS_LOG(ERROR) << "NNCompilation set BandMode failed, ret: " << ret_code;
375+        return kLiteError;
376+      }
377+    }
378
379-  if (extension_options_.quant_config != nullptr && extension_options_.quant_config_size != 0) {
380-    ret_code = mindspore::lite::HMS_HiAIOptions_SetQuantConfig(nn_compilation,
381-                                                                      extension_options_.quant_config,
382-                                                                      extension_options_.quant_config_size);
383-    if ((ret_code != OH_NN_SUCCESS) && (ret_code != OH_NN_OPERATION_FORBIDDEN)) {
384-      MS_LOG(ERROR) << "NNCompilation set QuantConfig failed, ret: " << ret_code;
385-      return kLiteError;
386+    if (extension_options_.is_optional_quant_setted) {
387+      if (extension_options_.quant_config == nullptr || extension_options_.quant_config_size <= 0) {
388+        MS_LOG(ERROR) << "NNCompilation set QuantConfig faild, input quant config is invalid, please make sure buffer "
389+                      << "is not null and size > 0.";
390+        return kLiteError;
391+      }
392+      ret_code = mindspore::lite::HMS_HiAIOptions_SetQuantConfig(nn_compilation, extension_options_.quant_config,
393+                                                                 extension_options_.quant_config_size);
394+      if ((ret_code != OH_NN_SUCCESS) && (ret_code != OH_NN_OPERATION_FORBIDDEN)) {
395+        MS_LOG(ERROR) << "NNCompilation set QuantConfig failed, ret: " << ret_code;
396+        return kLiteError;
397+      }
398     }
399+  } else {
400+    MS_LOG(WARNING) << "hiai_foundation is nullptr.";
401   }
402 #endif
403
404@@ -664,7 +673,7 @@ Status NNRTDelegate::CreateNNRTSubgraphKernels(DelegateModel<schema::Primitive>
405       continue ;
406     }
407
408-    auto nnrt_model_kernel = new (std::nothrow)NNRTModelKernel(nn_executor, nnrt_device_info_.device_id_, in_tensors, out_tensors);
409+    auto nnrt_model_kernel = new (std::nothrow) NNRTModelKernel(nn_executor, nnrt_device_info_, in_tensors, out_tensors);
410     if (nnrt_model_kernel == nullptr) {
411       MS_LOG(ERROR) << "new NNRTModelKernel failed";
412       return kLiteError;
413diff --git a/mindspore/lite/src/litert/delegate/nnrt/nnrt_model_kernel.cc b/mindspore/lite/src/litert/delegate/nnrt/nnrt_model_kernel.cc
414index 2a66d133..1411020b 100644
415--- a/mindspore/lite/src/litert/delegate/nnrt/nnrt_model_kernel.cc
416+++ b/mindspore/lite/src/litert/delegate/nnrt/nnrt_model_kernel.cc
417@@ -17,9 +17,15 @@
418 #include "nnrt_model_kernel.h"
419 #include "nnrt_allocator.h"
420 #include "litert/cxx_api/tensor/tensor_impl.h"
421-int mindspore::NNRTModelKernel::Prepare() {
422+
423+namespace mindspore{
424+namespace {
425+constexpr auto kDynamicDims = "DynamicDims";
426+}
427+
428+int NNRTModelKernel::Prepare() {
429   for (size_t i = 0; i < inputs_.size(); i++) {
430-    auto nnrt_allocator = std::make_shared<lite::NNRTAllocator>(oh_nn_executor, i, device_id_, lite::NNRT_INPUT);
431+    auto nnrt_allocator = std::make_shared<lite::NNRTAllocator>(oh_nn_executor_, i, nnrt_device_info_.device_id_, lite::NNRT_INPUT);
432     if (nnrt_allocator == nullptr) {
433       MS_LOG(ERROR) << "Create NNRTAllocator failed";
434       return lite::RET_NULL_PTR;
435@@ -27,7 +33,7 @@ int mindspore::NNRTModelKernel::Prepare() {
436     inputs_[i].SetAllocator(nnrt_allocator);
437   }
438   for (size_t i = 0; i < outputs_.size(); i++) {
439-    auto nnrt_allocator = std::make_shared<lite::NNRTAllocator>(oh_nn_executor, i, device_id_, lite::NNRT_OUTPUT);
440+    auto nnrt_allocator = std::make_shared<lite::NNRTAllocator>(oh_nn_executor_, i, nnrt_device_info_.device_id_, lite::NNRT_OUTPUT);
441     if (nnrt_allocator == nullptr) {
442       MS_LOG(ERROR) << "Create NNRTAllocator failed";
443       return lite::RET_NULL_PTR;
444@@ -37,7 +43,19 @@ int mindspore::NNRTModelKernel::Prepare() {
445   return lite::RET_OK;
446 }
447
448-int mindspore::NNRTModelKernel::Execute() {
449+int NNRTModelKernel::ReSize() {
450+  const auto &extensions = nnrt_device_info_.extensions_;
451+  auto iter = std::find_if(extensions.begin(), extensions.end(), [](const lite::Extension &extension) {
452+    return extension.name == kDynamicDims;
453+  });
454+  if (iter != extensions.end() && !iter->value.empty()) {
455+    return lite::RET_OK;
456+  }
457+  MS_LOG(ERROR) << "NNRT only support the resize function when DynamicDims is enabled.";
458+  return lite::RET_ERROR;
459+}
460+
461+int NNRTModelKernel::Execute() {
462   MS_CHECK_TRUE_RET(this->outputs().empty() != true, lite::RET_ERROR);
463   zero_copy_ = IS_NNRT_ALLOCATOR(this->outputs()[Index0].allocator());
464
465@@ -61,7 +79,7 @@ int mindspore::NNRTModelKernel::Execute() {
466   }
467   MS_LOG(INFO) << "Running NNRtModel Kernel...";
468   OH_NN_ReturnCode ret_code;
469-  ret_code = OH_NNExecutor_RunSync(oh_nn_executor, nn_input_tensors_.data(), nn_input_tensors_.size(),
470+  ret_code = OH_NNExecutor_RunSync(oh_nn_executor_, nn_input_tensors_.data(), nn_input_tensors_.size(),
471                                    nn_output_tensors_.data(), nn_output_tensors_.size());
472
473   if (ret_code != OH_NN_SUCCESS) {
474@@ -73,67 +91,11 @@ int mindspore::NNRTModelKernel::Execute() {
475   return lite::RET_OK;
476 }
477
478-OH_NN_DataType mindspore::NNRTModelKernel::ConvertDataType(mindspore::DataType data_type) {
479-  OH_NN_DataType oh_data_type;
480-  switch (data_type) {
481-    case DataType::kTypeUnknown:
482-    case DataType::kObjectTypeString:
483-    case DataType::kObjectTypeList:
484-    case DataType::kObjectTypeTuple:
485-    case DataType::kObjectTypeTensorType:
486-    case DataType::kNumberTypeBegin:
487-    case DataType::kNumberTypeEnd:
488-    case DataType::kInvalidType:
489-      oh_data_type = OH_NN_UNKNOWN;
490-      break;
491-    case DataType::kNumberTypeBool:
492-      oh_data_type = OH_NN_BOOL;
493-      break;
494-    case DataType::kNumberTypeInt8:
495-      oh_data_type = OH_NN_INT8;
496-      break;
497-    case DataType::kNumberTypeInt16:
498-      oh_data_type = OH_NN_INT16;
499-      break;
500-    case DataType::kNumberTypeInt32:
501-      oh_data_type = OH_NN_INT32;
502-      break;
503-    case DataType::kNumberTypeInt64:
504-      oh_data_type = OH_NN_INT64;
505-      break;
506-    case DataType::kNumberTypeUInt8:
507-      oh_data_type = OH_NN_UINT8;
508-      break;
509-    case DataType::kNumberTypeUInt16:
510-      oh_data_type = OH_NN_UINT16;
511-      break;
512-    case DataType::kNumberTypeUInt32:
513-      oh_data_type = OH_NN_UINT32;
514-      break;
515-    case DataType::kNumberTypeUInt64:
516-      oh_data_type = OH_NN_UINT64;
517-      break;
518-    case DataType::kNumberTypeFloat16:
519-      oh_data_type = OH_NN_FLOAT16;
520-      break;
521-    case DataType::kNumberTypeFloat32:
522-      oh_data_type = OH_NN_FLOAT32;
523-      break;
524-    case DataType::kNumberTypeFloat64:
525-      oh_data_type = OH_NN_FLOAT64;
526-      break;
527-    default: {
528-      oh_data_type = OH_NN_UNKNOWN;
529-    }
530-  }
531-  return oh_data_type;
532-}
533-
534-int mindspore::NNRTModelKernel::SetInputs() {
535+int NNRTModelKernel::SetInputs() {
536   if (!zero_copy_) {
537     OH_NN_ReturnCode ret{OH_NN_FAILED};
538     size_t nn_input_count = 0;
539-    ret = OH_NNExecutor_GetInputCount(oh_nn_executor, &nn_input_count);
540+    ret = OH_NNExecutor_GetInputCount(oh_nn_executor_, &nn_input_count);
541     if (ret != OH_NN_SUCCESS) {
542       MS_LOG(ERROR) << "OH_NNExecutor_GetInputCount failed.";
543       return lite::RET_ERROR;
544@@ -143,13 +105,13 @@ int mindspore::NNRTModelKernel::SetInputs() {
545       return lite::RET_ERROR;
546     }
547     for (size_t i = 0; i < nn_input_count; i++) {
548-      NN_TensorDesc *tensor_desc_tmp = OH_NNExecutor_CreateInputTensorDesc(oh_nn_executor, i);
549+      NN_TensorDesc *tensor_desc_tmp = OH_NNExecutor_CreateInputTensorDesc(oh_nn_executor_, i);
550       if (tensor_desc_tmp == nullptr) {
551         MS_LOG(ERROR) << "OH_NNExecutor_CreateInputTensorDesc failed, i = " << i;
552         return lite::RET_ERROR;
553       }
554       nn_input_tensor_descs_.emplace_back(tensor_desc_tmp);
555-      NN_Tensor *tensor_tmp = OH_NNTensor_Create(device_id_, tensor_desc_tmp);
556+      NN_Tensor *tensor_tmp = OH_NNTensor_Create(nnrt_device_info_.device_id_, tensor_desc_tmp);
557       if (tensor_tmp == nullptr) {
558         MS_LOG(ERROR) << "OH_NNTensor_Create input failed, i = " << i;
559         return lite::RET_ERROR;
560@@ -166,6 +128,10 @@ int mindspore::NNRTModelKernel::SetInputs() {
561     }
562   } else {
563     for (size_t i = 0; i < inputs_.size(); i++) {
564+      if (inputs_[i].allocator() == nullptr) {
565+        MS_LOG(ERROR) << "NNRTAllocator is nullptr, i = " << i;
566+        return lite::RET_ERROR;
567+      }
568       void *data = inputs_[i].MutableData();
569       NN_Tensor *tensor_tmp = reinterpret_cast<lite::NNRTAllocator *>(inputs_[i].allocator().get())->GetNNTensor(data);
570       if (tensor_tmp == nullptr) {
571@@ -178,11 +144,11 @@ int mindspore::NNRTModelKernel::SetInputs() {
572   return lite::RET_OK;
573 }
574
575-int mindspore::NNRTModelKernel::SetOutputs() {
576+int NNRTModelKernel::SetOutputs() {
577   if (!zero_copy_) {
578     OH_NN_ReturnCode ret{OH_NN_FAILED};
579     size_t nn_output_count = 0;
580-    ret = OH_NNExecutor_GetOutputCount(oh_nn_executor, &nn_output_count);
581+    ret = OH_NNExecutor_GetOutputCount(oh_nn_executor_, &nn_output_count);
582     if (ret != OH_NN_SUCCESS) {
583       MS_LOG(ERROR) << "OH_NNExecutor_GetOutputCount failed.";
584       return lite::RET_ERROR;
585@@ -192,13 +158,13 @@ int mindspore::NNRTModelKernel::SetOutputs() {
586       return lite::RET_ERROR;
587     }
588     for (size_t i = 0; i < nn_output_count; i++) {
589-      NN_TensorDesc *tensor_desc_tmp = OH_NNExecutor_CreateOutputTensorDesc(oh_nn_executor, i);
590+      NN_TensorDesc *tensor_desc_tmp = OH_NNExecutor_CreateOutputTensorDesc(oh_nn_executor_, i);
591       if (tensor_desc_tmp == nullptr) {
592         MS_LOG(ERROR) << "OH_NNExecutor_CreateOutputTensorDesc failed, i = " << i;
593         return lite::RET_ERROR;
594       }
595       nn_output_tensor_descs_.emplace_back(tensor_desc_tmp);
596-      NN_Tensor *tensor_tmp = OH_NNTensor_Create(device_id_, tensor_desc_tmp);
597+      NN_Tensor *tensor_tmp = OH_NNTensor_Create(nnrt_device_info_.device_id_, tensor_desc_tmp);
598       if (tensor_tmp == nullptr) {
599         MS_LOG(ERROR) << "OH_NNTensor_Create output failed, i = " << i;
600         return lite::RET_ERROR;
601@@ -210,6 +176,10 @@ int mindspore::NNRTModelKernel::SetOutputs() {
602     }
603   } else {
604     for (size_t i = 0; i < outputs_.size(); i++) {
605+      if (outputs_[i].allocator() == nullptr) {
606+        MS_LOG(ERROR) << "NNRTAllocator is nullptr, i = " << i;
607+        return lite::RET_ERROR;
608+      }
609       void *data = outputs_[i].MutableData();
610       NN_Tensor *tensor_tmp = reinterpret_cast<lite::NNRTAllocator *>(outputs_[i].allocator().get())->GetNNTensor(data);
611       if (tensor_tmp == nullptr) {
612@@ -222,7 +192,7 @@ int mindspore::NNRTModelKernel::SetOutputs() {
613   return lite::RET_OK;
614 }
615
616-void mindspore::NNRTModelKernel::FreeNNTensor() {
617+void NNRTModelKernel::FreeNNTensor() {
618   for (size_t i = 0; i < nn_input_tensors_.size(); i++) {
619     OH_NNTensor_Destroy(&nn_input_tensors_[i]);
620     OH_NNTensorDesc_Destroy(&nn_input_tensor_descs_[i]);
621@@ -232,3 +202,5 @@ void mindspore::NNRTModelKernel::FreeNNTensor() {
622     OH_NNTensorDesc_Destroy(&nn_output_tensor_descs_[i]);
623   }
624 }
625+
626+}  // namespace mindspore
627diff --git a/mindspore/lite/src/litert/delegate/nnrt/nnrt_model_kernel.h b/mindspore/lite/src/litert/delegate/nnrt/nnrt_model_kernel.h
628index 40800a2a..7590d036 100644
629--- a/mindspore/lite/src/litert/delegate/nnrt/nnrt_model_kernel.h
630+++ b/mindspore/lite/src/litert/delegate/nnrt/nnrt_model_kernel.h
631@@ -22,6 +22,7 @@
632 #include "include/api/kernel.h"
633 #include "interfaces/kits/c/neural_network_runtime/neural_network_runtime.h"
634 #include "src/common/log_adapter.h"
635+#include "src/litert/inner_context.h"
636 #include "include/errorcode.h"
637
638 namespace mindspore {
639@@ -31,16 +32,12 @@ class NNRTModelKernel : public kernel::Kernel {
640    * Because nnr can't run single op, but the whole model. So we decide to make the whole model into one kernel.
641    * */
642  public:
643-  NNRTModelKernel(OH_NNExecutor *oh_nn_executor, size_t device_id, const std::vector<mindspore::MSTensor> &inputs,
644+  NNRTModelKernel(OH_NNExecutor *oh_nn_executor, lite::NNRtDeviceInfo nnrt_device_info, const std::vector<mindspore::MSTensor> &inputs,
645                   const std::vector<mindspore::MSTensor> &outputs)
646-      : kernel::Kernel(inputs, outputs, nullptr, nullptr), device_id_(device_id), oh_nn_executor(oh_nn_executor) {}
647+      : kernel::Kernel(inputs, outputs, nullptr, nullptr), oh_nn_executor_(oh_nn_executor), nnrt_device_info_(nnrt_device_info) {}
648   int Prepare() override;
649   int Execute() override;
650-  int ReSize() override {
651-    MS_LOG(ERROR) << "NNRT does not support the resize function temporarily.";
652-    return lite::RET_ERROR;
653-  };
654-  OH_NN_DataType ConvertDataType(mindspore::DataType data_type);
655+  int ReSize() override;
656   int SetInputs();
657   int SetOutputs();
658   void FreeNNTensor();
659@@ -52,8 +49,8 @@ class NNRTModelKernel : public kernel::Kernel {
660   }
661
662  protected:
663-  size_t device_id_;
664-  OH_NNExecutor *oh_nn_executor = nullptr;
665+  OH_NNExecutor *oh_nn_executor_ = nullptr;
666+  lite::NNRtDeviceInfo nnrt_device_info_;
667   std::vector<NN_Tensor *> nn_input_tensors_;
668   std::vector<NN_TensorDesc *> nn_input_tensor_descs_;
669   std::vector<NN_Tensor *> nn_output_tensors_;
670diff --git a/mindspore/lite/src/litert/delegate/nnrt/nnrt_utils.cc b/mindspore/lite/src/litert/delegate/nnrt/nnrt_utils.cc
671new file mode 100644
672index 00000000..049857bb
673--- /dev/null
674+++ b/mindspore/lite/src/litert/delegate/nnrt/nnrt_utils.cc
675@@ -0,0 +1,110 @@
676+/**
677+ * Copyright 2024 Huawei Technologies Co., Ltd
678+ *
679+ * Licensed under the Apache License, Version 2.0 (the "License");
680+ * you may not use this file except in compliance with the License.
681+ * You may obtain a copy of the License at
682+ *
683+ * http://www.apache.org/licenses/LICENSE-2.0
684+ *
685+ * Unless required by applicable law or agreed to in writing, software
686+ * distributed under the License is distributed on an "AS IS" BASIS,
687+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
688+ * See the License for the specific language governing permissions and
689+ * limitations under the License.
690+ */
691+
692+#include "src/litert/delegate/nnrt/nnrt_utils.h"
693+#include <unordered_map>
694+
695+namespace mindspore::lite {
696+OH_NN_Format CastToNNRtFormat(Format format) {
697+  const std::unordered_map<Format, OH_NN_Format> kFormatMap = {
698+    {Format::NCHW, OH_NN_FORMAT_NCHW},
699+    {Format::NHWC, OH_NN_FORMAT_NHWC},
700+  };
701+  auto iter = kFormatMap.find(format);
702+  if (iter == kFormatMap.end()) {
703+    return OH_NN_FORMAT_NONE;
704+  }
705+  return iter->second;
706+}
707+
708+OH_NN_DataType CastToNNRtDataType(TypeId data_type) {
709+  OH_NN_DataType oh_data_type;
710+  switch (data_type) {
711+    case TypeId::kMetaTypeBegin:
712+    case TypeId::kMetaTypeType:
713+    case TypeId::kMetaTypeAny:
714+    case TypeId::kMetaTypeObject:
715+    case TypeId::kMetaTypeTypeType:
716+    case TypeId::kMetaTypeProblem:
717+    case TypeId::kMetaTypeExternal:
718+    case TypeId::kMetaTypeNone:
719+    case TypeId::kMetaTypeNull:
720+    case TypeId::kMetaTypeEllipsis:
721+    case TypeId::kMetaTypeEnd:
722+    case TypeId::kObjectTypeNumber:
723+    case TypeId::kObjectTypeString:
724+    case TypeId::kObjectTypeList:
725+    case TypeId::kObjectTypeTuple:
726+    case TypeId::kObjectTypeSlice:
727+    case TypeId::kObjectTypeKeyword:
728+    case TypeId::kObjectTypeTensorType:
729+    case TypeId::kObjectTypeRowTensorType:
730+    case TypeId::kObjectTypeCOOTensorType:
731+    case TypeId::kObjectTypeUndeterminedType:
732+    case TypeId::kObjectTypeClass:
733+    case TypeId::kObjectTypeDictionary:
734+    case TypeId::kObjectTypeFunction:
735+    case TypeId::kObjectTypeJTagged:
736+    case TypeId::kObjectTypeSymbolicKeyType:
737+    case TypeId::kObjectTypeEnvType:
738+    case TypeId::kObjectTypeRefKey:
739+    case TypeId::kObjectTypeRef:
740+    case TypeId::kObjectTypeEnd:
741+      oh_data_type = OH_NN_UNKNOWN;
742+      break;
743+    case TypeId::kNumberTypeBool:
744+      oh_data_type = OH_NN_BOOL;
745+      break;
746+    case TypeId::kNumberTypeInt8:
747+      oh_data_type = OH_NN_INT8;
748+      break;
749+    case TypeId::kNumberTypeInt16:
750+      oh_data_type = OH_NN_INT16;
751+      break;
752+    case TypeId::kNumberTypeInt32:
753+      oh_data_type = OH_NN_INT32;
754+      break;
755+    case TypeId::kNumberTypeInt64:
756+      oh_data_type = OH_NN_INT64;
757+      break;
758+    case TypeId::kNumberTypeUInt8:
759+      oh_data_type = OH_NN_UINT8;
760+      break;
761+    case TypeId::kNumberTypeUInt16:
762+      oh_data_type = OH_NN_UINT16;
763+      break;
764+    case TypeId::kNumberTypeUInt32:
765+      oh_data_type = OH_NN_UINT32;
766+      break;
767+    case TypeId::kNumberTypeUInt64:
768+      oh_data_type = OH_NN_UINT64;
769+      break;
770+    case TypeId::kNumberTypeFloat16:
771+      oh_data_type = OH_NN_FLOAT16;
772+      break;
773+    case TypeId::kNumberTypeFloat32:
774+      oh_data_type = OH_NN_FLOAT32;
775+      break;
776+    case TypeId::kNumberTypeFloat64:
777+      oh_data_type = OH_NN_FLOAT64;
778+      break;
779+    default: {
780+      oh_data_type = OH_NN_UNKNOWN;
781+    }
782+  }
783+  return oh_data_type;
784+}
785+}  // namespace mindspore::lite
786diff --git a/mindspore/lite/src/litert/delegate/nnrt/nnrt_utils.h b/mindspore/lite/src/litert/delegate/nnrt/nnrt_utils.h
787new file mode 100644
788index 00000000..f8055686
789--- /dev/null
790+++ b/mindspore/lite/src/litert/delegate/nnrt/nnrt_utils.h
791@@ -0,0 +1,29 @@
792+/**
793+ * Copyright 2024 Huawei Technologies Co., Ltd
794+ *
795+ * Licensed under the Apache License, Version 2.0 (the "License");
796+ * you may not use this file except in compliance with the License.
797+ * You may obtain a copy of the License at
798+ *
799+ * http://www.apache.org/licenses/LICENSE-2.0
800+ *
801+ * Unless required by applicable law or agreed to in writing, software
802+ * distributed under the License is distributed on an "AS IS" BASIS,
803+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
804+ * See the License for the specific language governing permissions and
805+ * limitations under the License.
806+ */
807+
808+#ifndef MINDSPORE_LITE_SRC_RUNTIME_DELEGATE_NNRT_UTILS_H
809+#define MINDSPORE_LITE_SRC_RUNTIME_DELEGATE_NNRT_UTILS_H
810+
811+#include "include/api/format.h"
812+#include "ir/dtype/type_id.h"
813+#include "interfaces/kits/c/neural_network_runtime/neural_network_runtime.h"
814+
815+namespace mindspore::lite {
816+OH_NN_Format CastToNNRtFormat(Format format);
817+OH_NN_DataType CastToNNRtDataType(TypeId data_type);
818+}  // namespace mindspore::lite
819+
820+#endif  // MINDSPORE_LITE_SRC_RUNTIME_DELEGATE_NNRT_UTILS_H
821diff --git a/mindspore/lite/src/litert/infer_manager.cc b/mindspore/lite/src/litert/infer_manager.cc
822index 908ab122..3a5f8832 100644
823--- a/mindspore/lite/src/litert/infer_manager.cc
824+++ b/mindspore/lite/src/litert/infer_manager.cc
825@@ -208,7 +208,10 @@ int KernelInferShape(const std::vector<lite::Tensor *> &inputs, const std::vecto
826         return tensor_ret;
827       }
828     } else {
829-      if (out_tensors.at(i)->data_ != nullptr) {
830+      // During the online phase of shape operator fusion, the output data is computed in advance during the infer shape
831+      // stage. Therefore, the output data is not nullptr and is constant.
832+      if (parameter->type_ == static_cast<int>(PrimType::PrimType_Inner_ShapeFusion) &&
833+          out_tensors.at(i)->data_ != nullptr) {
834         outputs.at(i)->set_own_data(true);
835         outputs.at(i)->set_category(CONST_TENSOR);
836       }
837diff --git a/mindspore/lite/src/tensor.cc b/mindspore/lite/src/tensor.cc
838index a7bb1899..9d9a1491 100644
839--- a/mindspore/lite/src/tensor.cc
840+++ b/mindspore/lite/src/tensor.cc
841@@ -18,6 +18,9 @@
842 #include <vector>
843 #include <string>
844 #include <utility>
845+#ifdef SUPPORT_NNRT
846+#include "src/litert/delegate/nnrt/nnrt_allocator.h"
847+#endif
848 #include "schema/ops_types_generated.h"
849 #include "securec/include/securec.h"
850 #include "include/errorcode.h"
851@@ -427,7 +430,18 @@ int Tensor::MallocData(const AllocatorPtr allocator) {
852   if (allocator_ == nullptr) {
853     this->tensor_c_.data_ = malloc(data_size);
854   } else {
855-    this->tensor_c_.data_ = allocator_->Malloc(data_size);
856+#ifdef SUPPORT_NNRT
857+    if (IS_NNRT_ALLOCATOR(allocator_)) {
858+      this->tensor_c_.data_ = dynamic_cast<NNRTAllocator *>(allocator_.get())->MallocByDesc(data_size, this->shape(),
859+                                                                                            this->data_type(),
860+                                                                                            this->format(),
861+                                                                                            this->tensor_name());
862+    } else {
863+#endif
864+      this->tensor_c_.data_ = allocator_->Malloc(data_size);
865+#ifdef SUPPORT_NNRT
866+    }
867+#endif
868     allocator_->SetRefCount(this->tensor_c_.data_, 1);
869   }
870   if (this->tensor_c_.data_ == nullptr) {
871--
8722.17.1
873
874