diff --git a/frameworks/native/neural_network_core/BUILD.gn b/frameworks/native/neural_network_core/BUILD.gn index 73e52d2438e3b3c94d8f24d76e74097d580b3a43..3a797f726a2b5004ddd32929488184bee3d43f88 100644 --- a/frameworks/native/neural_network_core/BUILD.gn +++ b/frameworks/native/neural_network_core/BUILD.gn @@ -28,6 +28,7 @@ nnrt_core_sources = [ "backend_manager.cpp", "backend_registrar.cpp", "neural_network_core.cpp", + "nnrt_client.cpp", "tensor_desc.cpp", "utils.cpp", "validation.cpp", diff --git a/frameworks/native/neural_network_core/compilation.h b/frameworks/native/neural_network_core/compilation.h index b9cb69edaa966e281be56b2cf51f6f3565ecffaf..f3a9a36ccabe39caa89d47a5ec3e850fd63814f4 100644 --- a/frameworks/native/neural_network_core/compilation.h +++ b/frameworks/native/neural_network_core/compilation.h @@ -40,6 +40,10 @@ struct Compilation { Compiler* compiler {nullptr}; std::vector> options; std::unordered_map> configs; + size_t nnrtModelID {0}; + uint32_t hiaiModelId {0}; + int32_t callingPid {-1}; + bool isNeedModelLatency {false}; ~Compilation() { diff --git a/frameworks/native/neural_network_core/executor.h b/frameworks/native/neural_network_core/executor.h index ba06e675832ad5d8ca2d06df56c38189bdc475b2..cf05e8c0471775851cbd890318a1166f3bb858c4 100644 --- a/frameworks/native/neural_network_core/executor.h +++ b/frameworks/native/neural_network_core/executor.h @@ -18,9 +18,11 @@ #include #include +#include #include "compiler.h" #include "tensor_desc.h" +#include "executor_config.h" #include "interfaces/kits/c/neural_network_runtime/neural_network_runtime_type.h" namespace OHOS { @@ -54,7 +56,10 @@ public: size_t outputSize, int32_t timeout, void* userData) = 0; + virtual OH_NN_ReturnCode GetModelID(uint32_t& modelId) const = 0; virtual size_t GetBackendID() = 0; + virtual OH_NN_ReturnCode SetExtensionConfig(const std::unordered_map>& configs) = 0; + virtual ExecutorConfig* GetExecutorConfig() const = 0; }; } // namespace NeuralNetworkRuntime } // namespace OHOS diff --git a/frameworks/native/neural_network_core/executor_config.h b/frameworks/native/neural_network_core/executor_config.h new file mode 100644 index 0000000000000000000000000000000000000000..00a59d4fbc50a8a83e7d312744db5c1484e1fe41 --- /dev/null +++ b/frameworks/native/neural_network_core/executor_config.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_RUNTIME_EXECUTOR_CONFIG_H +#define NEURAL_NETWORK_RUNTIME_EXECUTOR_CONFIG_H + +#include "nnrt_client.h" + +namespace OHOS { +namespace NeuralNetworkRuntime { +struct ExecutorConfig { + bool isNeedModelLatency {false}; + int32_t callingPid {-1}; + uint32_t hiaiModelId {0}; +}; +} // namespace NeuralNetworkRuntime +} // namespace OHOS + +#endif // NEURAL_NETWORK_RUNTIME_EXECUTOR_CONFIG_H \ No newline at end of file diff --git a/frameworks/native/neural_network_core/neural_network_core.cpp b/frameworks/native/neural_network_core/neural_network_core.cpp index b9d088243a0a5b7c774dcb3af242547ae7ad2b73..320481b44fd820d1a90c8ee15e98b7330da9e9f2 100644 --- a/frameworks/native/neural_network_core/neural_network_core.cpp +++ b/frameworks/native/neural_network_core/neural_network_core.cpp @@ -17,12 +17,17 @@ #include #include +#include +#include +#include +#include #include "common/log.h" #include "executor.h" #include "tensor.h" #include "compilation.h" #include "backend_manager.h" +#include "nnrt_client.h" using namespace OHOS::NeuralNetworkRuntime; #define NNRT_API __attribute__((visibility("default"))) @@ -121,8 +126,8 @@ NNRT_API OH_NNCompilation *OH_NNCompilation_Construct(const OH_NNModel *model) } compilation->nnModel = const_cast(reinterpret_cast(model)); - OH_NNCompilation* nnCompilation = reinterpret_cast(compilation); + OH_NNCompilation* nnCompilation = reinterpret_cast(compilation); return nnCompilation; } @@ -207,13 +212,13 @@ NNRT_API OH_NN_ReturnCode OH_NNCompilation_ExportCacheToBuffer(OH_NNCompilation return OH_NN_INVALID_PARAMETER; } - Compilation* compilationImpr = reinterpret_cast(compilation); - if (compilationImpr->compiler == nullptr) { + Compilation* compilationImpl = reinterpret_cast(compilation); + if (compilationImpl->compiler == nullptr) { LOGE("OH_NNCompilation_ExportCacheToBuffer failed, should call OH_NNCompilation_Build before export cache."); return OH_NN_INVALID_PARAMETER; } - OH_NN_ReturnCode ret = compilationImpr->compiler->SaveToCacheBuffer(buffer, length, modelSize); + OH_NN_ReturnCode ret = compilationImpl->compiler->SaveToCacheBuffer(buffer, length, modelSize); if (ret != OH_NN_SUCCESS) { LOGE("OH_NNCompilation_ExportCacheToBuffer failed, fail to save cache to buffer."); } @@ -240,9 +245,9 @@ NNRT_API OH_NN_ReturnCode OH_NNCompilation_ImportCacheFromBuffer(OH_NNCompilatio return OH_NN_INVALID_PARAMETER; } - Compilation* compilationImpr = reinterpret_cast(compilation); - compilationImpr->offlineModelBuffer.first = const_cast(buffer); - compilationImpr->offlineModelBuffer.second = modelSize; + Compilation* compilationImpl = reinterpret_cast(compilation); + compilationImpl->offlineModelBuffer.first = const_cast(buffer); + compilationImpl->offlineModelBuffer.second = modelSize; return OH_NN_SUCCESS; } @@ -272,7 +277,7 @@ NNRT_API OH_NN_ReturnCode OH_NNCompilation_AddExtensionConfig(OH_NNCompilation * return OH_NN_INVALID_PARAMETER; } - Compilation* compilationImpr = reinterpret_cast(compilation); + Compilation* compilationImpl = reinterpret_cast(compilation); std::string configNameStr = configName; if (configNameStr.empty()) { @@ -288,7 +293,7 @@ NNRT_API OH_NN_ReturnCode OH_NNCompilation_AddExtensionConfig(OH_NNCompilation * return OH_NN_FAILED; } - auto emplaceResult = compilationImpr->configs.emplace(configNameStr, configValueVec); + auto emplaceResult = compilationImpl->configs.emplace(configNameStr, configValueVec); if (!emplaceResult.second) { LOGE("OH_NNCompilation_AddExtensionConfig failed, configName %{public}s already exists," "don't set again.", configName); @@ -305,8 +310,8 @@ NNRT_API OH_NN_ReturnCode OH_NNCompilation_SetDevice(OH_NNCompilation *compilati return OH_NN_INVALID_PARAMETER; } - Compilation* compilationImpr = reinterpret_cast(compilation); - compilationImpr->backendID = deviceID; + Compilation* compilationImpl = reinterpret_cast(compilation); + compilationImpl->backendID = deviceID; return OH_NN_SUCCESS; } @@ -325,9 +330,9 @@ NNRT_API OH_NN_ReturnCode OH_NNCompilation_SetCache(OH_NNCompilation *compilatio return OH_NN_INVALID_PARAMETER; } - Compilation* compilationImpr = reinterpret_cast(compilation); - compilationImpr->cachePath = const_cast(cachePath); - compilationImpr->cacheVersion = version; + Compilation* compilationImpl = reinterpret_cast(compilation); + compilationImpl->cachePath = const_cast(cachePath); + compilationImpl->cacheVersion = version; return OH_NN_SUCCESS; } @@ -340,11 +345,11 @@ NNRT_API OH_NN_ReturnCode OH_NNCompilation_SetPerformanceMode(OH_NNCompilation * return OH_NN_INVALID_PARAMETER; } - Compilation* compilationImpr = reinterpret_cast(compilation); - compilationImpr->performance = performanceMode; + Compilation* compilationImpl = reinterpret_cast(compilation); + compilationImpl->performance = performanceMode; - if (compilationImpr->compiler != nullptr) { - OH_NN_ReturnCode ret = compilationImpr->compiler->SetPerformance(performanceMode); + if (compilationImpl->compiler != nullptr) { + OH_NN_ReturnCode ret = compilationImpl->compiler->SetPerformance(performanceMode); if (ret != OH_NN_SUCCESS) { LOGE("OH_NNCompilation_SetPerformanceMode failed."); return ret; @@ -361,11 +366,11 @@ NNRT_API OH_NN_ReturnCode OH_NNCompilation_SetPriority(OH_NNCompilation *compila return OH_NN_INVALID_PARAMETER; } - Compilation* compilationImpr = reinterpret_cast(compilation); - compilationImpr->priority = priority; + Compilation* compilationImpl = reinterpret_cast(compilation); + compilationImpl->priority = priority; - if (compilationImpr->compiler != nullptr) { - OH_NN_ReturnCode ret = compilationImpr->compiler->SetPriority(priority); + if (compilationImpl->compiler != nullptr) { + OH_NN_ReturnCode ret = compilationImpl->compiler->SetPriority(priority); if (ret != OH_NN_SUCCESS) { LOGE("OH_NNCompilation_SetPriority failed."); return ret; @@ -382,8 +387,8 @@ NNRT_API OH_NN_ReturnCode OH_NNCompilation_EnableFloat16(OH_NNCompilation *compi return OH_NN_INVALID_PARAMETER; } - Compilation* compilationImpr = reinterpret_cast(compilation); - compilationImpr->enableFp16 = enableFloat16; + Compilation* compilationImpl = reinterpret_cast(compilation); + compilationImpl->enableFp16 = enableFloat16; return OH_NN_SUCCESS; } @@ -470,6 +475,210 @@ OH_NN_ReturnCode SetCompilationOptions(Compilation* compilation) return OH_NN_SUCCESS; } +OH_NN_ReturnCode CheckExceedRamLimit(const Compilation* compilation, bool& isExceedRamLimit) +{ + if (compilation == nullptr) { + LOGE("CheckExceedRamLimit failed, compilation is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + NNRtServiceApi& nnrtService = NNRtServiceApi::GetInstance(); + if (!nnrtService.IsServiceAvaliable()) { + LOGW("CheckExceedRamLimit failed, fail to get nnrt service, skip check exceed ram limit."); + return OH_NN_SUCCESS; + } + + if (nnrtService.CheckModelSizeFromBuffer == nullptr) { + LOGE("CheckExceedRamLimit failed, nnrtService CheckModelSizeFromBuffer func is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + if (nnrtService.CheckModelSizeFromModel == nullptr) { + LOGE("CheckExceedRamLimit failed, nnrtService CheckModelSizeFromModel func is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + if (nnrtService.CheckModelSizeFromPath == nullptr) { + LOGE("CheckExceedRamLimit failed, nnrtService CheckModelSizeFromPath func is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + int ret = static_cast(OH_NN_SUCCESS); + if (compilation->nnModel != nullptr) { + ret = nnrtService.CheckModelSizeFromModel(compilation->nnModel, isExceedRamLimit); + } else if (compilation->offlineModelPath != nullptr) { + ret = nnrtService.CheckModelSizeFromPath(compilation->offlineModelPath, isExceedRamLimit); + } else if (compilation->cachePath != nullptr) { + ret = nnrtService.CheckModelSizeFromPath(compilation->cachePath, isExceedRamLimit); + } else if ((compilation->offlineModelBuffer.first != nullptr) && \ + (compilation->offlineModelBuffer.second != size_t(0))) { + ret = nnrtService.CheckModelSizeFromBuffer( + compilation->offlineModelBuffer.first, compilation->offlineModelBuffer.second, isExceedRamLimit); + } else if ((compilation->cacheBuffer.first != nullptr) && \ + (compilation->cacheBuffer.second != size_t(0))) { + ret = nnrtService.CheckModelSizeFromBuffer( + compilation->cacheBuffer.first, compilation->cacheBuffer.second, isExceedRamLimit); + } else { + LOGE("CheckExceedRamLimit failed, no available model to check."); + return OH_NN_INVALID_PARAMETER; + } + + if (ret != static_cast(OH_NN_SUCCESS)) { + LOGE("CheckExceedRamLimit failed, some error happened when check if model exceed ram limit."); + return OH_NN_FAILED; + } + + return OH_NN_SUCCESS; +} + +OH_NN_ReturnCode AuthenticateModel(const Compilation* compilation) +{ + bool isExceedRamLimit = false; + OH_NN_ReturnCode retCode = CheckExceedRamLimit(compilation, isExceedRamLimit); + if (retCode != OH_NN_SUCCESS) { + LOGE("AuthenticateModel failed, fail to check if model exceed ram limit."); + return retCode; + } + + if (!isExceedRamLimit) { + LOGI("Model accupy memory less then limit, no need authenticating."); + return OH_NN_SUCCESS; // If model ram is less than max limit, no need authenticating. + } + + NNRtServiceApi& nnrtService = NNRtServiceApi::GetInstance(); + if (!nnrtService.IsServiceAvaliable()) { + LOGW("AuthenticateModel failed, fail to get nnrt service, skip authenticating."); + return OH_NN_SUCCESS; + } + + if (nnrtService.IsSupportAuthentication == nullptr) { + LOGE("Authentication failed, nnrtService IsSupportAuthentication func is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + bool supportStat = false; + int ret = nnrtService.IsSupportAuthentication(&supportStat); + if (ret != static_cast(OH_NN_SUCCESS)) { + LOGE("Authentication failed, some error happened when judge if support authenticating."); + return static_cast(ret); + } + + if (!supportStat) { + LOGW("device not support authenticating, jumper over authenticating model."); + return OH_NN_SUCCESS; + } + + if (nnrtService.Authentication == nullptr) { + LOGE("Authentication failed, nnrtService Authentication func is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + ret = nnrtService.Authentication(compilation->callingPid); + if (ret != static_cast(OH_NN_SUCCESS)) { + LOGE("Authentication failed, input model cannot run by npu."); + return static_cast(ret); + } + + return OH_NN_SUCCESS; +} + +OH_NN_ReturnCode Authentication(Compilation** compilation) +{ + if (compilation == nullptr) { + LOGE("Authentication failed, compilation is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + Compilation* compilationImpl = *compilation; + if (compilationImpl == nullptr) { + LOGE("Authentication failed, compilation implementation is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + auto iter = compilationImpl->configs.find("callingPid"); + if (iter == compilationImpl->configs.end()) { + LOGE("missing 'callingPid' parameter in compilation configs."); + } else { + compilationImpl->callingPid = std::atoi((iter->second).data()); + } + + NNRtServiceApi& nnrtService = NNRtServiceApi::GetInstance(); + if (!nnrtService.IsServiceAvaliable()) { + LOGW("Authentication failed, fail to get nnrt service, skip Authentication."); + return OH_NN_SUCCESS; + } + + OH_NN_ReturnCode ret = AuthenticateModel(compilationImpl); + if (ret != OH_NN_SUCCESS) { + LOGE("Authentication failed, fail to authenticate model."); + return ret; + } + + LOGI("Authentication success."); + return OH_NN_SUCCESS; +} + +OH_NN_ReturnCode GetModelId(Compilation** compilation) +{ + if (compilation == nullptr) { + LOGE("GetModelId failed, compilation is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + Compilation* compilationImpl = *compilation; + if (compilationImpl == nullptr) { + LOGE("GetModelId failed, compilation implementation is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + NNRtServiceApi& nnrtService = NNRtServiceApi::GetInstance(); + if (!nnrtService.IsServiceAvaliable()) { + LOGW("GetModelId failed, fail to get nnrt service, skip get modelId."); + return OH_NN_SUCCESS; + } + + if (nnrtService.GetNNRtModelIDFromPath == nullptr) { + LOGE("GetModelId failed, nnrtService GetNNRtModelIDFromPath func is nullptr"); + return OH_NN_INVALID_PARAMETER; + } + + if (nnrtService.GetNNRtModelIDFromBuffer == nullptr) { + LOGE("GetModelId failed, nnrtService GetNNRtModelIDFromBuffer func is nullptr"); + return OH_NN_INVALID_PARAMETER; + } + + if (nnrtService.GetNNRtModelIDFromModel == nullptr) { + LOGE("GetModelId failed, nnrtService GetNNRtModelIDFromModel func is nullptr"); + return OH_NN_INVALID_PARAMETER; + } + + int ret = static_cast(OH_NN_SUCCESS); + if (compilationImpl->nnModel != nullptr) { + compilationImpl->nnrtModelID = nnrtService.GetNNRtModelIDFromModel(compilationImpl->nnModel); + } else if (compilationImpl->offlineModelPath != nullptr) { + compilationImpl->nnrtModelID = nnrtService.GetNNRtModelIDFromPath(compilationImpl->offlineModelPath); + } else if (compilationImpl->cachePath != nullptr) { + compilationImpl->nnrtModelID = nnrtService.GetNNRtModelIDFromPath(compilationImpl->cachePath); + } else if ((compilationImpl->offlineModelBuffer.first != nullptr) && \ + (compilationImpl->offlineModelBuffer.second != size_t(0))) { + compilationImpl->nnrtModelID = nnrtService.GetNNRtModelIDFromBuffer( + compilationImpl->offlineModelBuffer.first, compilationImpl->offlineModelBuffer.second); + } else if ((compilationImpl->cacheBuffer.first != nullptr) && \ + (compilationImpl->cacheBuffer.second != size_t(0))) { + compilationImpl->nnrtModelID = nnrtService.GetNNRtModelIDFromBuffer( + compilationImpl->cacheBuffer.first, compilationImpl->cacheBuffer.second); + } else { + LOGE("GetModelId failed, no available model to set modelId, please check."); + return OH_NN_INVALID_PARAMETER; + } + + if (ret != static_cast(OH_NN_SUCCESS)) { + LOGE("GetModelId failed, some error happened when set modelId."); + return OH_NN_FAILED; + } + + return OH_NN_SUCCESS; +} + NNRT_API OH_NN_ReturnCode OH_NNCompilation_Build(OH_NNCompilation *compilation) { if (compilation == nullptr) { @@ -477,49 +686,61 @@ NNRT_API OH_NN_ReturnCode OH_NNCompilation_Build(OH_NNCompilation *compilation) return OH_NN_INVALID_PARAMETER; } - Compilation* compilationImpr = reinterpret_cast(compilation); + Compilation* compilationImpl = reinterpret_cast(compilation); - if (((compilationImpr->nnModel != nullptr) && (compilationImpr->offlineModelPath != nullptr)) || - ((compilationImpr->nnModel != nullptr) && - ((compilationImpr->offlineModelBuffer.first != nullptr) || - (compilationImpr->offlineModelBuffer.second != static_cast(0)))) || - ((compilationImpr->offlineModelPath != nullptr) && - ((compilationImpr->offlineModelBuffer.first != nullptr) || - (compilationImpr->offlineModelBuffer.second != static_cast(0))))) { + if (((compilationImpl->nnModel != nullptr) && (compilationImpl->offlineModelPath != nullptr)) || + ((compilationImpl->nnModel != nullptr) && + ((compilationImpl->offlineModelBuffer.first != nullptr) || + (compilationImpl->offlineModelBuffer.second != static_cast(0)))) || + ((compilationImpl->offlineModelPath != nullptr) && + ((compilationImpl->offlineModelBuffer.first != nullptr) || + (compilationImpl->offlineModelBuffer.second != static_cast(0))))) { LOGE("OH_NNCompilation_Build failed, find multi model to build compilation."); return OH_NN_INVALID_PARAMETER; } OH_NN_ReturnCode ret = OH_NN_SUCCESS; - if (compilationImpr->compiler != nullptr) { + if (compilationImpl->compiler != nullptr) { LOGE("OH_NNCompilation_Build failed, the compiler in compilation is not nullptr, " "please input a new compilation."); return OH_NN_INVALID_PARAMETER; } Compiler* compiler = nullptr; - ret = CreateCompiler(compilationImpr, &compiler); + ret = CreateCompiler(compilationImpl, &compiler); + if (ret != OH_NN_SUCCESS) { + LOGE("OH_NNCompilation_Build failed, fail to create compiler."); + return ret; + } + compilationImpl->compiler = compiler; + + ret = SetCompilationOptions(compilationImpl); if (ret != OH_NN_SUCCESS) { - LOGE("OH_NNCompilation_Build failed, faile to create compiler."); + LOGE("OH_NNCompilation_Build failed, fail to create compiler."); return ret; } - compilationImpr->compiler = compiler; - ret = SetCompilationOptions(compilationImpr); + ret = Authentication(&compilationImpl); if (ret != OH_NN_SUCCESS) { - LOGE("OH_NNCompilation_Build failed, faile to create compiler."); + LOGE("OH_NNCompilation_Build failed, fail to create compiler."); return ret; } - bool isBuild = compilationImpr->compiler->IsBuild(); + bool isBuild = compilationImpl->compiler->IsBuild(); if (isBuild) { LOGE("OH_NNCompilation_Build failed, compilation has been built, don't build again."); return OH_NN_OPERATION_FORBIDDEN; } - ret = compilationImpr->compiler->Build(); + ret = compilationImpl->compiler->Build(); + if (ret != OH_NN_SUCCESS) { + LOGE("OH_NNCompilation_Build failed, fail to build compilation."); + return ret; + } + + ret = GetModelId(&compilationImpl); if (ret != OH_NN_SUCCESS) { - LOGE("OH_NNCompilation_Build failed, faile to build compilation."); + LOGE("OH_NNCompilation_Build failed, fail to get modelId."); return ret; } @@ -538,23 +759,23 @@ NNRT_API void OH_NNCompilation_Destroy(OH_NNCompilation **compilation) return; } - Compilation* compilationImpr = reinterpret_cast(*compilation); - if (compilationImpr->compiler != nullptr) { + Compilation* compilationImpl = reinterpret_cast(*compilation); + if (compilationImpl->compiler != nullptr) { BackendManager& manager = BackendManager::GetInstance(); - std::shared_ptr backend = manager.GetBackend(compilationImpr->backendID); + std::shared_ptr backend = manager.GetBackend(compilationImpl->backendID); if (backend == nullptr) { - LOGE("OH_NNCompilation_Destroy failed, fail to get backend %{public}zu.", compilationImpr->backendID); + LOGE("OH_NNCompilation_Destroy failed, fail to get backend %{public}zu.", compilationImpl->backendID); return; } - OH_NN_ReturnCode ret = backend->DestroyCompiler(compilationImpr->compiler); + OH_NN_ReturnCode ret = backend->DestroyCompiler(compilationImpl->compiler); if (ret != OH_NN_SUCCESS) { LOGE("OH_NNCompilation_Destroy failed, fail to destroy compiler."); return; } } - delete compilationImpr; + delete compilationImpl; *compilation = nullptr; } @@ -979,6 +1200,147 @@ NNRT_API OH_NN_ReturnCode OH_NNTensor_GetOffset(const NN_Tensor *tensor, size_t return OH_NN_SUCCESS; } +OH_NN_ReturnCode Scheduling(Compilation** compilation) +{ + if (compilation == nullptr) { + LOGE("Scheduling failed, compilation is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + Compilation* compilationImpl = *compilation; + if (compilationImpl == nullptr) { + LOGE("Scheduling failed, compilation implementation is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + NNRtServiceApi& nnrtService = NNRtServiceApi::GetInstance(); + if (!nnrtService.IsServiceAvaliable()) { + LOGW("Scheduling failed, fail to get nnrt service, skip schedule."); + return OH_NN_SUCCESS; + } + + if (nnrtService.IsSupportScheduling == nullptr) { + LOGE("Scheduling failed, nnrtService IsSupportScheduling func is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + bool supportStat = false; + int ret = nnrtService.IsSupportScheduling(&supportStat); + if (ret != static_cast(OH_NN_SUCCESS)) { + LOGE("Scheduling failed, some error happened when judge if support scheduling."); + return static_cast(ret); + } + if (!supportStat) { + LOGW("device not support scheduling, jumper over scheduling."); + return OH_NN_SUCCESS; + } + + if (nnrtService.Scheduling == nullptr) { + LOGE("Scheduling failed, nnrtService IsSupportScheduling func is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + bool needModelLatency = false; + ret = nnrtService.Scheduling(compilationImpl->hiaiModelId, &needModelLatency); + if (ret != static_cast(OH_NN_SUCCESS)) { + LOGE("Scheduling failed, some error happened when scheduling."); + return static_cast(ret); + } + + compilationImpl->isNeedModelLatency = needModelLatency; + + LOGI("Scheduling success."); + return OH_NN_SUCCESS; +} + +OH_NN_ReturnCode SetModelId(const Compilation* compilation) +{ + if (compilation == nullptr) { + LOGE("SetModelId failed, compilation is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + NNRtServiceApi& nnrtService = NNRtServiceApi::GetInstance(); + if (!nnrtService.IsServiceAvaliable()) { + LOGW("SetModelId failed, fail to get nnrt service, skip set modelId."); + return OH_NN_SUCCESS; + } + + if (nnrtService.SetModelID == nullptr) { + LOGE("SetModelId failed, nnrtService SetModelID func is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + int ret = nnrtService.SetModelID( + compilation->callingPid, compilation->hiaiModelId, compilation->nnrtModelID); + if (ret != static_cast(OH_NN_SUCCESS)) { + LOGE("SetModelId failed, fail to set modelId."); + return static_cast(ret); + } + + return OH_NN_SUCCESS; +} + +OH_NN_ReturnCode ExecutorPrepare(Executor** executor, Compilation** compilation) +{ + if (executor == nullptr) { + LOGE("ExecutorPrepare failed, executor is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + if (compilation == nullptr) { + LOGE("ExecutorPrepare failed, compilation is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + Executor* executorImpl = *executor; + if (executorImpl == nullptr) { + LOGE("ExecutorPrepare failed, executor implementation is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + Compilation* compilationImpl = *compilation; + if (compilationImpl == nullptr) { + LOGE("ExecutorPrepare failed, compilation implementation is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + OH_NN_ReturnCode ret = SetModelId(compilationImpl); + if (ret != OH_NN_SUCCESS) { + LOGE("ExecutorPrepare failed, fail to set modelId."); + return ret; + } + + LOGD("ExecutorPrepare parameter, callingPid: %{public}d, hiaiModelId: %{public}u, nnrtModelId: %{public}zu.", + compilationImpl->callingPid, compilationImpl->hiaiModelId, compilationImpl->nnrtModelID); + + ret = Scheduling(&compilationImpl); + if (ret != OH_NN_SUCCESS) { + LOGE("ExecutorPrepare failed, failed to create executor."); + return ret; + } + + std::unordered_map> configMap; + std::string callingPidStr = std::to_string(compilationImpl->callingPid); + std::vector vecCallingPid(callingPidStr.begin(), callingPidStr.end()); + configMap["callingPid"] = vecCallingPid; + + std::string hiaiModelIdStr = std::to_string(compilationImpl->hiaiModelId); + std::vector vechiaiModelId(hiaiModelIdStr.begin(), hiaiModelIdStr.end()); + configMap["hiaiModelId"] = vechiaiModelId; + + std::vector vecNeedLatency(static_cast(compilationImpl->isNeedModelLatency)); + configMap["isNeedModelLatency"] = vecNeedLatency; + + executorImpl->SetExtensionConfig(configMap); + if (ret != OH_NN_SUCCESS) { + LOGE("ExecutorPrepare failed, failed to set config to executor."); + return ret; + } + + return OH_NN_SUCCESS; +} + NNRT_API OH_NNExecutor *OH_NNExecutor_Construct(OH_NNCompilation *compilation) { if (compilation == nullptr) { @@ -1000,18 +1362,60 @@ NNRT_API OH_NNExecutor *OH_NNExecutor_Construct(OH_NNCompilation *compilation) return nullptr; } + OH_NN_ReturnCode ret = executorImpl->GetModelID(compilationImpl->hiaiModelId); + if (ret != OH_NN_SUCCESS) { + LOGE("OH_NNExecutor_Construct failed, failed to get hiai modelId."); + OH_NNExecutor_Destroy(reinterpret_cast(&executorImpl)); + return nullptr; + } + + ret = ExecutorPrepare(&executorImpl, &compilationImpl); + if (ret != OH_NN_SUCCESS) { + LOGE("OH_NNExecutor_Construct failed, failed to prepare executor."); + OH_NNExecutor_Destroy(reinterpret_cast(&executorImpl)); + return nullptr; + } + OH_NNExecutor *executor = reinterpret_cast(executorImpl); return executor; } +OH_NN_ReturnCode Unload(const ExecutorConfig* config) +{ + if (config == nullptr) { + LOGE("Unload failed, config is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + NNRtServiceApi& nnrtService = NNRtServiceApi::GetInstance(); + if (!nnrtService.IsServiceAvaliable()) { + LOGW("Unload failed, fail to get nnrt service, skip unload."); + return OH_NN_SUCCESS; + } + + if (nnrtService.Unload == nullptr) { + LOGE("Unload failed, nnrtService Unload func is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + int ret = nnrtService.Unload(config->hiaiModelId); + if (ret != static_cast(OH_NN_SUCCESS)) { + LOGE("Unload failed, nnrtService is not exist, jump over Unload."); + return static_cast(ret); + } + + LOGI("Unload success."); + return OH_NN_SUCCESS; +} + NNRT_API void OH_NNExecutor_Destroy(OH_NNExecutor **executor) { if (executor == nullptr) { - LOGW("OH_NNExecutor_Destroy failed, executor is nullptr."); + LOGE("OH_NNExecutor_Destroy failed, executor is nullptr."); return; } if (*executor == nullptr) { - LOGW("OH_NNExecutor_Destroy failed, *executor is nullptr."); + LOGE("OH_NNExecutor_Destroy failed, *executor is nullptr."); return; } @@ -1024,11 +1428,17 @@ NNRT_API void OH_NNExecutor_Destroy(OH_NNExecutor **executor) return; } + OH_NN_ReturnCode ret = Unload(executorImpl->GetExecutorConfig()); + if (ret != OH_NN_SUCCESS) { + LOGE("Unload failed, some error happened when unload nnrt service."); + } + auto returnCode = backend->DestroyExecutor(executorImpl); if (returnCode != OH_NN_SUCCESS) { LOGE("OH_NNExecutor_Destroy failed, failed to destroy executor."); return; } + *executor = nullptr; } @@ -1169,6 +1579,85 @@ NNRT_API OH_NN_ReturnCode OH_NNExecutor_SetOnServiceDied(OH_NNExecutor *executor return executorImpl->SetOnServiceDied(onServiceDied); } +OH_NN_ReturnCode UpdateModelLatency(const ExecutorConfig* config, int32_t modelLatency) +{ + if (config == nullptr) { + LOGE("UpdateModelLatency failed, config is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + NNRtServiceApi& nnrtService = NNRtServiceApi::GetInstance(); + if (!nnrtService.IsServiceAvaliable()) { + LOGW("UpdateModelLatency failed, fail to get nnrt service, skip update model latency."); + return OH_NN_SUCCESS; + } + + if (nnrtService.UpdateModelLatency == nullptr) { + LOGE("UpdateModelLatency failed, nnrtService UpdateModelLatency func is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + LOGD("UpdateModelLatency, hiaiModelId: %{public}u, modelLatency: %{public}d.", config->hiaiModelId, modelLatency); + + int ret = nnrtService.UpdateModelLatency(config->hiaiModelId, modelLatency); + if (ret != static_cast(OH_NN_SUCCESS)) { + LOGE("UpdateModelLatency failed, nnrtService is not exist, jump over UpdateModelLatency."); + return static_cast(ret); + } + + LOGI("UpdateModelLatency success."); + return OH_NN_SUCCESS; +} + +OH_NN_ReturnCode RunSync(Executor *executor, + NN_Tensor *inputTensor[], + size_t inputCount, + NN_Tensor *outputTensor[], + size_t outputCount) +{ + ExecutorConfig* configPtr = executor->GetExecutorConfig(); + if (configPtr == nullptr) { + LOGE("RunSync failed, executor config is nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + long timeStart = 0; + long timeEnd = 0; + int32_t modelLatency = 0; + if (configPtr->isNeedModelLatency) { + timeStart = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count(); + } + + OH_NN_ReturnCode ret = executor->RunSync(inputTensor, inputCount, outputTensor, outputCount); + if (ret != OH_NN_SUCCESS) { + LOGE("OH_NNExecutor_RunSync failed, fail to run executor."); + return ret; + } + + if (configPtr->isNeedModelLatency) { + timeEnd = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count(); + modelLatency = static_cast((timeEnd - timeStart)); + std::thread t(UpdateModelLatency, configPtr, modelLatency); + t.detach(); + LOGE("update async start."); + + configPtr->isNeedModelLatency = false; + std::unordered_map> configMap; + std::vector vecNeedLatency(static_cast(configPtr->isNeedModelLatency)); + configMap["isNeedModelLatency"] = vecNeedLatency; + + ret = executor->SetExtensionConfig(configMap); + if (ret != OH_NN_SUCCESS) { + LOGE("OH_NNExecutor_RunSync failed, fail update executor config."); + return ret; + } + } + + return OH_NN_SUCCESS; +} + NNRT_API OH_NN_ReturnCode OH_NNExecutor_RunSync(OH_NNExecutor *executor, NN_Tensor *inputTensor[], size_t inputCount, @@ -1197,7 +1686,7 @@ NNRT_API OH_NN_ReturnCode OH_NNExecutor_RunSync(OH_NNExecutor *executor, } Executor *executorImpl = reinterpret_cast(executor); - return executorImpl->RunSync(inputTensor, inputCount, outputTensor, outputCount); + return RunSync(executorImpl, inputTensor, inputCount, outputTensor, outputCount); } NNRT_API OH_NN_ReturnCode OH_NNExecutor_RunAsync(OH_NNExecutor *executor, diff --git a/frameworks/native/neural_network_core/nnrt_client.cpp b/frameworks/native/neural_network_core/nnrt_client.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6d5992704c0a9efcf73a8d414923f40f29a81001 --- /dev/null +++ b/frameworks/native/neural_network_core/nnrt_client.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nnrt_client.h" + +#include +#include + +#include "common/log.h" + +namespace OHOS { +namespace NeuralNetworkRuntime { +template +void LoadFunction(void* handle, const char* name, T* nnrtFunction) +{ + if (name == nullptr) { + LOGE("LoadFunction error: the function %s does not exist.", name); + return; + } + + void* fn = dlsym(handle, name); + if (fn == nullptr) { + LOGE("LoadFunction error: unable to open function %{public}s", name); + return; + } + + *nnrtFunction = reinterpret_cast(fn); + return; +} + +static void* libNNRtService = nullptr; + +NNRtServiceApi& NNRtServiceApi::GetInstance() +{ + static NNRtServiceApi nnrtService; + + // Assumes there can be multiple instances of NN API + std::string nnrtLibraryName = "libdllite_service_client.z.so"; + libNNRtService = dlopen(nnrtLibraryName.c_str(), RTLD_LAZY | RTLD_NODELETE); + if (libNNRtService == nullptr) { + LOGE("LoadNNRtService error: unable to open library %{public}s", nnrtLibraryName.c_str()); + nnrtService.m_serviceAvailable = false; + return nnrtService; + } + + LoadFunction(libNNRtService, "CheckModelSizeFromPath", &nnrtService.CheckModelSizeFromPath); + LoadFunction(libNNRtService, "CheckModelSizeFromBuffer", &nnrtService.CheckModelSizeFromBuffer); + LoadFunction(libNNRtService, "CheckModelSizeFromModel", &nnrtService.CheckModelSizeFromModel); + LoadFunction(libNNRtService, "GetNNRtModelIDFromPath", &nnrtService.GetNNRtModelIDFromPath); + LoadFunction(libNNRtService, "GetNNRtModelIDFromBuffer", &nnrtService.GetNNRtModelIDFromBuffer); + LoadFunction(libNNRtService, "GetNNRtModelIDFromModel", &nnrtService.GetNNRtModelIDFromModel); + LoadFunction(libNNRtService, "SetModelID", &nnrtService.SetModelID); + LoadFunction(libNNRtService, "IsSupportAuthentication", &nnrtService.IsSupportAuthentication); + LoadFunction(libNNRtService, "IsSupportScheduling", &nnrtService.IsSupportScheduling); + LoadFunction(libNNRtService, "Authentication", &nnrtService.Authentication); + LoadFunction(libNNRtService, "Scheduling", &nnrtService.Scheduling); + LoadFunction(libNNRtService, "UpdateModelLatency", &nnrtService.UpdateModelLatency); + LoadFunction(libNNRtService, "Unload", &nnrtService.Unload); + + nnrtService.m_serviceAvailable = true; + return nnrtService; +} + +bool NNRtServiceApi::IsServiceAvaliable() +{ + return m_serviceAvailable; +} + +NNRtServiceApi::~NNRtServiceApi() +{ + if (libNNRtService != nullptr) { + dlclose(libNNRtService); + libNNRtService = nullptr; + } +} +} // namespace NeuralNetworkRuntime +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/neural_network_core/nnrt_client.h b/frameworks/native/neural_network_core/nnrt_client.h new file mode 100644 index 0000000000000000000000000000000000000000..5c28dd3f2f4f03386e9d88602613a514a0460adc --- /dev/null +++ b/frameworks/native/neural_network_core/nnrt_client.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_RUNTIME_CLIENT_H +#define NEURAL_NETWORK_RUNTIME_CLIENT_H + +#include +#include + +namespace OHOS { +namespace NeuralNetworkRuntime { +class NNRtServiceApi { +public: + static NNRtServiceApi& GetInstance(); + bool IsServiceAvaliable(); + + int (*CheckModelSizeFromPath)(const char* path, bool& exceedLimit); + int (*CheckModelSizeFromBuffer)(const void* buffer, size_t size, bool& exceedLimit); + int (*CheckModelSizeFromModel)(void* model, bool& exceedLimit); + size_t (*GetNNRtModelIDFromPath)(const char*); + size_t (*GetNNRtModelIDFromBuffer)(const void* buffer, size_t size); + size_t (*GetNNRtModelIDFromModel)(void* model); + int (*SetModelID)(int callingPid, uint32_t hiaimodelID, size_t nnrtModelID); + int (*IsSupportAuthentication)(bool* supportStat); + int (*IsSupportScheduling)(bool* supportStat); + int (*Authentication)(int callingPid); + int (*Scheduling)(uint32_t hiaiModelId, bool* needModelLatency); + int (*UpdateModelLatency)(uint32_t hiaiModelId, int modelLatency); + int (*Unload)(uint32_t hiaiModelId); + +private: + bool m_serviceAvailable = false; + NNRtServiceApi() = default; + NNRtServiceApi(const NNRtServiceApi&) = delete; + NNRtServiceApi& operator=(const NNRtServiceApi&) = delete; + virtual ~NNRtServiceApi(); +}; +} // namespace NeuralNetworkRuntime +} // namespace OHOS + +#endif // NEURAL_NETWORK_RUNTIME_CLIENT_H \ No newline at end of file diff --git a/frameworks/native/neural_network_runtime/device.h b/frameworks/native/neural_network_runtime/device.h index 853c102b0ce41b7e977558c1d5380fe1c1203cb0..5dd2d678b0cb6824a676cd4e775fe8c13f6db007 100644 --- a/frameworks/native/neural_network_runtime/device.h +++ b/frameworks/native/neural_network_runtime/device.h @@ -56,7 +56,8 @@ public: std::shared_ptr& preparedModel) = 0; virtual OH_NN_ReturnCode PrepareModelFromModelCache(const std::vector& modelCache, const ModelConfig& config, - std::shared_ptr& preparedModel) = 0; + std::shared_ptr& preparedModel, + bool& isUpdatable) = 0; virtual OH_NN_ReturnCode PrepareOfflineModel(std::shared_ptr model, const ModelConfig& config, std::shared_ptr& preparedModel) = 0; diff --git a/frameworks/native/neural_network_runtime/hdi_device_v1_0.cpp b/frameworks/native/neural_network_runtime/hdi_device_v1_0.cpp index 5482c2da8121a0122e70d7f36eaa1eab444a7337..c271b72cfe85c1e794e93d8b39794bf6f2178309 100644 --- a/frameworks/native/neural_network_runtime/hdi_device_v1_0.cpp +++ b/frameworks/native/neural_network_runtime/hdi_device_v1_0.cpp @@ -299,7 +299,7 @@ OH_NN_ReturnCode HDIDeviceV1_0::PrepareModel(const void* metaGraph, } OH_NN_ReturnCode HDIDeviceV1_0::PrepareModelFromModelCache(const std::vector& modelCache, - const ModelConfig& config, std::shared_ptr& preparedModel) + const ModelConfig& config, std::shared_ptr& preparedModel, bool& isUpdatable) { std::vector iBuffers; auto memManager = MemoryManager::GetInstance(); diff --git a/frameworks/native/neural_network_runtime/hdi_device_v1_0.h b/frameworks/native/neural_network_runtime/hdi_device_v1_0.h index cc78f11e4fead24b4dc8323f998de7b8fb598020..14c23f19631401708bf5d45e5ca3323ebdf12520 100644 --- a/frameworks/native/neural_network_runtime/hdi_device_v1_0.h +++ b/frameworks/native/neural_network_runtime/hdi_device_v1_0.h @@ -52,7 +52,8 @@ public: std::shared_ptr& preparedModel) override; OH_NN_ReturnCode PrepareModelFromModelCache(const std::vector& modelCache, const ModelConfig& config, - std::shared_ptr& preparedModel) override; + std::shared_ptr& preparedModel, + bool& isUpdatable) override; OH_NN_ReturnCode PrepareOfflineModel(std::shared_ptr model, const ModelConfig& config, std::shared_ptr& preparedModel) override; diff --git a/frameworks/native/neural_network_runtime/hdi_device_v2_0.cpp b/frameworks/native/neural_network_runtime/hdi_device_v2_0.cpp index 18755a3d6d84a3517a4ab4c6085a297a04d28952..c65bb1414f92503a0d9734608c868d1873597513 100644 --- a/frameworks/native/neural_network_runtime/hdi_device_v2_0.cpp +++ b/frameworks/native/neural_network_runtime/hdi_device_v2_0.cpp @@ -336,7 +336,7 @@ OH_NN_ReturnCode HDIDeviceV2_0::PrepareModel(const void* metaGraph, } OH_NN_ReturnCode HDIDeviceV2_0::PrepareModelFromModelCache(const std::vector& modelCache, - const ModelConfig& config, std::shared_ptr& preparedModel) + const ModelConfig& config, std::shared_ptr& preparedModel, bool& isUpdatable) { std::vector iBuffers; auto memManager = MemoryManager::GetInstance(); diff --git a/frameworks/native/neural_network_runtime/hdi_device_v2_0.h b/frameworks/native/neural_network_runtime/hdi_device_v2_0.h index f9ec9d739b3dc3732d0cd3f1b1d4f0bdae5ca2eb..e2cf4a1766f8753fe007733e2fa7112d643ba2d8 100644 --- a/frameworks/native/neural_network_runtime/hdi_device_v2_0.h +++ b/frameworks/native/neural_network_runtime/hdi_device_v2_0.h @@ -52,7 +52,8 @@ public: std::shared_ptr& preparedModel) override; OH_NN_ReturnCode PrepareModelFromModelCache(const std::vector& modelCache, const ModelConfig& config, - std::shared_ptr& preparedModel) override; + std::shared_ptr& preparedModel, + bool& isUpdatable) override; OH_NN_ReturnCode PrepareOfflineModel(std::shared_ptr model, const ModelConfig& config, std::shared_ptr& preparedModel) override; diff --git a/frameworks/native/neural_network_runtime/hdi_device_v2_1.cpp b/frameworks/native/neural_network_runtime/hdi_device_v2_1.cpp index 30f35e9757b96083178a8f08c8877a59c344b4ea..330fccedfb6ed85b0abe090cc8e30d7bcbcd43a6 100644 --- a/frameworks/native/neural_network_runtime/hdi_device_v2_1.cpp +++ b/frameworks/native/neural_network_runtime/hdi_device_v2_1.cpp @@ -336,7 +336,7 @@ OH_NN_ReturnCode HDIDeviceV2_1::PrepareModel(const void* metaGraph, } OH_NN_ReturnCode HDIDeviceV2_1::PrepareModelFromModelCache(const std::vector& modelCache, - const ModelConfig& config, std::shared_ptr& preparedModel) + const ModelConfig& config, std::shared_ptr& preparedModel, bool& isUpdatable) { std::vector iBuffers; auto memManager = MemoryManager::GetInstance(); diff --git a/frameworks/native/neural_network_runtime/hdi_device_v2_1.h b/frameworks/native/neural_network_runtime/hdi_device_v2_1.h index 0cde9a7d0c4e865a125f0358a8df276d7a8bdad8..15080d8173d36b34bc598f356f9488478b4024e9 100644 --- a/frameworks/native/neural_network_runtime/hdi_device_v2_1.h +++ b/frameworks/native/neural_network_runtime/hdi_device_v2_1.h @@ -52,7 +52,8 @@ public: std::shared_ptr& preparedModel) override; OH_NN_ReturnCode PrepareModelFromModelCache(const std::vector& modelCache, const ModelConfig& config, - std::shared_ptr& preparedModel) override; + std::shared_ptr& preparedModel, + bool& isUpdatable) override; OH_NN_ReturnCode PrepareOfflineModel(std::shared_ptr model, const ModelConfig& config, std::shared_ptr& preparedModel) override; diff --git a/frameworks/native/neural_network_runtime/hdi_prepared_model_v1_0.cpp b/frameworks/native/neural_network_runtime/hdi_prepared_model_v1_0.cpp index 9c94d81777ba0b912588f81226db9b3c3d138aab..f4b87c3c40c8acf2acc76d0eddc4340db232d8e9 100644 --- a/frameworks/native/neural_network_runtime/hdi_prepared_model_v1_0.cpp +++ b/frameworks/native/neural_network_runtime/hdi_prepared_model_v1_0.cpp @@ -280,5 +280,11 @@ OH_NN_ReturnCode HDIPreparedModelV1_0::Run(const std::vector& inputs return OH_NN_SUCCESS; } + +OH_NN_ReturnCode HDIPreparedModelV1_0::GetModelID(uint32_t& modelId) const +{ + LOGE("hdi preparedModel V1_0 not support get model ID."); + return OH_NN_SUCCESS; +} } // namespace NeuralNetworkRuntime } // OHOS \ No newline at end of file diff --git a/frameworks/native/neural_network_runtime/hdi_prepared_model_v1_0.h b/frameworks/native/neural_network_runtime/hdi_prepared_model_v1_0.h index ff227747ceb35e6499b5bd46b978d59c88c35a4d..47da0604cb776718bbf1c37f64a72f521f305ec8 100644 --- a/frameworks/native/neural_network_runtime/hdi_prepared_model_v1_0.h +++ b/frameworks/native/neural_network_runtime/hdi_prepared_model_v1_0.h @@ -47,6 +47,8 @@ public: std::vector>& outputsDims, std::vector& isOutputBufferEnough) override; + OH_NN_ReturnCode GetModelID(uint32_t& modelId) const override; + private: // first: major version, second: minor version std::pair m_hdiVersion; diff --git a/frameworks/native/neural_network_runtime/hdi_prepared_model_v2_0.cpp b/frameworks/native/neural_network_runtime/hdi_prepared_model_v2_0.cpp index b3b535b9048f43b84ee8983fc8b95dabd207038b..deb04ed3de084bb6c60eb8da05594201795042f0 100644 --- a/frameworks/native/neural_network_runtime/hdi_prepared_model_v2_0.cpp +++ b/frameworks/native/neural_network_runtime/hdi_prepared_model_v2_0.cpp @@ -297,5 +297,11 @@ OH_NN_ReturnCode HDIPreparedModelV2_0::GetInputDimRanges(std::vector>& outputsDims, std::vector& isOutputBufferEnough) override; + OH_NN_ReturnCode GetModelID(uint32_t& modelId) const override; + OH_NN_ReturnCode GetInputDimRanges(std::vector>& minInputDims, std::vector>& maxInputDims) override; diff --git a/frameworks/native/neural_network_runtime/hdi_prepared_model_v2_1.cpp b/frameworks/native/neural_network_runtime/hdi_prepared_model_v2_1.cpp index 4f5b25b0e036c7b3d3c633555532bb764d3a86f2..122bce0be7eb1a84f4bb7d038dc205e2bdafff69 100644 --- a/frameworks/native/neural_network_runtime/hdi_prepared_model_v2_1.cpp +++ b/frameworks/native/neural_network_runtime/hdi_prepared_model_v2_1.cpp @@ -297,5 +297,11 @@ OH_NN_ReturnCode HDIPreparedModelV2_1::GetInputDimRanges(std::vector>& outputsDims, std::vector& isOutputBufferEnough) override; + OH_NN_ReturnCode GetModelID(uint32_t& modelId) const override; + OH_NN_ReturnCode GetInputDimRanges(std::vector>& minInputDims, std::vector>& maxInputDims) override; diff --git a/frameworks/native/neural_network_runtime/inner_model.cpp b/frameworks/native/neural_network_runtime/inner_model.cpp index 6ad34df241f65a098e5d69dac8097431db1c54f9..0933e434e029ffac6d97756b97187a322454ef54 100644 --- a/frameworks/native/neural_network_runtime/inner_model.cpp +++ b/frameworks/native/neural_network_runtime/inner_model.cpp @@ -705,11 +705,6 @@ OH_NN_ReturnCode InnerModel::GetSupportedOperations(size_t deviceID, const bool* return OH_NN_SUCCESS; } -std::shared_ptr InnerModel::GetLiteGraphs() const -{ - return m_liteGraph; -} - std::vector> InnerModel::GetInputTensors() const { return m_inputTensors; diff --git a/frameworks/native/neural_network_runtime/inner_model.h b/frameworks/native/neural_network_runtime/inner_model.h index 066ab7bb50f32e5250a77837420674420943871a..a041f2673316f1ee5259f8fc8b450430ba45c1c8 100644 --- a/frameworks/native/neural_network_runtime/inner_model.h +++ b/frameworks/native/neural_network_runtime/inner_model.h @@ -54,7 +54,10 @@ public: std::vector> GetOutputTensors() const; std::vector, OH_NN_TensorType>> GetInputTensorDescs() const; std::vector, OH_NN_TensorType>> GetOutputTensorDescs() const; - std::shared_ptr GetLiteGraphs() const; + std::shared_ptr GetLiteGraphs() const + { + return m_liteGraph; + } void* GetMetaGraph() const; ExtensionConfig GetExtensionConfig() const; diff --git a/frameworks/native/neural_network_runtime/nncompiled_cache.cpp b/frameworks/native/neural_network_runtime/nncompiled_cache.cpp index 7d7ee1ce5232c894543e0c71b72488a939c8c573..9b02056c7d223c7a9e6f3aeaf568838dd1bf24b2 100644 --- a/frameworks/native/neural_network_runtime/nncompiled_cache.cpp +++ b/frameworks/native/neural_network_runtime/nncompiled_cache.cpp @@ -26,10 +26,10 @@ namespace OHOS { namespace NeuralNetworkRuntime { -constexpr int MAX_MODEL_SIZE = 200 * 1024 * 1024; // 200MB -constexpr int NULL_PTR_LENGTH = 0; -constexpr int NUMBER_CACHE_INFO_MEMBERS = 3; -constexpr int HEX_UNIT = 16; +constexpr int32_t MAX_MODEL_SIZE = 200 * 1024 * 1024; // 200MB +constexpr int32_t NULL_PTR_LENGTH = 0; +constexpr int32_t NUMBER_CACHE_INFO_MEMBERS = 3; +constexpr int32_t HEX_UNIT = 16; constexpr char ROOT_DIR_STR = '/'; constexpr char DOUBLE_SLASH_STR[] = "//"; @@ -94,15 +94,15 @@ OH_NN_ReturnCode NNCompiledCache::Restore(const std::string& cacheDir, return ret; } - if (static_cast(version) > cacheInfo.version) { + if (static_cast(version) > cacheInfo.version) { LOGE("[NNCompiledCache] Restore failed, version is not match. The current version is %{public}u, " - "but the cache files version is %{public}zu.", + "but the cache files version is %{public}lld.", version, - static_cast(cacheInfo.version)); + cacheInfo.version); return OH_NN_INVALID_PARAMETER; } - if (static_cast(version) < cacheInfo.version) { + if (static_cast(version) < cacheInfo.version) { LOGE("[NNCompiledCache] Restore failed, the current version is lower than the cache files, " "please set a higher version."); return OH_NN_OPERATION_FORBIDDEN; @@ -166,7 +166,7 @@ OH_NN_ReturnCode NNCompiledCache::GenerateCacheFiles(const std::vector cacheInfo = CreateUniquePtr(cacheSize); + std::unique_ptr cacheInfo = CreateUniquePtr(cacheSize); if (cacheInfo == nullptr) { LOGE("[NNCompiledCache] GenerateCacheFiles failed, fail to create cacheInfo instance."); return OH_NN_MEMORY_ERROR; @@ -189,16 +189,16 @@ OH_NN_ReturnCode NNCompiledCache::GenerateCacheFiles(const std::vector& caches, - std::unique_ptr& cacheInfo, + std::unique_ptr& cacheInfo, const std::string& cacheDir, uint32_t version) const { size_t cacheNumber = caches.size(); auto cacheInfoPtr = cacheInfo.get(); - *cacheInfoPtr++ = static_cast(cacheNumber); - *cacheInfoPtr++ = static_cast(version); - *cacheInfoPtr++ = static_cast(m_backendID); // Should call SetBackend first. + *cacheInfoPtr++ = static_cast(cacheNumber); + *cacheInfoPtr++ = static_cast(version); + *cacheInfoPtr++ = static_cast(m_backendID); // Should call SetBackend first. // standardize the input dir OH_NN_ReturnCode ret = OH_NN_SUCCESS; @@ -224,7 +224,7 @@ OH_NN_ReturnCode NNCompiledCache::GenerateCacheModel(const std::vector(GetCrc16(static_cast(caches[i].data), caches[i].length)); + static_cast(GetCrc16(static_cast(caches[i].data), caches[i].length)); *cacheInfoPtr++ = checkSum; if (!cacheModelStream.write(static_cast(caches[i].data), caches[i].length)) { LOGE("[NNCompiledCache] GenerateCacheModel failed, fail to write cache model."); @@ -239,7 +239,7 @@ OH_NN_ReturnCode NNCompiledCache::GenerateCacheModel(const std::vector& cacheInfo, + std::unique_ptr& cacheInfo, const std::string& cacheDir) const { // standardize the input dir @@ -303,7 +303,7 @@ OH_NN_ReturnCode NNCompiledCache::CheckCacheInfo(NNCompiledCacheInfo& modelCache return OH_NN_INVALID_PARAMETER; } - std::vector modelCheckSum; + std::vector modelCheckSum; modelCheckSum.resize(modelCacheInfo.fileNumber); modelCacheInfo.modelCheckSum.resize(modelCacheInfo.fileNumber); if (!infoCacheFile.read(reinterpret_cast(&modelCheckSum[0]), diff --git a/frameworks/native/neural_network_runtime/nncompiled_cache.h b/frameworks/native/neural_network_runtime/nncompiled_cache.h index 1140fab89bb37ad3c28f62cc5e65dbe7348114a7..f720474dc5bf5a609280ad3343d82b7231ed8c1d 100644 --- a/frameworks/native/neural_network_runtime/nncompiled_cache.h +++ b/frameworks/native/neural_network_runtime/nncompiled_cache.h @@ -29,9 +29,9 @@ namespace NeuralNetworkRuntime { const uint32_t INVALID_CAHCE_VERSION = UINT32_MAX; // UINT32_MAX is reserved for invalid cache version. struct NNCompiledCacheInfo { - uint64_t fileNumber{0}; - uint64_t version{0}; - uint64_t deviceId{0}; + int64_t fileNumber{0}; + int64_t version{0}; + int64_t deviceId{0}; std::vector modelCheckSum; }; @@ -49,19 +49,19 @@ public: OH_NN_ReturnCode SetBackend(size_t backendID); void SetModelName(const std::string& modelName); + OH_NN_ReturnCode WriteCacheInfo(uint32_t cacheSize, + std::unique_ptr& cacheInfo, + const std::string& cacheDir) const; + OH_NN_ReturnCode CheckCacheInfo(NNCompiledCacheInfo& modelCacheInfo, const std::string& cacheInfoPath) const; private: OH_NN_ReturnCode GenerateCacheFiles(const std::vector& caches, const std::string& cacheDir, uint32_t version) const; OH_NN_ReturnCode GenerateCacheModel(const std::vector& caches, - std::unique_ptr& cacheInfo, + std::unique_ptr& cacheInfo, const std::string& cacheDir, uint32_t version) const; - OH_NN_ReturnCode WriteCacheInfo(uint32_t cacheSize, - std::unique_ptr& cacheInfo, - const std::string& cacheDir) const; - OH_NN_ReturnCode CheckCacheInfo(NNCompiledCacheInfo& modelCacheInfo, const std::string& cacheInfoPath) const; OH_NN_ReturnCode ReadCacheModelFile(const std::string& file, Buffer& cache) const; unsigned short GetCrc16(char* buffer, size_t length) const; OH_NN_ReturnCode GetCacheFileLength(std::ifstream& ifs, int& fileSize) const; diff --git a/frameworks/native/neural_network_runtime/nncompiler.cpp b/frameworks/native/neural_network_runtime/nncompiler.cpp index 45a9fca5a1f55b360d2f337e9f5e596fb3d325c2..725bafbd80caaea1dd89a4511ff78ddd3ea91f6b 100644 --- a/frameworks/native/neural_network_runtime/nncompiler.cpp +++ b/frameworks/native/neural_network_runtime/nncompiler.cpp @@ -29,6 +29,7 @@ namespace NeuralNetworkRuntime { namespace { const int CACHE_INPUT_TENSORDESC_OFFSET = 2; const int CACHE_OUTPUT_TENSORDESC_OFFSET = 1; +constexpr int32_t NUMBER_CACHE_INFO_MEMBERS = 3; struct SerializedTensorDesc { public: @@ -351,7 +352,7 @@ OH_NN_ReturnCode NNCompiler::BuildOfflineModel() OH_NN_ReturnCode NNCompiler::NormalBuild() { if ((m_liteGraph == nullptr) && (m_metaGraph == nullptr)) { - LOGW("[NNCompiler] Build failed, both liteGraph and metaGraph are nullptr."); + LOGE("[NNCompiler] Build failed, both liteGraph and metaGraph are nullptr."); return OH_NN_INVALID_PARAMETER; } @@ -434,8 +435,19 @@ OH_NN_ReturnCode NNCompiler::Build() return OH_NN_SUCCESS; } + ret = OnlineBuild(); + if (ret != OH_NN_SUCCESS) { + LOGE("[NNCompiler] OnlineBuild failed, Failed to build model online."); + return ret; + } + + return OH_NN_SUCCESS; +} + +OH_NN_ReturnCode NNCompiler::OnlineBuild() +{ // cache存在,从cache直接复原prepareModel、input/output TensorDesc - ret = RestoreFromCacheFile(); + OH_NN_ReturnCode ret = RestoreFromCacheFile(); if (ret == OH_NN_OPERATION_FORBIDDEN) { LOGE("[NNCompiler] Build failed, operation is forbidden."); return ret; @@ -443,14 +455,15 @@ OH_NN_ReturnCode NNCompiler::Build() if (ret == OH_NN_SUCCESS) { LOGI("[NNCompiler] Build success, restore from cache file."); m_isBuild = true; - return OH_NN_SUCCESS; } // cache不存在或cache restore失败,走在线构图 - ret = NormalBuild(); - if (ret != OH_NN_SUCCESS) { - LOGE("[NNCompiler] Build failed, fail to build model online."); - return ret; + if (!m_isBuild) { + ret = NormalBuild(); + if (ret != OH_NN_SUCCESS) { + LOGE("[NNCompiler] Build failed, fail to build model online."); + return ret; + } } return OH_NN_SUCCESS; @@ -593,12 +606,53 @@ OH_NN_ReturnCode NNCompiler::RestoreFromCacheFile() config.mode = m_performance; config.priority = m_priority; std::vector modelOnlyCaches(caches.begin(), caches.end() - CACHE_INPUT_TENSORDESC_OFFSET); - ret = m_device->PrepareModelFromModelCache(modelOnlyCaches, config, m_preparedModel); + bool isUpdatable = false; + ret = m_device->PrepareModelFromModelCache(modelOnlyCaches, config, m_preparedModel, isUpdatable); if (ret != OH_NN_SUCCESS) { LOGE("[NNCompiler] RestoreFromCacheFile failed, error happened when preparing model from cache."); ReleaseBufferByDevice(caches); return ret; } + + if (isUpdatable) { + LOGI("isUpdatable is true"); + + NNCompiledCacheInfo modelCacheInfo; + std::string cacheInfoPath = m_cachePath + "/" + m_extensionConfig.modelName + "cache_info.nncache"; + ret = compiledCache.CheckCacheInfo(modelCacheInfo, cacheInfoPath); + if (ret != OH_NN_SUCCESS) { + LOGE("[NNCompiledCache] isUpdatable is true to check cache info failed."); + return ret; + } + + LOGI("isUpdatable modelCacheInfo--->%{public}lld", modelCacheInfo.version); + + const size_t cacheNumber = caches.size(); + uint32_t cacheSize = NUMBER_CACHE_INFO_MEMBERS + cacheNumber; + uint32_t infoCharNumber = cacheSize * sizeof(int64_t); + + std::unique_ptr cacheInfo = CreateUniquePtr(cacheSize); + if (cacheInfo == nullptr) { + LOGE("[NNCompiledCache] isUpdatable is true to create unique failed."); + return OH_NN_MEMORY_ERROR; + } + + auto cacheInfoPtr = cacheInfo.get(); + *cacheInfoPtr++ = modelCacheInfo.fileNumber; + *cacheInfoPtr++ = modelCacheInfo.version - 1; + *cacheInfoPtr++ = modelCacheInfo.deviceId; + + for (size_t i = 0; i < modelCacheInfo.modelCheckSum.size(); ++i) { + *cacheInfoPtr++ = static_cast(modelCacheInfo.modelCheckSum[i]); + } + + ret = compiledCache.WriteCacheInfo(infoCharNumber, cacheInfo, m_cachePath); + if (ret != OH_NN_SUCCESS) { + LOGE("[NNCompiledCache] isUpdatable is true to write cache info failed."); + return ret; + } + } + ReleaseBufferByDevice(caches); m_inputTensorDescs = inputTensorDescs; diff --git a/frameworks/native/neural_network_runtime/nncompiler.h b/frameworks/native/neural_network_runtime/nncompiler.h index 5a22574d0644c0e312664bac4aec8ea8b127ad72..a1b82ad572df1a9b337bffb3acba6cde97e09f38 100644 --- a/frameworks/native/neural_network_runtime/nncompiler.h +++ b/frameworks/native/neural_network_runtime/nncompiler.h @@ -63,6 +63,7 @@ private: OH_NN_ReturnCode DeserializedTensorsFromBuffer( const Buffer& buffer, std::vector, OH_NN_TensorType>>& tensorDescs); + OH_NN_ReturnCode OnlineBuild(); OH_NN_ReturnCode NormalBuild(); OH_NN_ReturnCode BuildOfflineModel(); OH_NN_ReturnCode CheckModelParameter() const; diff --git a/frameworks/native/neural_network_runtime/nnexecutor.cpp b/frameworks/native/neural_network_runtime/nnexecutor.cpp index 187cfd49a0c554f86da4163c7cb42bbe72d2ccb4..eb1d5e2c9256b981ebf74be62b972ca3040769f5 100644 --- a/frameworks/native/neural_network_runtime/nnexecutor.cpp +++ b/frameworks/native/neural_network_runtime/nnexecutor.cpp @@ -187,6 +187,38 @@ NN_TensorDesc* NNExecutor::CreateOutputTensorDesc(size_t index) const return reinterpret_cast(tensorDescImpl); } +OH_NN_ReturnCode NNExecutor::SetExtensionConfig(const std::unordered_map>& configs) +{ + if (m_executorConfig == nullptr) { + m_executorConfig = new (std::nothrow) ExecutorConfig(); + } + + for (auto config : configs) { + if (!config.first.compare("callingPid")) { + m_executorConfig->callingPid = std::atoi(reinterpret_cast(config.second.data())); + LOGD("[NNExecutor] SetExtensionConfig, callingPid: %{public}d.", m_executorConfig->callingPid); + } + + if (!config.first.compare("hiaiModelId")) { + m_executorConfig->hiaiModelId = std::atoi(reinterpret_cast(config.second.data())); + LOGD("[NNExecutor] SetExtensionConfig, hiaiModelId: %{public}d.", m_executorConfig->hiaiModelId); + } + + if (!config.first.compare("isNeedModelLatency")) { + m_executorConfig->isNeedModelLatency = static_cast(reinterpret_cast(config.second.data())); + LOGD("[NNExecutor] SetExtensionConfig, isNeedModelLatency: %{public}d.", + m_executorConfig->isNeedModelLatency); + } + } + + return OH_NN_SUCCESS; +} + +ExecutorConfig* NNExecutor::GetExecutorConfig() const +{ + return m_executorConfig; +} + OH_NN_ReturnCode NNExecutor::SetOnRunDone(NN_OnRunDone onRunDone) { LOGE("NNExecutor::SetOnRunDone failed, SetOnRunDone is not supported."); @@ -284,6 +316,17 @@ OH_NN_ReturnCode NNExecutor::RunAsync(NN_Tensor* inputTensors[], size_t inputSiz return OH_NN_OPERATION_FORBIDDEN; } +OH_NN_ReturnCode NNExecutor::GetModelID(uint32_t& modelId) const +{ + OH_NN_ReturnCode ret = m_preparedModel->GetModelID(modelId); + if (ret != OH_NN_SUCCESS) { + LOGE("GetModelID failed, some error happen when get model id for device."); + return ret; + } + + return OH_NN_SUCCESS; +} + size_t NNExecutor::GetBackendID() { return m_backendID; diff --git a/frameworks/native/neural_network_runtime/nnexecutor.h b/frameworks/native/neural_network_runtime/nnexecutor.h index 1d2c17e6b7bb72e2e581cb8556cf806c6f8ef376..6b46fe0ceab42c19106e2d2363dee150d96e84b2 100644 --- a/frameworks/native/neural_network_runtime/nnexecutor.h +++ b/frameworks/native/neural_network_runtime/nnexecutor.h @@ -55,7 +55,10 @@ public: size_t outputSize, int32_t timeout, void* userData) override; + OH_NN_ReturnCode GetModelID(uint32_t& modelId) const override; size_t GetBackendID() override; + OH_NN_ReturnCode SetExtensionConfig(const std::unordered_map>& configs) override; + ExecutorConfig* GetExecutorConfig() const override; // The following APIs are compatible with older versions OH_NN_ReturnCode SetInput(uint32_t index, const OH_NN_Tensor& nnTensor, const void* buffer, size_t length); @@ -104,6 +107,7 @@ private: bool isInnerMem {false}; }; bool m_isRun {false}; + ExecutorConfig* m_executorConfig {nullptr}; std::unordered_map m_inputTensors; std::unordered_map m_outputTensors; std::unordered_map> m_inputCreatedMem; diff --git a/frameworks/native/neural_network_runtime/prepared_model.h b/frameworks/native/neural_network_runtime/prepared_model.h index 5c6304aab427d9e6c5b347bd45222a6f2f67a884..1b1e74d879e73cb7c23194fc872e0cb4d8e1a686 100644 --- a/frameworks/native/neural_network_runtime/prepared_model.h +++ b/frameworks/native/neural_network_runtime/prepared_model.h @@ -40,6 +40,8 @@ public: std::vector>& outputsDims, std::vector& isOutputBufferEnough) = 0; + virtual OH_NN_ReturnCode GetModelID(uint32_t& modelId) const = 0; + virtual OH_NN_ReturnCode GetInputDimRanges(std::vector>& minInputDims, std::vector>& maxInputDims) { diff --git a/test/unittest/common/v1_0/compilation_mock_idevice.cpp b/test/unittest/common/v1_0/compilation_mock_idevice.cpp index 856ad08e6527981d189148da35ab4112773e1a75..adc9ed5fcb3e6cc1493d8dc1766b1d855cca62cb 100644 --- a/test/unittest/common/v1_0/compilation_mock_idevice.cpp +++ b/test/unittest/common/v1_0/compilation_mock_idevice.cpp @@ -222,6 +222,31 @@ OH_NN_ReturnCode HDIDeviceV1_0::ReleaseBuffer(const void* buffer) return OH_NN_SUCCESS; } +OH_NN_ReturnCode HDIDeviceV1_0::PrepareModelFromModelCache(const std::vector& modelCache, + const ModelConfig& config, std::shared_ptr& preparedModel, bool& isUpdatable) +{ + if (HDI::Nnrt::V1_0::MockIPreparedModel::m_ExpectRetCode == OH_NN_FAILED) { + HDI::Nnrt::V1_0::MockIPreparedModel::m_ExpectRetCode = OH_NN_OPERATION_FORBIDDEN; + return OH_NN_FAILED; + } + + if (modelCache.size() == 0 || config.enableFloat16 == false) { + LOGE("HDIDeviceV1_0 mock PrepareModel failed, the modelCache size equals 0 or enableFloat16 is false"); + return OH_NN_FAILED; + } + + sptr hdiPreparedModel = sptr(new (std::nothrow) OHOS::HDI::Nnrt::V1_0::MockIPreparedModel()); + if (hdiPreparedModel == nullptr) { + LOGE("HDIDeviceV1_0 mock PrepareModelFromModelCache failed, error happened when new sptr"); + return OH_NN_NULL_PTR; + } + + preparedModel = CreateSharedPtr(hdiPreparedModel); + + return OH_NN_SUCCESS; +} + bool NNTensor::IsDynamicShape() const { if (HDI::Nnrt::V1_0::MockIPreparedModel::m_ExpectRetCode == OH_NN_FAILED) { diff --git a/test/unittest/common/v2_0/compilation_mock_idevice.cpp b/test/unittest/common/v2_0/compilation_mock_idevice.cpp index e101380ece135dab9a78a55086eaca862aabccca..8e0b3ec746791e365fb86da47f9e10e824d5c59d 100644 --- a/test/unittest/common/v2_0/compilation_mock_idevice.cpp +++ b/test/unittest/common/v2_0/compilation_mock_idevice.cpp @@ -222,6 +222,31 @@ OH_NN_ReturnCode HDIDeviceV2_0::ReleaseBuffer(const void* buffer) return OH_NN_SUCCESS; } +OH_NN_ReturnCode HDIDeviceV2_0::PrepareModelFromModelCache(const std::vector& modelCache, + const ModelConfig& config, std::shared_ptr& preparedModel, bool& isUpdatable) +{ + if (HDI::Nnrt::V2_0::MockIPreparedModel::m_ExpectRetCode == OH_NN_FAILED) { + HDI::Nnrt::V2_0::MockIPreparedModel::m_ExpectRetCode = OH_NN_OPERATION_FORBIDDEN; + return OH_NN_FAILED; + } + + if (modelCache.size() == 0 || config.enableFloat16 == false) { + LOGE("HDIDeviceV2_0 mock PrepareModel failed, the modelCache size equals 0 or enableFloat16 is false"); + return OH_NN_FAILED; + } + + sptr hdiPreparedModel = sptr(new (std::nothrow) OHOS::HDI::Nnrt::V2_0::MockIPreparedModel()); + if (hdiPreparedModel == nullptr) { + LOGE("HDIDeviceV2_0 mock PrepareModelFromModelCache failed, error happened when new sptr"); + return OH_NN_NULL_PTR; + } + + preparedModel = CreateSharedPtr(hdiPreparedModel); + + return OH_NN_SUCCESS; +} + bool NNTensor::IsDynamicShape() const { if (HDI::Nnrt::V2_0::MockIPreparedModel::m_ExpectRetCode == OH_NN_FAILED) { diff --git a/test/unittest/components/nn_backend/nn_backend_test.cpp b/test/unittest/components/nn_backend/nn_backend_test.cpp index 92f1d54c4290f2098864ca49e363ae90fc73996f..dbf41ffabd5f6e8761d63ecd12c0410e8d8ef4eb 100644 --- a/test/unittest/components/nn_backend/nn_backend_test.cpp +++ b/test/unittest/components/nn_backend/nn_backend_test.cpp @@ -54,9 +54,10 @@ public: MOCK_METHOD3(PrepareModel, OH_NN_ReturnCode(const void*, const ModelConfig&, std::shared_ptr&)); - MOCK_METHOD3(PrepareModelFromModelCache, OH_NN_ReturnCode(const std::vector&, + MOCK_METHOD4(PrepareModelFromModelCache, OH_NN_ReturnCode(const std::vector&, const ModelConfig&, - std::shared_ptr&)); + std::shared_ptr&, + bool&)); MOCK_METHOD3(PrepareOfflineModel, OH_NN_ReturnCode(std::shared_ptr, const ModelConfig&, std::shared_ptr&)); diff --git a/test/unittest/components/nn_compiler/nn_compiler_test.cpp b/test/unittest/components/nn_compiler/nn_compiler_test.cpp index 6af1adf9e5e4e515a9a54c01b176a2cc7bb95d2a..3f0cd78af7e115167a3990518efbaa211eb2ac00 100644 --- a/test/unittest/components/nn_compiler/nn_compiler_test.cpp +++ b/test/unittest/components/nn_compiler/nn_compiler_test.cpp @@ -55,9 +55,10 @@ public: MOCK_METHOD3(PrepareModel, OH_NN_ReturnCode(const void*, const ModelConfig&, std::shared_ptr&)); - MOCK_METHOD3(PrepareModelFromModelCache, OH_NN_ReturnCode(const std::vector&, + MOCK_METHOD4(PrepareModelFromModelCache, OH_NN_ReturnCode(const std::vector&, const ModelConfig&, - std::shared_ptr&)); + std::shared_ptr&, + bool&)); MOCK_METHOD3(PrepareOfflineModel, OH_NN_ReturnCode(std::shared_ptr, const ModelConfig&, std::shared_ptr&)); diff --git a/test/unittest/components/v1_0/hdi_device/hdi_device_test.cpp b/test/unittest/components/v1_0/hdi_device/hdi_device_test.cpp index fa924948de96d63a259d93ab4153ea9bc23d546c..5c98750e36fa8fa337d098de7967a6246ce344a6 100644 --- a/test/unittest/components/v1_0/hdi_device/hdi_device_test.cpp +++ b/test/unittest/components/v1_0/hdi_device/hdi_device_test.cpp @@ -657,7 +657,8 @@ HWTEST_F(HDIDeviceTest, hdidevice_preparemodelfrommodelcache_001, TestSize.Level EXPECT_CALL(*sp, PrepareModelFromModelCache(::testing::_, ::testing::_, ::testing::_)) .WillRepeatedly(::testing::DoAll(::testing::SetArgReferee<2>(iPreparedModel), ::testing::Return(HDF_SUCCESS))); - OH_NN_ReturnCode result = hdiDevice->PrepareModelFromModelCache(modelCache, config, preparedModel); + bool isUpdatable = false; + OH_NN_ReturnCode result = hdiDevice->PrepareModelFromModelCache(modelCache, config, preparedModel, isUpdatable); const auto &memoryManager = MemoryManager::GetInstance(); memoryManager->UnMapMemory(buffer); EXPECT_EQ(OH_NN_SUCCESS, result); @@ -693,7 +694,8 @@ HWTEST_F(HDIDeviceTest, hdidevice_preparemodelfrommodelcache_002, TestSize.Level EXPECT_CALL(*sp, PrepareModelFromModelCache(::testing::_, ::testing::_, ::testing::_)) .WillRepeatedly(::testing::DoAll(::testing::SetArgReferee<2>(iPreparedModel), ::testing::Return(HDF_FAILURE))); - OH_NN_ReturnCode result = hdiDevice->PrepareModelFromModelCache(modelCache, config, preparedModel); + bool isUpdatable = false; + OH_NN_ReturnCode result = hdiDevice->PrepareModelFromModelCache(modelCache, config, preparedModel, isUpdatable); EXPECT_EQ(OH_NN_UNAVAILABLE_DEVICE, result); } @@ -711,7 +713,8 @@ HWTEST_F(HDIDeviceTest, hdidevice_preparemodelfrommodelcache_003, TestSize.Level std::vector modelCache = { { nullptr, 0 } }; ModelConfig config; std::shared_ptr preparedModel; - OH_NN_ReturnCode result = hdiDevice->PrepareModelFromModelCache(modelCache, config, preparedModel); + bool isUpdatable = false; + OH_NN_ReturnCode result = hdiDevice->PrepareModelFromModelCache(modelCache, config, preparedModel, isUpdatable); EXPECT_EQ(OH_NN_NULL_PTR, result); } diff --git a/test/unittest/components/v2_0/hdi_device/hdi_device_test.cpp b/test/unittest/components/v2_0/hdi_device/hdi_device_test.cpp index 14c96b85dba43fa1f814117e747800abe832617e..50fbd282025b290d8b371ffb06b95cfa7047c96b 100644 --- a/test/unittest/components/v2_0/hdi_device/hdi_device_test.cpp +++ b/test/unittest/components/v2_0/hdi_device/hdi_device_test.cpp @@ -695,7 +695,8 @@ HWTEST_F(HDIDeviceTest, hdidevice_preparemodelfrommodelcache_001, TestSize.Level EXPECT_CALL(*sp, PrepareModelFromModelCache(::testing::_, ::testing::_, ::testing::_)) .WillRepeatedly(::testing::DoAll(::testing::SetArgReferee<2>(iPreparedModel), ::testing::Return(HDF_SUCCESS))); - OH_NN_ReturnCode result = hdiDevice->PrepareModelFromModelCache(modelCache, config, preparedModel); + bool isUpdatable = false; + OH_NN_ReturnCode result = hdiDevice->PrepareModelFromModelCache(modelCache, config, preparedModel, isUpdatable); const auto &memoryManager = MemoryManager::GetInstance(); memoryManager->UnMapMemory(buffer); EXPECT_EQ(OH_NN_SUCCESS, result); @@ -731,7 +732,8 @@ HWTEST_F(HDIDeviceTest, hdidevice_preparemodelfrommodelcache_002, TestSize.Level EXPECT_CALL(*sp, PrepareModelFromModelCache(::testing::_, ::testing::_, ::testing::_)) .WillRepeatedly(::testing::DoAll(::testing::SetArgReferee<2>(iPreparedModel), ::testing::Return(HDF_FAILURE))); - OH_NN_ReturnCode result = hdiDevice->PrepareModelFromModelCache(modelCache, config, preparedModel); + bool isUpdatable = false; + OH_NN_ReturnCode result = hdiDevice->PrepareModelFromModelCache(modelCache, config, preparedModel, isUpdatable); EXPECT_EQ(OH_NN_FAILED, result); } @@ -749,7 +751,8 @@ HWTEST_F(HDIDeviceTest, hdidevice_preparemodelfrommodelcache_003, TestSize.Level std::vector modelCache = { { nullptr, 0 } }; ModelConfig config; std::shared_ptr preparedModel; - OH_NN_ReturnCode result = hdiDevice->PrepareModelFromModelCache(modelCache, config, preparedModel); + bool isUpdatable = false; + OH_NN_ReturnCode result = hdiDevice->PrepareModelFromModelCache(modelCache, config, preparedModel, isUpdatable); EXPECT_EQ(OH_NN_NULL_PTR, result); }