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, ¶m->cache_path_); 143 DoParseCacheVersion(extensions, ¶m->cache_version_); 144 DoParseBondMode(extensions, ¶m->band_mode); 145- DoParseQuantConfig(extensions, ¶m->quant_config, ¶m->quant_config_size); 146+ DoParseQuantConfig(extensions, ¶m->quant_config, ¶m->quant_config_size, ¶m->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