diff --git a/README.md b/README.md index b3e11e93a7539056d402444cea4b0dbe2f8f2128..73a49d0d18d63c7122ef618febc8478a004dddf5 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ In the root directory of the OpenHarmony source code, call the following command ### API Description -- [Native API reference](https://gitee.com/openharmony-sig/interface_native_header/tree/master/en/native_sdk/ai) +- [Native API reference](https://gitee.com/openharmony/docs/blob/master/en/application-dev/reference/native-apis/_neural_network_runtime.md) - [HDI API reference](https://gitee.com/openharmony/drivers_interface/tree/master/nnrt) ### How to Use @@ -59,5 +59,5 @@ In the root directory of the OpenHarmony source code, call the following command ## Repositories Involved -- [**neural_network_runtime**](https://gitee.com/openharmony-sig/neural_network_runtime) +- [**neural_network_runtime**](https://gitee.com/openharmony/neural_network_runtime) - [third_party_mindspore](https://gitee.com/openharmony/third_party_mindspore) diff --git a/README_zh.md b/README_zh.md index cdba5b6e7788311a679a7d257560385646640d09..c60d05de86cef415b5fdbefe8b420c82eaf1812d 100644 --- a/README_zh.md +++ b/README_zh.md @@ -11,7 +11,7 @@ Neural Network Runtime与MindSpore Lite使用MindIR统一模型的中间表达 通常,AI应用、AI推理引擎、Neural Network Runtime处在同一个进程下,芯片驱动运行在另一个进程下,两者之间需要借助进程间通信(IPC)传递模型和计算数据。Neural Network Runtime根据HDI接口实现了HDI客户端,相应的,芯片厂商需要根据HDI接口实现并开放HDI服务。 **图1** Neural Network Runtime架构图 -!["Neural Network Runtime架构图"](./figures/neural_network_runtime_intro.png) +!["Neural Network Runtime架构图"](./figures/zh-cn_neural_network_runtime_intro.jpg) ## 目录 @@ -49,15 +49,15 @@ Neural Network Runtime与MindSpore Lite使用MindIR统一模型的中间表达 ### 接口说明 -- Native接口文档请参考:[Native接口](https://gitee.com/openharmony/ai_neural_network_runtime/tree/master/interfaces/kits/c)。 -- HDI接口文档请参考:[HDI接口](https://gitee.com/openharmony/drivers_interface/tree/master/nnrt)。 +- Native接口文档请参考:[Native接口](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/native-apis/_neural_nework_runtime.md)。 +- HDI接口文档请参考:[HDI接口](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/reference/hdi-apis/_n_n_rt.md)。 ### 使用说明 -- AI推理引擎/应用开发请参考:[Neural Network Runtime应用开发指导](./neural-network-runtime-guidelines.md)。 -- AI加速芯片驱动/设备开发请参考:[Neural Network Runtime设备开发指导](./example/drivers/README_zh.md)。 +- AI推理引擎/应用开发请参考:[Neural Network Runtime对接AI推理框架开发指导](./neural-network-runtime-guidelines.md)。 +- AI加速芯片驱动/设备开发请参考:[Neural Network Runtime设备接入指导](./example/drivers/README_zh.md)。 ## 相关仓 -- [**neural_network_runtime**](https://gitee.com/openharmony-sig/neural_network_runtime) +- [**neural_network_runtime**](https://gitee.com/openharmony/neural_network_runtime) - [third_party_mindspore](https://gitee.com/openharmony/third_party_mindspore) diff --git a/bundle.json b/bundle.json index 8c4a123aa6168b2f76f155b24f7610ce444a1053..73285db52bfe3ce008739908d30e5d5b33428707 100644 --- a/bundle.json +++ b/bundle.json @@ -28,6 +28,7 @@ "hdf_core", "hilog", "hitrace", + "ipc", "mindspore" ], "third_party": [] diff --git a/example/drivers/README_zh.md b/example/drivers/README_zh.md index 4098284bd37c13f1960d5a87bdb61e26b1576fca..a6bbfbec8b79efcf400acafd7976198c43b59554 100644 --- a/example/drivers/README_zh.md +++ b/example/drivers/README_zh.md @@ -1,4 +1,4 @@ -# NNRt设备开发指导 +# Neural Network Runtime设备接入指导 ## 概述 diff --git a/figures/neural_network_runtime_intro.png b/figures/neural_network_runtime_intro.png deleted file mode 100755 index aa0015e41decb3556d2e5d0e549f0e8eae35a24f..0000000000000000000000000000000000000000 Binary files a/figures/neural_network_runtime_intro.png and /dev/null differ diff --git a/figures/zh-cn_neural_network_runtime_intro.jpg b/figures/zh-cn_neural_network_runtime_intro.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5fd090696ba9e931b647aebd29f34a02c59622a9 Binary files /dev/null and b/figures/zh-cn_neural_network_runtime_intro.jpg differ diff --git a/frameworks/native/neural_network_core/backend_manager.cpp b/frameworks/native/neural_network_core/backend_manager.cpp index c392795f5a87f44a436cadf11c6ee33811b92cad..ed1027a3f49354503902d446b492aaf04ec460df 100644 --- a/frameworks/native/neural_network_core/backend_manager.cpp +++ b/frameworks/native/neural_network_core/backend_manager.cpp @@ -23,21 +23,13 @@ namespace NeuralNetworkRuntime { BackendManager::~BackendManager() { m_backends.clear(); + m_backendNames.clear(); m_backendIDs.clear(); } -std::vector BackendManager::GetAllBackendsID() +const std::vector& BackendManager::GetAllBackendsID() { - std::vector tmpBackendIds; - std::shared_ptr backend {nullptr}; - for (auto iter = m_backends.begin(); iter != m_backends.end(); ++iter) { - backend = iter->second; - if (!IsValidBackend(backend)) { - continue; - } - tmpBackendIds.emplace_back(iter->first); - } - return tmpBackendIds; + return m_backendIDs; } std::shared_ptr BackendManager::GetBackend(size_t backendID) const @@ -62,32 +54,26 @@ std::shared_ptr BackendManager::GetBackend(size_t backendID) const return iter->second; } -std::string BackendManager::GetBackendName(size_t backendID) +const std::string& BackendManager::GetBackendName(size_t backendID) { - std::string tmpBackendName; - if (m_backends.empty()) { + if (m_backendNames.empty()) { LOGE("[BackendManager] GetBackendName failed, there is no registered backend can be used."); - return tmpBackendName; + return m_emptyBackendName; } - auto iter = m_backends.begin(); + auto iter = m_backendNames.begin(); if (backendID == static_cast(0)) { LOGI("[BackendManager] the backendID is 0, default return 1st backend."); } else { - iter = m_backends.find(backendID); + iter = m_backendNames.find(backendID); } - if (iter == m_backends.end()) { + if (iter == m_backendNames.end()) { LOGE("[BackendManager] GetBackendName failed, backendID %{public}zu is not registered.", backendID); - return tmpBackendName; + return m_emptyBackendName; } - OH_NN_ReturnCode ret = iter->second->GetBackendName(tmpBackendName); - if (ret != OH_NN_SUCCESS) { - LOGE("[BackendManager] GetBackendName failed, fail to get backendName from backend."); - } - - return tmpBackendName; + return iter->second; } OH_NN_ReturnCode BackendManager::RegisterBackend(std::function()> creator) @@ -106,14 +92,22 @@ OH_NN_ReturnCode BackendManager::RegisterBackend(std::functionGetBackendID(); const std::lock_guard lock(m_mtx); - auto setResult = m_backendIDs.emplace(backendID); - if (!setResult.second) { + auto iter = std::find(m_backendIDs.begin(), m_backendIDs.end(), backendID); + if (iter != m_backendIDs.end()) { LOGE("[BackendManager] RegisterBackend failed, backend already exists, cannot register again. " "backendID=%{public}zu", backendID); return OH_NN_FAILED; } + std::string tmpBackendName; + auto ret = regBackend->GetBackendName(tmpBackendName); + if (ret != OH_NN_SUCCESS) { + LOGE("[BackendManager] RegisterBackend failed, fail to get backend name."); + return OH_NN_FAILED; + } m_backends.emplace(backendID, regBackend); + m_backendIDs.emplace_back(backendID); + m_backendNames.emplace(backendID, tmpBackendName); return OH_NN_SUCCESS; } diff --git a/frameworks/native/neural_network_core/backend_manager.h b/frameworks/native/neural_network_core/backend_manager.h index 936f254ff4f429010ac7db7bc273e639c54d2cc4..5e25e87f523435dc80b6b340e2813e10e73ceccc 100644 --- a/frameworks/native/neural_network_core/backend_manager.h +++ b/frameworks/native/neural_network_core/backend_manager.h @@ -32,9 +32,9 @@ namespace OHOS { namespace NeuralNetworkRuntime { class BackendManager { public: - std::vector GetAllBackendsID(); + const std::vector& GetAllBackendsID(); std::shared_ptr GetBackend(size_t backendID) const; - std::string GetBackendName(size_t backendID); + const std::string& GetBackendName(size_t backendID); // Register backend by C++ API OH_NN_ReturnCode RegisterBackend(std::function()> creator); @@ -60,7 +60,9 @@ private: bool IsValidBackend(std::shared_ptr backend) const; private: - std::unordered_set m_backendIDs; + std::vector m_backendIDs; + std::unordered_map m_backendNames; + std::string m_emptyBackendName; // key is the name of backend. std::unordered_map> m_backends; std::mutex m_mtx; diff --git a/frameworks/native/neural_network_core/cpp_type.h b/frameworks/native/neural_network_core/cpp_type.h index 96d6594580aeef980afc2e78013a606816986e49..faf90394b9ff8aaa1e0585c2478ef74567ea4418 100644 --- a/frameworks/native/neural_network_core/cpp_type.h +++ b/frameworks/native/neural_network_core/cpp_type.h @@ -19,6 +19,7 @@ #include #include #include +#include #include "interfaces/kits/c/neural_network_runtime/neural_network_runtime_type.h" @@ -37,6 +38,9 @@ struct ModelConfig { bool enableFloat16; OH_NN_PerformanceMode mode; OH_NN_Priority priority; + std::string isProfiling; + std::string cachePath; + std::map opLayout; }; struct Buffer { diff --git a/frameworks/native/neural_network_runtime/BUILD.gn b/frameworks/native/neural_network_runtime/BUILD.gn index 8b8995afe82a9672cdaf80fee28644c45d002d5f..f74ec5586fda4f635d28472ba174fbb38027a59e 100644 --- a/frameworks/native/neural_network_runtime/BUILD.gn +++ b/frameworks/native/neural_network_runtime/BUILD.gn @@ -30,6 +30,8 @@ nnrt_sources = [ "hdi_prepared_model_v1_0.cpp", "hdi_prepared_model_v2_0.cpp", "inner_model.cpp", + "lite_graph_to_hdi_model_v1_0.cpp", + "lite_graph_to_hdi_model_v2_0.cpp", "memory_manager.cpp", "neural_network_runtime.cpp", "neural_network_runtime_compat.cpp", @@ -127,6 +129,7 @@ ohos_shared_library("libneural_network_runtime") { "hdf_core:libhdf_utils", "hilog:libhilog", "hitrace:libhitracechain", + "ipc:ipc_core", "mindspore:mindir", ] 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 62f31123376c37ca1d7127b0759c994e6e338e79..ef69c9a13e9ee921de17b9627cfa5d857c3e72d6 100644 --- a/frameworks/native/neural_network_runtime/hdi_device_v1_0.cpp +++ b/frameworks/native/neural_network_runtime/hdi_device_v1_0.cpp @@ -19,6 +19,7 @@ #include "mindir.h" #include "hdi_prepared_model_v1_0.h" +#include "lite_graph_to_hdi_model_v1_0.h" #include "memory_manager.h" #include "transform.h" #include "common/log.h" @@ -164,7 +165,7 @@ OH_NN_ReturnCode HDIDeviceV1_0::GetSupportedOperation(std::shared_ptrGetSupportedOperation(*iModel, ops); - mindspore::lite::MindIR_Model_Destroy(&iModel); + V1::HDIModel_Destroy(&iModel); auto ret = ReleaseSharedBuffer(tensorBuffer); if (ret != OH_NN_SUCCESS) { LOGE("Release tensorBuffer failed."); @@ -255,7 +256,7 @@ OH_NN_ReturnCode HDIDeviceV1_0::PrepareModel(std::shared_ptrPrepareModel(*iModel, iModelConfig, iPreparedModel); - mindspore::lite::MindIR_Model_Destroy(&iModel); + V1::HDIModel_Destroy(&iModel); auto ret = ReleaseSharedBuffer(tensorBuffer); if (ret != OH_NN_SUCCESS) { LOGE("Release tensorBuffer failed."); 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 8b4dc3529fd65a2b601899c7be9e909015cf1c4e..221bb6b0369f7c2b0af23cc96e6e9503a6a87918 100644 --- a/frameworks/native/neural_network_runtime/hdi_device_v2_0.cpp +++ b/frameworks/native/neural_network_runtime/hdi_device_v2_0.cpp @@ -20,6 +20,7 @@ #include "securec.h" #include "hdi_prepared_model_v2_0.h" +#include "lite_graph_to_hdi_model_v2_0.h" #include "hdi_returncode_utils.h" #include "memory_manager.h" #include "transform.h" @@ -209,7 +210,7 @@ OH_NN_ReturnCode HDIDeviceV2_0::GetSupportedOperation(std::shared_ptrGetSupportedOperation(*iModel, ops); - mindspore::lite::MindIR_Model_Destroy(&iModel); + V2::HDIModel_Destroy(&iModel); innerRet = ReleaseSharedBuffer(tensorBuffer); if (innerRet != OH_NN_SUCCESS) { LOGE("Release tensorBuffer failed."); @@ -293,7 +294,7 @@ OH_NN_ReturnCode HDIDeviceV2_0::PrepareModel(std::shared_ptrPrepareModel(*iModel, iModelConfig, iPreparedModel); - mindspore::lite::MindIR_Model_Destroy(&iModel); + V2::HDIModel_Destroy(&iModel); auto innerRet = ReleaseSharedBuffer(tensorBuffer); if (innerRet != OH_NN_SUCCESS) { LOGE("Release tensorBuffer failed."); diff --git a/frameworks/native/neural_network_runtime/inner_model.cpp b/frameworks/native/neural_network_runtime/inner_model.cpp index 2b275ba0e44e0219e22a0fdd3d89a9c2d7961749..4600c51bdea4c040ea1a445fe8956cbc79639563 100644 --- a/frameworks/native/neural_network_runtime/inner_model.cpp +++ b/frameworks/native/neural_network_runtime/inner_model.cpp @@ -148,7 +148,8 @@ OH_NN_ReturnCode InnerModel::BuildFromLiteGraph(const MSLITE::LiteGraph* liteGra } OH_NN_ReturnCode InnerModel::BuildFromMetaGraph( - const void* metaGraph, const Buffer& quantBuffer, const std::string& modelName) + const void* metaGraph, const Buffer& quantBuffer, const std::string& modelName, const std::string& isProfiling, + std::map& opLayouts) { NNRT_TRACE_NAME("Build model from meta graph"); if (metaGraph == nullptr) { @@ -169,7 +170,8 @@ OH_NN_ReturnCode InnerModel::BuildFromMetaGraph( m_metaGraph = const_cast(metaGraph); m_quantBuffer = quantBuffer; m_modelName = modelName; - + m_isProfiling = isProfiling; + m_opLayouts = opLayouts; return OH_NN_SUCCESS; } @@ -421,7 +423,7 @@ OH_NN_ReturnCode InnerModel::AddOperation(OH_NN_OperationType opType, const OH_N } std::vector parameters = ConstructVectorFromArray(paramIndices.data, paramIndices.size); - Ops::OpsRegistry& opsRegistry = Ops::OpsRegistry::GetSingleton(); + const Ops::OpsRegistry& opsRegistry = Ops::OpsRegistry::GetSingleton(); std::unique_ptr opsBuilder = opsRegistry.GetOpsBuilder(opType); if (opsBuilder == nullptr) { LOGE("AddOperation failed, cannot add operation of type: %d.", opType); @@ -460,13 +462,15 @@ OH_NN_ReturnCode InnerModel::SpecifyInputsAndOutputs( m_inputIndices = ConstructVectorFromArray(inputIndices.data, inputIndices.size); m_outputIndices = ConstructVectorFromArray(outputIndices.data, outputIndices.size); - for (uint32_t i : m_inputIndices) { - m_inputTensors.emplace_back(m_allTensors[i]); - } + std::transform(m_inputIndices.begin(), m_inputIndices.end(), std::back_inserter(m_inputTensors), + [this](uint32_t i) { + return m_allTensors[i]; + }); - for (uint32_t i : m_outputIndices) { - m_outputTensors.emplace_back(m_allTensors[i]); - } + std::transform(m_outputIndices.begin(), m_outputIndices.end(), std::back_inserter(m_outputTensors), + [this](uint32_t i) { + return m_allTensors[i]; + }); return OH_NN_SUCCESS; } @@ -629,14 +633,12 @@ void InnerModel::AddTensorsToLiteGraph(std::unordered_map& m // Note: Indices in m_inputIndices and m_outputIndices have been checked in SpecifyInputAndOutput(), there is no // need to check twice. std::vector& inputIndices = m_liteGraph->input_indices_; - for (uint32_t index : m_inputIndices) { - inputIndices.emplace_back(modelIDToGraphID.at(index)); - } + std::transform(m_inputIndices.begin(), m_inputIndices.end(), std::back_inserter(inputIndices), + [modelIDToGraphID](uint32_t index) {return modelIDToGraphID.at(index);}); std::vector& outputIndices = m_liteGraph->output_indices_; - for (uint32_t index : m_outputIndices) { - outputIndices.emplace_back(modelIDToGraphID.at(index)); - } + std::transform(m_outputIndices.begin(), m_outputIndices.end(), std::back_inserter(outputIndices), + [modelIDToGraphID](uint32_t index) {return modelIDToGraphID.at(index);}); } OH_NN_ReturnCode InnerModel::AddNodesToLiteGraph(const std::unordered_map& modelIDToGraphID) @@ -762,5 +764,15 @@ std::string InnerModel::GetModelName() const { return m_modelName; } + +std::string InnerModel::GetProfiling() const +{ + return m_isProfiling; +} + +std::map InnerModel::GetOpLayouts() const +{ + return m_opLayouts; +} } // namespace NeuralNetworkRuntime } // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/neural_network_runtime/inner_model.h b/frameworks/native/neural_network_runtime/inner_model.h index a538ed07927c2f705ebf98c93119dbac8eb16784..f95862d490e92b3ea21f48a20cc943450fa67c5a 100644 --- a/frameworks/native/neural_network_runtime/inner_model.h +++ b/frameworks/native/neural_network_runtime/inner_model.h @@ -34,7 +34,8 @@ public: bool IsBuild() const; OH_NN_ReturnCode BuildFromLiteGraph(const mindspore::lite::LiteGraph* liteGraph); OH_NN_ReturnCode BuildFromMetaGraph(const void* metaGraph, const Buffer& quantBuffer, - const std::string& modelName); + const std::string& modelName, const std::string& isProfiling, + std::map& opLayouts); OH_NN_ReturnCode AddTensor(const OH_NN_Tensor& nnTensor); OH_NN_ReturnCode AddTensorDesc(const NN_TensorDesc* nnTensorDesc); OH_NN_ReturnCode SetTensorQuantParam(uint32_t index, const NN_QuantParam* quantParam); @@ -58,6 +59,8 @@ public: void* GetMetaGraph() const; Buffer GetQuantBuffer() const; std::string GetModelName() const; + std::string GetProfiling() const; + std::map GetOpLayouts() const; private: void AddTensorsToLiteGraph(std::unordered_map& modelIDToGraphID); @@ -79,6 +82,8 @@ private: void* m_metaGraph {nullptr}; Buffer m_quantBuffer = {nullptr, 0}; std::string m_modelName; + std::string m_isProfiling; + std::map m_opLayouts; }; } // namespace NeuralNetworkRuntime } // namespace OHOS diff --git a/frameworks/native/neural_network_runtime/lite_graph_to_hdi_model_v1_0.cpp b/frameworks/native/neural_network_runtime/lite_graph_to_hdi_model_v1_0.cpp new file mode 100644 index 0000000000000000000000000000000000000000..912fcd82f38d8245e5a25b290be4812bdf86d499 --- /dev/null +++ b/frameworks/native/neural_network_runtime/lite_graph_to_hdi_model_v1_0.cpp @@ -0,0 +1,1185 @@ +/* + * Copyright (c) 2024 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 "lite_graph_to_hdi_model_v1_0.h" +#include +#include +#include +#include "common/log.h" +#include "message_parcel.h" +#include "nnrt/v1_0/nnrt_types.h" +#include "nnrt/v1_0/node_attr_types.h" +#include "securec.h" + +using namespace OHOS::HDI::Nnrt::V1_0; +typedef void *PrimitivePtr; +typedef void *TensorPtr; +namespace OHOS { +namespace NeuralNetworkRuntime { +namespace V1 { +std::vector ConvertActivation(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertActivation v1 failed, primitive is nullptr."); + return {}; + } + + Activation activation{}; + activation.activationType = static_cast( + mindspore::lite::MindIR_Activation_GetActivationType(primitive)); + activation.alpha = mindspore::lite::MindIR_Activation_GetAlpha(primitive); + activation.minVal = mindspore::lite::MindIR_Activation_GetMinVal(primitive); + activation.maxVal = mindspore::lite::MindIR_Activation_GetMaxVal(primitive); + activation.approximate = mindspore::lite::MindIR_Activation_GetApproximate(primitive); + + OHOS::MessageParcel data; + (void)ActivationBlockMarshalling(data, activation); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertAddFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertAddFusion v1 failed, primitive is nullptr."); + return {}; + } + + AddFusion add_fusion{}; + add_fusion.activationType = static_cast( + mindspore::lite::MindIR_Activation_GetActivationType(primitive)); + + OHOS::MessageParcel data; + (void)AddFusionBlockMarshalling(data, add_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertArgMaxFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertArgMaxFusion v1 failed, primitive is nullptr."); + return {}; + } + + ArgMaxFusion arg_max_fusion{}; + arg_max_fusion.axis = mindspore::lite::MindIR_ArgMaxFusion_GetAxis(primitive); + arg_max_fusion.topK = mindspore::lite::MindIR_ArgMaxFusion_GetTopK(primitive); + arg_max_fusion.keepDims = mindspore::lite::MindIR_ArgMaxFusion_GetKeepDims(primitive); + arg_max_fusion.outMaxValue = mindspore::lite::MindIR_ArgMaxFusion_GetOutMaxValue(primitive); + + OHOS::MessageParcel data; + (void)ArgMaxFusionBlockMarshalling(data, arg_max_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertAvgPoolFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertAvgPoolFusion v1 failed, primitive is nullptr."); + return {}; + } + + AvgPoolFusion avg_pool_fusion{}; + avg_pool_fusion.kernelSize = mindspore::lite::MindIR_AvgPoolFusion_GetKernelSize(primitive); + avg_pool_fusion.strides = mindspore::lite::MindIR_AvgPoolFusion_GetStrides(primitive); + avg_pool_fusion.pad = mindspore::lite::MindIR_AvgPoolFusion_GetPad(primitive); + avg_pool_fusion.padMode = static_cast(mindspore::lite::MindIR_AvgPoolFusion_GetPadMode(primitive)); + avg_pool_fusion.roundMode = static_cast(mindspore::lite::MindIR_AvgPoolFusion_GetRoundMode(primitive)); + avg_pool_fusion.format = static_cast(mindspore::lite::MindIR_AvgPoolFusion_GetFormat(primitive)); + avg_pool_fusion.global = mindspore::lite::MindIR_AvgPoolFusion_GetGlobal(primitive); + avg_pool_fusion.activationType = + static_cast(mindspore::lite::MindIR_AvgPoolFusion_GetActivationType(primitive)); + + OHOS::MessageParcel data; + (void)AvgPoolFusionBlockMarshalling(data, avg_pool_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertBatchToSpaceND(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertBatchToSpaceND v1 failed, primitive is nullptr."); + return {}; + } + + BatchToSpaceND batch_to_space_n_d{}; + batch_to_space_n_d.blockShape = mindspore::lite::MindIR_BatchToSpaceND_GetBlockShape(primitive); + batch_to_space_n_d.crops = mindspore::lite::MindIR_BatchToSpaceND_GetCrops(primitive); + + OHOS::MessageParcel data; + (void)BatchToSpaceNDBlockMarshalling(data, batch_to_space_n_d); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertBiasAdd(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertBiasAdd v1 failed, primitive is nullptr."); + return {}; + } + + BiasAdd bias_add{}; + OHOS::MessageParcel data; + (void)BiasAddBlockMarshalling(data, bias_add); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertCast(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertCast v1 failed, primitive is nullptr."); + return {}; + } + + Cast cast{}; + OHOS::MessageParcel data; + (void)CastBlockMarshalling(data, cast); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertConcat(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertConcat v1 failed, primitive is nullptr."); + return {}; + } + + Concat concat{}; + concat.axis = mindspore::lite::MindIR_Concat_GetAxis(primitive); + OHOS::MessageParcel data; + (void)ConcatBlockMarshalling(data, concat); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertConv2DFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertConv2DFusion v1 failed, primitive is nullptr."); + return {}; + } + + Conv2DFusion conv2_d_fusion{}; + conv2_d_fusion.kernelSize = mindspore::lite::MindIR_Conv2DFusion_GetKernelSize(primitive); + conv2_d_fusion.stride = mindspore::lite::MindIR_Conv2DFusion_GetStride(primitive); + conv2_d_fusion.dilation = mindspore::lite::MindIR_Conv2DFusion_GetDilation(primitive); + conv2_d_fusion.padMode = static_cast(mindspore::lite::MindIR_Conv2DFusion_GetPadMode(primitive)); + conv2_d_fusion.padList = mindspore::lite::MindIR_Conv2DFusion_GetPadList(primitive); + conv2_d_fusion.group = mindspore::lite::MindIR_Conv2DFusion_GetGroup(primitive); + conv2_d_fusion.inChannel = mindspore::lite::MindIR_Conv2DFusion_GetInChannel(primitive); + conv2_d_fusion.outChannel = mindspore::lite::MindIR_Conv2DFusion_GetOutChannel(primitive); + conv2_d_fusion.activationType = static_cast( + mindspore::lite::MindIR_Conv2DFusion_GetActivationType(primitive)); + + OHOS::MessageParcel data; + (void)Conv2DFusionBlockMarshalling(data, conv2_d_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertConv2dTransposeFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertConv2dTransposeFusion v1 failed, primitive is nullptr."); + return {}; + } + + Conv2dTransposeFusion conv2d_transpose_fusion{}; + conv2d_transpose_fusion.kernelSize = mindspore::lite::MindIR_Conv2dTransposeFusion_GetKernelSize(primitive); + conv2d_transpose_fusion.stride = mindspore::lite::MindIR_Conv2dTransposeFusion_GetStride(primitive); + conv2d_transpose_fusion.dilation = mindspore::lite::MindIR_Conv2dTransposeFusion_GetDilation(primitive); + conv2d_transpose_fusion.padMode = static_cast( + mindspore::lite::MindIR_Conv2dTransposeFusion_GetPadMode(primitive)); + conv2d_transpose_fusion.padList = mindspore::lite::MindIR_Conv2dTransposeFusion_GetPadList(primitive); + conv2d_transpose_fusion.group = mindspore::lite::MindIR_Conv2dTransposeFusion_GetGroup(primitive); + conv2d_transpose_fusion.inChannel = mindspore::lite::MindIR_Conv2dTransposeFusion_GetInChannel(primitive); + conv2d_transpose_fusion.outChannel = mindspore::lite::MindIR_Conv2dTransposeFusion_GetOutChannel(primitive); + conv2d_transpose_fusion.activationType = static_cast( + mindspore::lite::MindIR_Conv2dTransposeFusion_GetActivationType(primitive)); + conv2d_transpose_fusion.outputPaddings = mindspore::lite::MindIR_Conv2dTransposeFusion_GetOutputPaddings(primitive); + + OHOS::MessageParcel data; + (void)Conv2dTransposeFusionBlockMarshalling(data, conv2d_transpose_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertDivFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertDivFusion v1 failed, primitive is nullptr."); + return {}; + } + + DivFusion div_fusion{}; + div_fusion.activationType = static_cast( + mindspore::lite::MindIR_DivFusion_GetActivationType(primitive)); + OHOS::MessageParcel data; + (void)DivFusionBlockMarshalling(data, div_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertEltwise(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertEltwise v1 failed, primitive is nullptr."); + return {}; + } + + Eltwise eltwise{}; + eltwise.mode = static_cast(mindspore::lite::MindIR_Eltwise_GetMode(primitive)); + OHOS::MessageParcel data; + (void)EltwiseBlockMarshalling(data, eltwise); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertExpandDims(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertExpandDims v1 failed, primitive is nullptr."); + return {}; + } + + ExpandDims expand_dims{}; + OHOS::MessageParcel data; + (void)ExpandDimsBlockMarshalling(data, expand_dims); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertFill(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertFill v1 failed, primitive is nullptr."); + return {}; + } + + Fill fill{}; + OHOS::MessageParcel data; + (void)FillBlockMarshalling(data, fill); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertFullConnection(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertFullConnection v1 failed, primitive is nullptr."); + return {}; + } + + FullConnection full_connection{}; + full_connection.hasBias = mindspore::lite::MindIR_FullConnection_GetHasBias(primitive); + full_connection.useAxis = mindspore::lite::MindIR_FullConnection_GetUseAxis(primitive); + full_connection.axis = mindspore::lite::MindIR_FullConnection_GetAxis(primitive); + full_connection.activationType = static_cast( + mindspore::lite::MindIR_FullConnection_GetActivationType(primitive)); + + OHOS::MessageParcel data; + (void)FullConnectionBlockMarshalling(data, full_connection); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertFusedBatchNorm(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertFusedBatchNorm v1 failed, primitive is nullptr."); + return {}; + } + + FusedBatchNorm fused_batch_norm{}; + fused_batch_norm.epsilon = mindspore::lite::MindIR_FusedBatchNorm_GetEpsilon(primitive); + OHOS::MessageParcel data; + (void)FusedBatchNormBlockMarshalling(data, fused_batch_norm); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertGather(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertGather v1 failed, primitive is nullptr."); + return {}; + } + + Gather gather{}; + OHOS::MessageParcel data; + (void)GatherBlockMarshalling(data, gather); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertLayerNormFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertGather v1 failed, primitive is nullptr."); + return {}; + } + + LayerNormFusion layer_norm_fusion{}; + layer_norm_fusion.beginNormAxis = mindspore::lite::MindIR_LayerNormFusion_GetBeginNormAxis(primitive); + layer_norm_fusion.epsilon = mindspore::lite::MindIR_LayerNormFusion_GetEpsilon(primitive); + layer_norm_fusion.elementwiseAffine = mindspore::lite::MindIR_LayerNormFusion_GetElementwiseAffine(primitive); + layer_norm_fusion.beginParamsAxis = mindspore::lite::MindIR_LayerNormFusion_GetBeginParamsAxis(primitive); + + OHOS::MessageParcel data; + (void)LayerNormFusionBlockMarshalling(data, layer_norm_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertLessEqual(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertLessEqual v1 failed, primitive is nullptr."); + return {}; + } + + LessEqual less_equal{}; + OHOS::MessageParcel data; + (void)LessEqualBlockMarshalling(data, less_equal); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertMatMulFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertMatMulFusion v1 failed, primitive is nullptr."); + return {}; + } + + MatMulFusion mat_mul_fusion{}; + mat_mul_fusion.transposeA = mindspore::lite::MindIR_MatMulFusion_GetTransposeA(primitive); + mat_mul_fusion.transposeB = mindspore::lite::MindIR_MatMulFusion_GetTransposeB(primitive); + mat_mul_fusion.activationType = static_cast( + mindspore::lite::MindIR_MatMulFusion_GetActivationType(primitive)); + + OHOS::MessageParcel data; + (void)MatMulFusionBlockMarshalling(data, mat_mul_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertMaximum(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertMaximum v1 failed, primitive is nullptr."); + return {}; + } + + Maximum maximum{}; + OHOS::MessageParcel data; + (void)MaximumBlockMarshalling(data, maximum); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertMaxPoolFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertMaxPoolFusion v1 failed, primitive is nullptr."); + return {}; + } + + MaxPoolFusion max_pool_fusion{}; + max_pool_fusion.kernelSize = mindspore::lite::MindIR_MaxPoolFusion_GetKernelSize(primitive); + max_pool_fusion.strides = mindspore::lite::MindIR_MaxPoolFusion_GetStrides(primitive); + max_pool_fusion.pad = mindspore::lite::MindIR_MaxPoolFusion_GetPad(primitive); + max_pool_fusion.padMode = static_cast(mindspore::lite::MindIR_MaxPoolFusion_GetPadMode(primitive)); + max_pool_fusion.format = static_cast(mindspore::lite::MindIR_MaxPoolFusion_GetFormat(primitive)); + max_pool_fusion.global = mindspore::lite::MindIR_MaxPoolFusion_GetGlobal(primitive); + max_pool_fusion.activationType = static_cast( + mindspore::lite::MindIR_MaxPoolFusion_GetActivationType(primitive)); + + OHOS::MessageParcel data; + (void)MaxPoolFusionBlockMarshalling(data, max_pool_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertMulFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertMulFusion v1 failed, primitive is nullptr."); + return {}; + } + + MulFusion mul_fusion{}; + mul_fusion.activationType = static_cast( + mindspore::lite::MindIR_MulFusion_GetActivationType(primitive)); + OHOS::MessageParcel data; + (void)MulFusionBlockMarshalling(data, mul_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertOneHot(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertOneHot v1 failed, primitive is nullptr."); + return {}; + } + + OneHot one_hot{}; + one_hot.axis = mindspore::lite::MindIR_OneHot_GetAxis(primitive); + OHOS::MessageParcel data; + (void)OneHotBlockMarshalling(data, one_hot); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertPadFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertPadFusion v1 failed, primitive is nullptr."); + return {}; + } + + PadFusion pad_fusion{}; + pad_fusion.paddings = mindspore::lite::MindIR_PadFusion_GetPaddings(primitive); + pad_fusion.paddingMode = static_cast(mindspore::lite::MindIR_PadFusion_GetPaddingMode(primitive)); + pad_fusion.constantValue = mindspore::lite::MindIR_PadFusion_GetConstantValue(primitive); + OHOS::MessageParcel data; + (void)PadFusionBlockMarshalling(data, pad_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertPowFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertPowFusion v1 failed, primitive is nullptr."); + return {}; + } + + PowFusion pow_fusion{}; + pow_fusion.scale = mindspore::lite::MindIR_PowFusion_GetScale(primitive); + pow_fusion.shift = mindspore::lite::MindIR_PowFusion_GetShift(primitive); + OHOS::MessageParcel data; + (void)PowFusionBlockMarshalling(data, pow_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertPReLUFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertPReLUFusion v1 failed, primitive is nullptr."); + return {}; + } + + PReLUFusion p_re_l_u_fusion{}; + p_re_l_u_fusion.channelShared = mindspore::lite::MindIR_PReLUFusion_GetChannelShared(primitive); + OHOS::MessageParcel data; + (void)PReLUFusionBlockMarshalling(data, p_re_l_u_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertQuantDTypeCast(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertPReLUFusion v1 failed, primitive is nullptr."); + return {}; + } + + QuantDTypeCast quant_d_type_cast{}; + quant_d_type_cast.srcT = mindspore::lite::MindIR_QuantDTypeCast_GetSrcT(primitive); + quant_d_type_cast.dstT = mindspore::lite::MindIR_QuantDTypeCast_GetDstT(primitive); + OHOS::MessageParcel data; + (void)QuantDTypeCastBlockMarshalling(data, quant_d_type_cast); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertReduceFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertReduceFusion v1 failed, primitive is nullptr."); + return {}; + } + + ReduceFusion reduce_fusion{}; + reduce_fusion.keepDims = mindspore::lite::MindIR_ReduceFusion_GetKeepDims(primitive); + reduce_fusion.mode = static_cast(mindspore::lite::MindIR_ReduceFusion_GetMode(primitive)); + reduce_fusion.reduceToEnd = mindspore::lite::MindIR_ReduceFusion_GetReduceToEnd(primitive); + reduce_fusion.coeff = mindspore::lite::MindIR_ReduceFusion_GetCoeff(primitive); + OHOS::MessageParcel data; + (void)ReduceFusionBlockMarshalling(data, reduce_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertReshape(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertReshape v1 failed, primitive is nullptr."); + return {}; + } + + Reshape reshape{}; + OHOS::MessageParcel data; + (void)ReshapeBlockMarshalling(data, reshape); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertResize(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertResize v1 failed, primitive is nullptr."); + return {}; + } + + Resize resize{}; + resize.method = static_cast(mindspore::lite::MindIR_Resize_GetMethod(primitive)); + resize.newHeight = mindspore::lite::MindIR_Resize_GetNewHeight(primitive); + resize.newWidth = mindspore::lite::MindIR_Resize_GetNewWidth(primitive); + resize.preserveAspectRatio = mindspore::lite::MindIR_Resize_GetPreserveAspectRatio(primitive); + resize.coordinateTransformMode = + static_cast(mindspore::lite::MindIR_Resize_GetCoordinateTransformMode(primitive)); + resize.cubicCoeff = mindspore::lite::MindIR_Resize_GetCubicCoeff(primitive); + resize.excludeOutside = mindspore::lite::MindIR_Resize_GetExcludeOutside(primitive); + resize.extrapolationValue = mindspore::lite::MindIR_Resize_GetExtrapolationValue(primitive); + resize.nearestMode = static_cast(mindspore::lite::MindIR_Resize_GetNearestMode(primitive)); + OHOS::MessageParcel data; + (void)ResizeBlockMarshalling(data, resize); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertRsqrt(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertRsqrt v1 failed, primitive is nullptr."); + return {}; + } + + Rsqrt rsqrt{}; + OHOS::MessageParcel data; + (void)RsqrtBlockMarshalling(data, rsqrt); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertScaleFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertScaleFusion v1 failed, primitive is nullptr."); + return {}; + } + + ScaleFusion scale_fusion{}; + scale_fusion.axis = mindspore::lite::MindIR_ScaleFusion_GetAxis(primitive); + scale_fusion.activationType = static_cast( + mindspore::lite::MindIR_ScaleFusion_GetActivationType(primitive)); + OHOS::MessageParcel data; + (void)ScaleFusionBlockMarshalling(data, scale_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertShape(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertShape v1 failed, primitive is nullptr."); + return {}; + } + + Shape shape{}; + OHOS::MessageParcel data; + (void)ShapeBlockMarshalling(data, shape); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} +std::vector ConvertSliceFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertSliceFusion v1 failed, primitive is nullptr."); + return {}; + } + + SliceFusion slice_fusion{}; + slice_fusion.axes = mindspore::lite::MindIR_SliceFusion_GetAxes(primitive); + OHOS::MessageParcel data; + (void)SliceFusionBlockMarshalling(data, slice_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertSoftmax(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertSoftmax v1 failed, primitive is nullptr."); + return {}; + } + + Softmax softmax{}; + softmax.axis = mindspore::lite::MindIR_Softmax_GetAxis(primitive); + OHOS::MessageParcel data; + (void)SoftmaxBlockMarshalling(data, softmax); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertSpaceToBatchND(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertSpaceToBatchND v1 failed, primitive is nullptr."); + return {}; + } + + SpaceToBatchND space_to_batch_n_d{}; + space_to_batch_n_d.blockShape = mindspore::lite::MindIR_SpaceToBatchND_GetBlockShape(primitive); + space_to_batch_n_d.paddings = mindspore::lite::MindIR_SpaceToBatchND_GetPaddings(primitive); + OHOS::MessageParcel data; + (void)SpaceToBatchNDBlockMarshalling(data, space_to_batch_n_d); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertSplit(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertSplit v1 failed, primitive is nullptr."); + return {}; + } + + Split split{}; + split.outputNum = mindspore::lite::MindIR_Split_GetOutputNum(primitive); + split.sizeSplits = mindspore::lite::MindIR_Split_GetSizeSplits(primitive); + split.axis = mindspore::lite::MindIR_Split_GetAxis(primitive); + OHOS::MessageParcel data; + (void)SplitBlockMarshalling(data, split); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertSqrt(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertSqrt v1 failed, primitive is nullptr."); + return {}; + } + + Sqrt sqrt{}; + OHOS::MessageParcel data; + (void)SqrtBlockMarshalling(data, sqrt); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} +std::vector ConvertSquaredDifference(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertSquaredDifference v1 failed, primitive is nullptr."); + return {}; + } + + SquaredDifference squared_difference{}; + OHOS::MessageParcel data; + (void)SquaredDifferenceBlockMarshalling(data, squared_difference); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertSqueeze(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertSqueeze v1 failed, primitive is nullptr."); + return {}; + } + + Squeeze squeeze{}; + squeeze.axis = mindspore::lite::MindIR_Squeeze_GetAxis(primitive); + OHOS::MessageParcel data; + (void)SqueezeBlockMarshalling(data, squeeze); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertStack(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertStack v1 failed, primitive is nullptr."); + return {}; + } + + Stack stack{}; + stack.axis = mindspore::lite::MindIR_Stack_GetAxis(primitive); + OHOS::MessageParcel data; + (void)StackBlockMarshalling(data, stack); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertStridedSlice(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertStridedSlice v1 failed, primitive is nullptr."); + return {}; + } + + StridedSlice strided_slice{}; + strided_slice.beginMask = mindspore::lite::MindIR_StridedSlice_GetBeginMask(primitive); + strided_slice.endMask = mindspore::lite::MindIR_StridedSlice_GetEndMask(primitive); + strided_slice.ellipsisMask = mindspore::lite::MindIR_StridedSlice_GetEllipsisMask(primitive); + strided_slice.newAxisMask = mindspore::lite::MindIR_StridedSlice_GetNewAxisMask(primitive); + strided_slice.shrinkAxisMask = mindspore::lite::MindIR_StridedSlice_GetShrinkAxisMask(primitive); + OHOS::MessageParcel data; + (void)StridedSliceBlockMarshalling(data, strided_slice); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertSubFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertSubFusion v1 failed, primitive is nullptr."); + return {}; + } + + SubFusion sub_fusion{}; + sub_fusion.activationType = static_cast( + mindspore::lite::MindIR_SubFusion_GetActivationType(primitive)); + OHOS::MessageParcel data; + (void)SubFusionBlockMarshalling(data, sub_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertTileFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertTileFusion v1 failed, primitive is nullptr."); + return {}; + } + + TileFusion tile_fusion{}; + tile_fusion.dims = mindspore::lite::MindIR_TileFusion_GetDims(primitive); + OHOS::MessageParcel data; + (void)TileFusionBlockMarshalling(data, tile_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertTopKFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertTopKFusion v1 failed, primitive is nullptr."); + return {}; + } + + TopKFusion top_k_fusion{}; + top_k_fusion.sorted = mindspore::lite::MindIR_TopKFusion_GetSorted(primitive); + top_k_fusion.axis = mindspore::lite::MindIR_TopKFusion_GetAxis(primitive); + OHOS::MessageParcel data; + (void)TopKFusionBlockMarshalling(data, top_k_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertTranspose(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertTranspose v1 failed, primitive is nullptr."); + return {}; + } + + Transpose transpose{}; + OHOS::MessageParcel data; + (void)TransposeBlockMarshalling(data, transpose); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertUnsqueeze(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertUnsqueeze v1 failed, primitive is nullptr."); + return {}; + } + + Unsqueeze unsqueeze{}; + unsqueeze.axis = mindspore::lite::MindIR_Unsqueeze_GetAxis(primitive); + OHOS::MessageParcel data; + (void)UnsqueezeBlockMarshalling(data, unsqueeze); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector Convert(NodeType type, PrimitivePtr primitive) +{ + switch (type) { + case NODE_TYPE_ACTIVATION: + return ConvertActivation(primitive); + break; + case NODE_TYPE_ADD_FUSION: + return ConvertAddFusion(primitive); + break; + case NODE_TYPE_ARGMAX_FUSION: + return ConvertArgMaxFusion(primitive); + break; + case NODE_TYPE_AVGPOOL_FUSION: + return ConvertAvgPoolFusion(primitive); + break; + case NODE_TYPE_BATCH_TO_SPACE_ND: + return ConvertBatchToSpaceND(primitive); + break; + case NODE_TYPE_BIAS_ADD: + return ConvertBiasAdd(primitive); + break; + case NODE_TYPE_CAST: + return ConvertCast(primitive); + break; + case NODE_TYPE_CONCAT: + return ConvertConcat(primitive); + break; + case NODE_TYPE_CONV2D_FUSION: + return ConvertConv2DFusion(primitive); + break; + case NODE_TYPE_CONV2D_TRANSPOSE_FUSION: + return ConvertConv2dTransposeFusion(primitive); + break; + case NODE_TYPE_DIV_FUSION: + return ConvertDivFusion(primitive); + break; + case NODE_TYPE_ELTWISE: + return ConvertEltwise(primitive); + break; + case NODE_TYPE_EXPAND_DIMS: + return ConvertExpandDims(primitive); + break; + case NODE_TYPE_FILL: + return ConvertFill(primitive); + break; + case NODE_TYPE_FULL_CONNECTION: + return ConvertFullConnection(primitive); + break; + case NODE_TYPE_FUSED_BATCH_NORM: + return ConvertFusedBatchNorm(primitive); + break; + case NODE_TYPE_GATHER: + return ConvertGather(primitive); + break; + case NODE_TYPE_LAYER_NORM_FUSION: + return ConvertLayerNormFusion(primitive); + break; + case NODE_TYPE_LESS_EQUAL: + return ConvertLessEqual(primitive); + break; + case NODE_TYPE_MATMUL_FUSION: + return ConvertMatMulFusion(primitive); + break; + case NODE_TYPE_MAXIMUM: + return ConvertMaximum(primitive); + break; + case NODE_TYPE_MAX_POOL_FUSION: + return ConvertMaxPoolFusion(primitive); + break; + case NODE_TYPE_MUL_FUSION: + return ConvertMulFusion(primitive); + break; + case NODE_TYPE_ONE_HOT: + return ConvertOneHot(primitive); + break; + case NODE_TYPE_PAD_FUSION: + return ConvertPadFusion(primitive); + break; + case NODE_TYPE_POW_FUSION: + return ConvertPowFusion(primitive); + break; + case NODE_TYPE_PRELU_FUSION: + return ConvertPReLUFusion(primitive); + break; + case NODE_TYPE_QUANT_DTYPE_CAST: + return ConvertQuantDTypeCast(primitive); + break; + case NODE_TYPE_REDUCE_FUSION: + return ConvertReduceFusion(primitive); + break; + case NODE_TYPE_RESHAPE: + return ConvertReshape(primitive); + break; + case NODE_TYPE_RESIZE: + return ConvertResize(primitive); + break; + case NODE_TYPE_RSQRT: + return ConvertRsqrt(primitive); + break; + case NODE_TYPE_SCALE_FUSION: + return ConvertScaleFusion(primitive); + break; + case NODE_TYPE_SHAPE: + return ConvertShape(primitive); + break; + case NODE_TYPE_SLICE_FUSION: + return ConvertSliceFusion(primitive); + break; + case NODE_TYPE_SOFTMAX: + return ConvertSoftmax(primitive); + break; + case NODE_TYPE_SPACE_TO_BATCH_ND: + return ConvertSpaceToBatchND(primitive); + break; + case NODE_TYPE_SPLIT: + return ConvertSplit(primitive); + break; + case NODE_TYPE_SQRT: + return ConvertSqrt(primitive); + break; + case NODE_TYPE_SQUARED_DIFFERENCE: + return ConvertSquaredDifference(primitive); + break; + case NODE_TYPE_SQUEEZE: + return ConvertSqueeze(primitive); + break; + case NODE_TYPE_STACK: + return ConvertStack(primitive); + break; + case NODE_TYPE_STRIDED_SLICE: + return ConvertStridedSlice(primitive); + break; + case NODE_TYPE_SUB_FUSION: + return ConvertSubFusion(primitive); + break; + case NODE_TYPE_TILE_FUSION: + return ConvertTileFusion(primitive); + break; + case NODE_TYPE_TOPK_FUSION: + return ConvertTopKFusion(primitive); + break; + case NODE_TYPE_TRANSPOSE: + return ConvertTranspose(primitive); + break; + case NODE_TYPE_UNSQUEEZE: + return ConvertUnsqueeze(primitive); + break; + default: + return {}; + } +} + +inline std::vector MindIR_Tensor_GetQuantParams_OHOS(TensorPtr tensor) +{ + if (tensor != nullptr) { + std::vector result; + auto src = mindspore::lite::MindIR_Tensor_GetQuantParams(tensor); + if (src.empty()) { + return {}; + } + size_t size = src.size(); + for (size_t i = 0; i < size; i++) { + OHOS::HDI::Nnrt::V1_0::QuantParam quantParam{src[i].numBits, src[i].zeroPoint, src[i].scale}; + result.emplace_back(quantParam); + } + return result; + } else { + return {}; + } +} + +void HDIModel_Destroy(OHOS::HDI::Nnrt::V1_0::Model **model) +{ + if (model != nullptr && *model != nullptr) { + auto model_data = *model; + delete (model_data); + *model = nullptr; + } +} + +OHOS::HDI::Nnrt::V1_0::SharedBuffer Copy_MindIR_Tensor_Data_To_HDIBuffer(const TensorPtr tensor, + const OHOS::HDI::Nnrt::V1_0::SharedBuffer &buffer_templete, uint8_t *mmap_ptr, unsigned int offset) +{ + if (tensor == nullptr) { + LOGE(""); + return {-1, 0, offset, 0}; + } + if (mmap_ptr == nullptr) { + LOGE("Tensor GetData failed, mmap pointer should not be nullptr"); + return {-1, 0, offset, 0}; + } + + OHOS::HDI::Nnrt::V1_0::SharedBuffer result{}; + std::vector data = mindspore::lite::MindIR_Tensor_GetData(tensor); + if (data.empty()) { + result.fd = -1; + result.bufferSize = buffer_templete.bufferSize; + result.offset = offset; + result.dataSize = 0; + return result; + } + result.fd = buffer_templete.fd; + result.bufferSize = buffer_templete.bufferSize; + auto ret = memcpy_s(mmap_ptr + offset, data.size(), data.data(), data.size()); + if (ret != EOK) { + LOGE("Tensor memcpy failed."); + return {-1, 0, offset, 0}; + } + result.offset = offset; + result.dataSize = data.size(); + return result; +} + +OHOS::HDI::Nnrt::V1_0::Model *LiteGraph_To_HDIModel(const mindspore::lite::LiteGraph *lite_graph, + const OHOS::HDI::Nnrt::V1_0::SharedBuffer &buffer) +{ + if (lite_graph == nullptr) { + LOGE("MindIR_LiteGraph_To_Model v1 failed, lite graph is nullptr."); + return nullptr; + } + + LOGI("MindIR_LiteGraph_To_Model begin"); // todo 改称hitrace + + std::vector inputIndex; + std::vector outputIndex; + std::vector nodes; + std::vector allTensors; + std::vector subGraph; + + // nodes + for (auto node : lite_graph->all_nodes_) { + if (node == nullptr) { + LOGE("MindIR_LiteGraph_To_Model v1 failed, node is nullptr."); + return nullptr; + } + OHOS::HDI::Nnrt::V1_0::Node tmp; + tmp.name = node->name_; + if (node->primitive_ == nullptr) { + LOGE("MindIR_LiteGraph_To_Model v1 failed, node primitive is nullptr."); + return nullptr; + } + tmp.nodeType = static_cast(mindspore::lite::MindIR_Primitive_GetType(node->primitive_)); + tmp.nodeAttr = Convert(tmp.nodeType, node->primitive_); + tmp.inputIndex = node->input_indices_; + tmp.outputIndex = node->output_indices_; + tmp.quantType = static_cast(node->quant_type_); + nodes.emplace_back(tmp); + } + + // Tensor + unsigned int tensor_buffer_offset = 0; + uint8_t *mmap_ptr = nullptr; + if (buffer.fd != -1) { + mmap_ptr = + static_cast(mmap(nullptr, buffer.bufferSize, PROT_READ | PROT_WRITE, MAP_SHARED, buffer.fd, 0)); + if (mmap_ptr == MAP_FAILED) { + LOGE("MindIR_LiteGraph_To_Model v1 failed, mmap failed."); + return nullptr; + } + } + for (auto tensor : lite_graph->all_tensors_) { + OHOS::HDI::Nnrt::V1_0::Tensor tmp; + tmp.name = mindspore::lite::MindIR_Tensor_GetName(tensor); + tmp.dataType = static_cast(mindspore::lite::MindIR_Tensor_GetDataType(tensor)); + tmp.dims = mindspore::lite::MindIR_Tensor_GetDims(tensor); + tmp.format = static_cast(mindspore::lite::MindIR_Tensor_GetFormat(tensor)); + tmp.data = Copy_MindIR_Tensor_Data_To_HDIBuffer(tensor, buffer, mmap_ptr, tensor_buffer_offset); // todo 实现 + tmp.quantParams = MindIR_Tensor_GetQuantParams_OHOS(tensor); + allTensors.emplace_back(tmp); + tensor_buffer_offset = tmp.data.offset + tmp.data.dataSize; + } + if (buffer.fd != -1) { + auto munmap_res = munmap(mmap_ptr, buffer.bufferSize); + if (munmap_res != 0) { + LOGE("MindIR_LiteGraph_To_Model v1 failed, unmap failed."); + return nullptr; + } + } + + // SubGraph + for (auto graph : lite_graph->sub_graphs_) { + OHOS::HDI::Nnrt::V1_0::SubGraph tmp; + tmp.name = graph->name_; + tmp.inputIndices = std::vector(graph->input_indices_); + tmp.outputIndices = std::vector(graph->output_indices_); + tmp.nodeIndices = std::vector(graph->node_indices_); + subGraph.emplace_back(tmp); + } + + auto *ret_model = new (std::nothrow) Model(); + if (ret_model == nullptr) { + LOGE("MindIR_LiteGraph_To_Model v1 failed, new Model failed."); + return nullptr; + } + ret_model->name = lite_graph->name_; + ret_model->inputIndex = lite_graph->input_indices_; + ret_model->outputIndex = lite_graph->output_indices_; + ret_model->nodes = nodes; + ret_model->allTensors = allTensors; + ret_model->subGraph = subGraph; + return ret_model; +} + +} // V1 +} // NeuralNetworkRuntime +} // OHOS \ No newline at end of file diff --git a/frameworks/native/neural_network_runtime/lite_graph_to_hdi_model_v1_0.h b/frameworks/native/neural_network_runtime/lite_graph_to_hdi_model_v1_0.h new file mode 100644 index 0000000000000000000000000000000000000000..fd562c7697be638d0af1fb98d6d7412e97d94e56 --- /dev/null +++ b/frameworks/native/neural_network_runtime/lite_graph_to_hdi_model_v1_0.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 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_LITEGRAPH_TO_HDIMODEL_V1_0_H +#define NEURAL_NETWORK_RUNTIME_LITEGRAPH_TO_HDIMODEL_V1_0_H + +#include "mindir.h" +#include "nnrt/v1_0/model_types.h" + +namespace OHOS { +namespace NeuralNetworkRuntime { +namespace V1 { +void HDIModel_Destroy(OHOS::HDI::Nnrt::V1_0::Model **model); +OHOS::HDI::Nnrt::V1_0::Model *LiteGraph_To_HDIModel(const mindspore::lite::LiteGraph *lite_graph, + const OHOS::HDI::Nnrt::V1_0::SharedBuffer &buffer); +} // V1 +} // NeuralNetworkRuntime +} // OHOS + +#endif // NEURAL_NETWORK_RUNTIME_LITEGRAPH_TO_HDIMODEL_V1_0_H \ No newline at end of file diff --git a/frameworks/native/neural_network_runtime/lite_graph_to_hdi_model_v2_0.cpp b/frameworks/native/neural_network_runtime/lite_graph_to_hdi_model_v2_0.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9125f33d6430edcc8ee29d3186e9603f4d7fd195 --- /dev/null +++ b/frameworks/native/neural_network_runtime/lite_graph_to_hdi_model_v2_0.cpp @@ -0,0 +1,1186 @@ +/* + * Copyright (c) 2024 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 "lite_graph_to_hdi_model_v2_0.h" +#include +#include +#include +#include "common/log.h" +#include "message_parcel.h" +#include "nnrt/v2_0/nnrt_types.h" +#include "nnrt/v2_0/node_attr_types.h" +#include "securec.h" + +using namespace OHOS::HDI::Nnrt::V2_0; +typedef void *PrimitivePtr; +typedef void *TensorPtr; +namespace OHOS { +namespace NeuralNetworkRuntime { +namespace V2 { +std::vector ConvertActivation(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertActivation v2 failed, primitive is nullptr."); + return {}; + } + + Activation activation{}; + activation.activationType = static_cast( + mindspore::lite::MindIR_Activation_GetActivationType(primitive)); + activation.alpha = mindspore::lite::MindIR_Activation_GetAlpha(primitive); + activation.minVal = mindspore::lite::MindIR_Activation_GetMinVal(primitive); + activation.maxVal = mindspore::lite::MindIR_Activation_GetMaxVal(primitive); + activation.approximate = mindspore::lite::MindIR_Activation_GetApproximate(primitive); + + OHOS::MessageParcel data; + (void)ActivationBlockMarshalling(data, activation); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertAddFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertAddFusion v2 failed, primitive is nullptr."); + return {}; + } + + AddFusion add_fusion{}; + add_fusion.activationType = static_cast( + mindspore::lite::MindIR_Activation_GetActivationType(primitive)); + + OHOS::MessageParcel data; + (void)AddFusionBlockMarshalling(data, add_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertArgMaxFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertArgMaxFusion v2 failed, primitive is nullptr."); + return {}; + } + + ArgMaxFusion arg_max_fusion{}; + arg_max_fusion.axis = mindspore::lite::MindIR_ArgMaxFusion_GetAxis(primitive); + arg_max_fusion.topK = mindspore::lite::MindIR_ArgMaxFusion_GetTopK(primitive); + arg_max_fusion.keepDims = mindspore::lite::MindIR_ArgMaxFusion_GetKeepDims(primitive); + arg_max_fusion.outMaxValue = mindspore::lite::MindIR_ArgMaxFusion_GetOutMaxValue(primitive); + + OHOS::MessageParcel data; + (void)ArgMaxFusionBlockMarshalling(data, arg_max_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertAvgPoolFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertAvgPoolFusion v2 failed, primitive is nullptr."); + return {}; + } + + AvgPoolFusion avg_pool_fusion{}; + avg_pool_fusion.kernelSize = mindspore::lite::MindIR_AvgPoolFusion_GetKernelSize(primitive); + avg_pool_fusion.strides = mindspore::lite::MindIR_AvgPoolFusion_GetStrides(primitive); + avg_pool_fusion.pad = mindspore::lite::MindIR_AvgPoolFusion_GetPad(primitive); + avg_pool_fusion.padMode = static_cast(mindspore::lite::MindIR_AvgPoolFusion_GetPadMode(primitive)); + avg_pool_fusion.roundMode = static_cast(mindspore::lite::MindIR_AvgPoolFusion_GetRoundMode(primitive)); + avg_pool_fusion.format = static_cast(mindspore::lite::MindIR_AvgPoolFusion_GetFormat(primitive)); + avg_pool_fusion.global = mindspore::lite::MindIR_AvgPoolFusion_GetGlobal(primitive); + avg_pool_fusion.activationType = + static_cast(mindspore::lite::MindIR_AvgPoolFusion_GetActivationType(primitive)); + + OHOS::MessageParcel data; + (void)AvgPoolFusionBlockMarshalling(data, avg_pool_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertBatchToSpaceND(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertBatchToSpaceND v2 failed, primitive is nullptr."); + return {}; + } + + BatchToSpaceND batch_to_space_n_d{}; + batch_to_space_n_d.blockShape = mindspore::lite::MindIR_BatchToSpaceND_GetBlockShape(primitive); + batch_to_space_n_d.crops = mindspore::lite::MindIR_BatchToSpaceND_GetCrops(primitive); + + OHOS::MessageParcel data; + (void)BatchToSpaceNDBlockMarshalling(data, batch_to_space_n_d); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertBiasAdd(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertBiasAdd v2 failed, primitive is nullptr."); + return {}; + } + + BiasAdd bias_add{}; + OHOS::MessageParcel data; + (void)BiasAddBlockMarshalling(data, bias_add); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertCast(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertCast v2 failed, primitive is nullptr."); + return {}; + } + + Cast cast{}; + OHOS::MessageParcel data; + (void)CastBlockMarshalling(data, cast); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertConcat(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertConcat v2 failed, primitive is nullptr."); + return {}; + } + + Concat concat{}; + concat.axis = mindspore::lite::MindIR_Concat_GetAxis(primitive); + OHOS::MessageParcel data; + (void)ConcatBlockMarshalling(data, concat); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertConv2DFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertConv2DFusion v2 failed, primitive is nullptr."); + return {}; + } + + Conv2DFusion conv2_d_fusion{}; + conv2_d_fusion.kernelSize = mindspore::lite::MindIR_Conv2DFusion_GetKernelSize(primitive); + conv2_d_fusion.stride = mindspore::lite::MindIR_Conv2DFusion_GetStride(primitive); + conv2_d_fusion.dilation = mindspore::lite::MindIR_Conv2DFusion_GetDilation(primitive); + conv2_d_fusion.padMode = static_cast(mindspore::lite::MindIR_Conv2DFusion_GetPadMode(primitive)); + conv2_d_fusion.padList = mindspore::lite::MindIR_Conv2DFusion_GetPadList(primitive); + conv2_d_fusion.group = mindspore::lite::MindIR_Conv2DFusion_GetGroup(primitive); + conv2_d_fusion.inChannel = mindspore::lite::MindIR_Conv2DFusion_GetInChannel(primitive); + conv2_d_fusion.outChannel = mindspore::lite::MindIR_Conv2DFusion_GetOutChannel(primitive); + conv2_d_fusion.activationType = static_cast( + mindspore::lite::MindIR_Conv2DFusion_GetActivationType(primitive)); + + OHOS::MessageParcel data; + (void)Conv2DFusionBlockMarshalling(data, conv2_d_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertConv2dTransposeFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertConv2dTransposeFusion v2 failed, primitive is nullptr."); + return {}; + } + + Conv2dTransposeFusion conv2d_transpose_fusion{}; + conv2d_transpose_fusion.kernelSize = mindspore::lite::MindIR_Conv2dTransposeFusion_GetKernelSize(primitive); + conv2d_transpose_fusion.stride = mindspore::lite::MindIR_Conv2dTransposeFusion_GetStride(primitive); + conv2d_transpose_fusion.dilation = mindspore::lite::MindIR_Conv2dTransposeFusion_GetDilation(primitive); + conv2d_transpose_fusion.padMode = static_cast( + mindspore::lite::MindIR_Conv2dTransposeFusion_GetPadMode(primitive)); + conv2d_transpose_fusion.padList = mindspore::lite::MindIR_Conv2dTransposeFusion_GetPadList(primitive); + conv2d_transpose_fusion.group = mindspore::lite::MindIR_Conv2dTransposeFusion_GetGroup(primitive); + conv2d_transpose_fusion.inChannel = mindspore::lite::MindIR_Conv2dTransposeFusion_GetInChannel(primitive); + conv2d_transpose_fusion.outChannel = mindspore::lite::MindIR_Conv2dTransposeFusion_GetOutChannel(primitive); + conv2d_transpose_fusion.activationType = static_cast( + mindspore::lite::MindIR_Conv2dTransposeFusion_GetActivationType(primitive)); + conv2d_transpose_fusion.outputPaddings = mindspore::lite::MindIR_Conv2dTransposeFusion_GetOutputPaddings(primitive); + + OHOS::MessageParcel data; + (void)Conv2dTransposeFusionBlockMarshalling(data, conv2d_transpose_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertDivFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertDivFusion v2 failed, primitive is nullptr."); + return {}; + } + + DivFusion div_fusion{}; + div_fusion.activationType = static_cast( + mindspore::lite::MindIR_DivFusion_GetActivationType(primitive)); + OHOS::MessageParcel data; + (void)DivFusionBlockMarshalling(data, div_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertEltwise(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertEltwise v2 failed, primitive is nullptr."); + return {}; + } + + Eltwise eltwise{}; + eltwise.mode = static_cast(mindspore::lite::MindIR_Eltwise_GetMode(primitive)); + OHOS::MessageParcel data; + (void)EltwiseBlockMarshalling(data, eltwise); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertExpandDims(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertExpandDims v2 failed, primitive is nullptr."); + return {}; + } + + ExpandDims expand_dims{}; + OHOS::MessageParcel data; + (void)ExpandDimsBlockMarshalling(data, expand_dims); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertFill(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertFill v2 failed, primitive is nullptr."); + return {}; + } + + Fill fill{}; + OHOS::MessageParcel data; + (void)FillBlockMarshalling(data, fill); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertFullConnection(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertFullConnection v2 failed, primitive is nullptr."); + return {}; + } + + FullConnection full_connection{}; + full_connection.hasBias = mindspore::lite::MindIR_FullConnection_GetHasBias(primitive); + full_connection.useAxis = mindspore::lite::MindIR_FullConnection_GetUseAxis(primitive); + full_connection.axis = mindspore::lite::MindIR_FullConnection_GetAxis(primitive); + full_connection.activationType = static_cast( + mindspore::lite::MindIR_FullConnection_GetActivationType(primitive)); + + OHOS::MessageParcel data; + (void)FullConnectionBlockMarshalling(data, full_connection); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertFusedBatchNorm(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertFusedBatchNorm v2 failed, primitive is nullptr."); + return {}; + } + + FusedBatchNorm fused_batch_norm{}; + fused_batch_norm.epsilon = mindspore::lite::MindIR_FusedBatchNorm_GetEpsilon(primitive); + OHOS::MessageParcel data; + (void)FusedBatchNormBlockMarshalling(data, fused_batch_norm); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertGather(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertGather v2 failed, primitive is nullptr."); + return {}; + } + + Gather gather{}; + OHOS::MessageParcel data; + (void)GatherBlockMarshalling(data, gather); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertLayerNormFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertGather v2 failed, primitive is nullptr."); + return {}; + } + + LayerNormFusion layer_norm_fusion{}; + layer_norm_fusion.beginNormAxis = mindspore::lite::MindIR_LayerNormFusion_GetBeginNormAxis(primitive); + layer_norm_fusion.epsilon = mindspore::lite::MindIR_LayerNormFusion_GetEpsilon(primitive); + layer_norm_fusion.elementwiseAffine = mindspore::lite::MindIR_LayerNormFusion_GetElementwiseAffine(primitive); + layer_norm_fusion.beginParamsAxis = mindspore::lite::MindIR_LayerNormFusion_GetBeginParamsAxis(primitive); + + OHOS::MessageParcel data; + (void)LayerNormFusionBlockMarshalling(data, layer_norm_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertLessEqual(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertLessEqual v2 failed, primitive is nullptr."); + return {}; + } + + LessEqual less_equal{}; + OHOS::MessageParcel data; + (void)LessEqualBlockMarshalling(data, less_equal); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertMatMulFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertMatMulFusion v2 failed, primitive is nullptr."); + return {}; + } + + MatMulFusion mat_mul_fusion{}; + mat_mul_fusion.transposeA = mindspore::lite::MindIR_MatMulFusion_GetTransposeA(primitive); + mat_mul_fusion.transposeB = mindspore::lite::MindIR_MatMulFusion_GetTransposeB(primitive); + mat_mul_fusion.activationType = static_cast( + mindspore::lite::MindIR_MatMulFusion_GetActivationType(primitive)); + + OHOS::MessageParcel data; + (void)MatMulFusionBlockMarshalling(data, mat_mul_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertMaximum(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertMaximum v2 failed, primitive is nullptr."); + return {}; + } + + Maximum maximum{}; + OHOS::MessageParcel data; + (void)MaximumBlockMarshalling(data, maximum); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertMaxPoolFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertMaxPoolFusion v2 failed, primitive is nullptr."); + return {}; + } + + MaxPoolFusion max_pool_fusion{}; + max_pool_fusion.kernelSize = mindspore::lite::MindIR_MaxPoolFusion_GetKernelSize(primitive); + max_pool_fusion.strides = mindspore::lite::MindIR_MaxPoolFusion_GetStrides(primitive); + max_pool_fusion.pad = mindspore::lite::MindIR_MaxPoolFusion_GetPad(primitive); + max_pool_fusion.padMode = static_cast(mindspore::lite::MindIR_MaxPoolFusion_GetPadMode(primitive)); + max_pool_fusion.format = static_cast(mindspore::lite::MindIR_MaxPoolFusion_GetFormat(primitive)); + max_pool_fusion.roundMode = static_cast(mindspore::lite::MindIR_MaxPoolFusion_GetRoundMode(primitive)); + max_pool_fusion.global = mindspore::lite::MindIR_MaxPoolFusion_GetGlobal(primitive); + max_pool_fusion.activationType = static_cast( + mindspore::lite::MindIR_MaxPoolFusion_GetActivationType(primitive)); + + OHOS::MessageParcel data; + (void)MaxPoolFusionBlockMarshalling(data, max_pool_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertMulFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertMulFusion v2 failed, primitive is nullptr."); + return {}; + } + + MulFusion mul_fusion{}; + mul_fusion.activationType = static_cast( + mindspore::lite::MindIR_MulFusion_GetActivationType(primitive)); + OHOS::MessageParcel data; + (void)MulFusionBlockMarshalling(data, mul_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertOneHot(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertOneHot v2 failed, primitive is nullptr."); + return {}; + } + + OneHot one_hot{}; + one_hot.axis = mindspore::lite::MindIR_OneHot_GetAxis(primitive); + OHOS::MessageParcel data; + (void)OneHotBlockMarshalling(data, one_hot); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertPadFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertPadFusion v2 failed, primitive is nullptr."); + return {}; + } + + PadFusion pad_fusion{}; + pad_fusion.paddings = mindspore::lite::MindIR_PadFusion_GetPaddings(primitive); + pad_fusion.paddingMode = static_cast(mindspore::lite::MindIR_PadFusion_GetPaddingMode(primitive)); + pad_fusion.constantValue = mindspore::lite::MindIR_PadFusion_GetConstantValue(primitive); + OHOS::MessageParcel data; + (void)PadFusionBlockMarshalling(data, pad_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertPowFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertPowFusion v2 failed, primitive is nullptr."); + return {}; + } + + PowFusion pow_fusion{}; + pow_fusion.scale = mindspore::lite::MindIR_PowFusion_GetScale(primitive); + pow_fusion.shift = mindspore::lite::MindIR_PowFusion_GetShift(primitive); + OHOS::MessageParcel data; + (void)PowFusionBlockMarshalling(data, pow_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertPReLUFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertPReLUFusion v2 failed, primitive is nullptr."); + return {}; + } + + PReLUFusion p_re_l_u_fusion{}; + p_re_l_u_fusion.channelShared = mindspore::lite::MindIR_PReLUFusion_GetChannelShared(primitive); + OHOS::MessageParcel data; + (void)PReLUFusionBlockMarshalling(data, p_re_l_u_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertQuantDTypeCast(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertPReLUFusion v2 failed, primitive is nullptr."); + return {}; + } + + QuantDTypeCast quant_d_type_cast{}; + quant_d_type_cast.srcT = mindspore::lite::MindIR_QuantDTypeCast_GetSrcT(primitive); + quant_d_type_cast.dstT = mindspore::lite::MindIR_QuantDTypeCast_GetDstT(primitive); + OHOS::MessageParcel data; + (void)QuantDTypeCastBlockMarshalling(data, quant_d_type_cast); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertReduceFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertReduceFusion v2 failed, primitive is nullptr."); + return {}; + } + + ReduceFusion reduce_fusion{}; + reduce_fusion.keepDims = mindspore::lite::MindIR_ReduceFusion_GetKeepDims(primitive); + reduce_fusion.mode = static_cast(mindspore::lite::MindIR_ReduceFusion_GetMode(primitive)); + reduce_fusion.reduceToEnd = mindspore::lite::MindIR_ReduceFusion_GetReduceToEnd(primitive); + reduce_fusion.coeff = mindspore::lite::MindIR_ReduceFusion_GetCoeff(primitive); + OHOS::MessageParcel data; + (void)ReduceFusionBlockMarshalling(data, reduce_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertReshape(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertReshape v2 failed, primitive is nullptr."); + return {}; + } + + Reshape reshape{}; + OHOS::MessageParcel data; + (void)ReshapeBlockMarshalling(data, reshape); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertResize(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertResize v2 failed, primitive is nullptr."); + return {}; + } + + Resize resize{}; + resize.method = static_cast(mindspore::lite::MindIR_Resize_GetMethod(primitive)); + resize.newHeight = mindspore::lite::MindIR_Resize_GetNewHeight(primitive); + resize.newWidth = mindspore::lite::MindIR_Resize_GetNewWidth(primitive); + resize.preserveAspectRatio = mindspore::lite::MindIR_Resize_GetPreserveAspectRatio(primitive); + resize.coordinateTransformMode = + static_cast(mindspore::lite::MindIR_Resize_GetCoordinateTransformMode(primitive)); + resize.cubicCoeff = mindspore::lite::MindIR_Resize_GetCubicCoeff(primitive); + resize.excludeOutside = mindspore::lite::MindIR_Resize_GetExcludeOutside(primitive); + resize.extrapolationValue = mindspore::lite::MindIR_Resize_GetExtrapolationValue(primitive); + resize.nearestMode = static_cast(mindspore::lite::MindIR_Resize_GetNearestMode(primitive)); + OHOS::MessageParcel data; + (void)ResizeBlockMarshalling(data, resize); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertRsqrt(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertRsqrt v2 failed, primitive is nullptr."); + return {}; + } + + Rsqrt rsqrt{}; + OHOS::MessageParcel data; + (void)RsqrtBlockMarshalling(data, rsqrt); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertScaleFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertScaleFusion v2 failed, primitive is nullptr."); + return {}; + } + + ScaleFusion scale_fusion{}; + scale_fusion.axis = mindspore::lite::MindIR_ScaleFusion_GetAxis(primitive); + scale_fusion.activationType = static_cast( + mindspore::lite::MindIR_ScaleFusion_GetActivationType(primitive)); + OHOS::MessageParcel data; + (void)ScaleFusionBlockMarshalling(data, scale_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertShape(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertShape v2 failed, primitive is nullptr."); + return {}; + } + + Shape shape{}; + OHOS::MessageParcel data; + (void)ShapeBlockMarshalling(data, shape); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} +std::vector ConvertSliceFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertSliceFusion v2 failed, primitive is nullptr."); + return {}; + } + + SliceFusion slice_fusion{}; + slice_fusion.axes = mindspore::lite::MindIR_SliceFusion_GetAxes(primitive); + OHOS::MessageParcel data; + (void)SliceFusionBlockMarshalling(data, slice_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertSoftmax(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertSoftmax v2 failed, primitive is nullptr."); + return {}; + } + + Softmax softmax{}; + softmax.axis = mindspore::lite::MindIR_Softmax_GetAxis(primitive); + OHOS::MessageParcel data; + (void)SoftmaxBlockMarshalling(data, softmax); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertSpaceToBatchND(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertSpaceToBatchND v2 failed, primitive is nullptr."); + return {}; + } + + SpaceToBatchND space_to_batch_n_d{}; + space_to_batch_n_d.blockShape = mindspore::lite::MindIR_SpaceToBatchND_GetBlockShape(primitive); + space_to_batch_n_d.paddings = mindspore::lite::MindIR_SpaceToBatchND_GetPaddings(primitive); + OHOS::MessageParcel data; + (void)SpaceToBatchNDBlockMarshalling(data, space_to_batch_n_d); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertSplit(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertSplit v2 failed, primitive is nullptr."); + return {}; + } + + Split split{}; + split.outputNum = mindspore::lite::MindIR_Split_GetOutputNum(primitive); + split.sizeSplits = mindspore::lite::MindIR_Split_GetSizeSplits(primitive); + split.axis = mindspore::lite::MindIR_Split_GetAxis(primitive); + OHOS::MessageParcel data; + (void)SplitBlockMarshalling(data, split); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertSqrt(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertSqrt v2 failed, primitive is nullptr."); + return {}; + } + + Sqrt sqrt{}; + OHOS::MessageParcel data; + (void)SqrtBlockMarshalling(data, sqrt); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} +std::vector ConvertSquaredDifference(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertSquaredDifference v2 failed, primitive is nullptr."); + return {}; + } + + SquaredDifference squared_difference{}; + OHOS::MessageParcel data; + (void)SquaredDifferenceBlockMarshalling(data, squared_difference); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertSqueeze(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertSqueeze v2 failed, primitive is nullptr."); + return {}; + } + + Squeeze squeeze{}; + squeeze.axis = mindspore::lite::MindIR_Squeeze_GetAxis(primitive); + OHOS::MessageParcel data; + (void)SqueezeBlockMarshalling(data, squeeze); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertStack(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertStack v2 failed, primitive is nullptr."); + return {}; + } + + Stack stack{}; + stack.axis = mindspore::lite::MindIR_Stack_GetAxis(primitive); + OHOS::MessageParcel data; + (void)StackBlockMarshalling(data, stack); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertStridedSlice(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertStridedSlice v2 failed, primitive is nullptr."); + return {}; + } + + StridedSlice strided_slice{}; + strided_slice.beginMask = mindspore::lite::MindIR_StridedSlice_GetBeginMask(primitive); + strided_slice.endMask = mindspore::lite::MindIR_StridedSlice_GetEndMask(primitive); + strided_slice.ellipsisMask = mindspore::lite::MindIR_StridedSlice_GetEllipsisMask(primitive); + strided_slice.newAxisMask = mindspore::lite::MindIR_StridedSlice_GetNewAxisMask(primitive); + strided_slice.shrinkAxisMask = mindspore::lite::MindIR_StridedSlice_GetShrinkAxisMask(primitive); + OHOS::MessageParcel data; + (void)StridedSliceBlockMarshalling(data, strided_slice); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertSubFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertSubFusion v2 failed, primitive is nullptr."); + return {}; + } + + SubFusion sub_fusion{}; + sub_fusion.activationType = static_cast( + mindspore::lite::MindIR_SubFusion_GetActivationType(primitive)); + OHOS::MessageParcel data; + (void)SubFusionBlockMarshalling(data, sub_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertTileFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertTileFusion v2 failed, primitive is nullptr."); + return {}; + } + + TileFusion tile_fusion{}; + tile_fusion.dims = mindspore::lite::MindIR_TileFusion_GetDims(primitive); + OHOS::MessageParcel data; + (void)TileFusionBlockMarshalling(data, tile_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertTopKFusion(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertTopKFusion v2 failed, primitive is nullptr."); + return {}; + } + + TopKFusion top_k_fusion{}; + top_k_fusion.sorted = mindspore::lite::MindIR_TopKFusion_GetSorted(primitive); + top_k_fusion.axis = mindspore::lite::MindIR_TopKFusion_GetAxis(primitive); + OHOS::MessageParcel data; + (void)TopKFusionBlockMarshalling(data, top_k_fusion); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertTranspose(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertTranspose v2 failed, primitive is nullptr."); + return {}; + } + + Transpose transpose{}; + OHOS::MessageParcel data; + (void)TransposeBlockMarshalling(data, transpose); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector ConvertUnsqueeze(PrimitivePtr primitive) +{ + if (primitive == nullptr) { + LOGE("ConvertUnsqueeze v2 failed, primitive is nullptr."); + return {}; + } + + Unsqueeze unsqueeze{}; + unsqueeze.axis = mindspore::lite::MindIR_Unsqueeze_GetAxis(primitive); + OHOS::MessageParcel data; + (void)UnsqueezeBlockMarshalling(data, unsqueeze); + std::vector ret(reinterpret_cast(data.GetData()), + reinterpret_cast(data.GetData()) + data.GetDataSize()); + return ret; +} + +std::vector Convert(NodeType type, PrimitivePtr primitive) +{ + switch (type) { + case NODE_TYPE_ACTIVATION: + return ConvertActivation(primitive); + break; + case NODE_TYPE_ADD_FUSION: + return ConvertAddFusion(primitive); + break; + case NODE_TYPE_ARGMAX_FUSION: + return ConvertArgMaxFusion(primitive); + break; + case NODE_TYPE_AVGPOOL_FUSION: + return ConvertAvgPoolFusion(primitive); + break; + case NODE_TYPE_BATCH_TO_SPACE_ND: + return ConvertBatchToSpaceND(primitive); + break; + case NODE_TYPE_BIAS_ADD: + return ConvertBiasAdd(primitive); + break; + case NODE_TYPE_CAST: + return ConvertCast(primitive); + break; + case NODE_TYPE_CONCAT: + return ConvertConcat(primitive); + break; + case NODE_TYPE_CONV2D_FUSION: + return ConvertConv2DFusion(primitive); + break; + case NODE_TYPE_CONV2D_TRANSPOSE_FUSION: + return ConvertConv2dTransposeFusion(primitive); + break; + case NODE_TYPE_DIV_FUSION: + return ConvertDivFusion(primitive); + break; + case NODE_TYPE_ELTWISE: + return ConvertEltwise(primitive); + break; + case NODE_TYPE_EXPAND_DIMS: + return ConvertExpandDims(primitive); + break; + case NODE_TYPE_FILL: + return ConvertFill(primitive); + break; + case NODE_TYPE_FULL_CONNECTION: + return ConvertFullConnection(primitive); + break; + case NODE_TYPE_FUSED_BATCH_NORM: + return ConvertFusedBatchNorm(primitive); + break; + case NODE_TYPE_GATHER: + return ConvertGather(primitive); + break; + case NODE_TYPE_LAYER_NORM_FUSION: + return ConvertLayerNormFusion(primitive); + break; + case NODE_TYPE_LESS_EQUAL: + return ConvertLessEqual(primitive); + break; + case NODE_TYPE_MATMUL_FUSION: + return ConvertMatMulFusion(primitive); + break; + case NODE_TYPE_MAXIMUM: + return ConvertMaximum(primitive); + break; + case NODE_TYPE_MAX_POOL_FUSION: + return ConvertMaxPoolFusion(primitive); + break; + case NODE_TYPE_MUL_FUSION: + return ConvertMulFusion(primitive); + break; + case NODE_TYPE_ONE_HOT: + return ConvertOneHot(primitive); + break; + case NODE_TYPE_PAD_FUSION: + return ConvertPadFusion(primitive); + break; + case NODE_TYPE_POW_FUSION: + return ConvertPowFusion(primitive); + break; + case NODE_TYPE_PRELU_FUSION: + return ConvertPReLUFusion(primitive); + break; + case NODE_TYPE_QUANT_DTYPE_CAST: + return ConvertQuantDTypeCast(primitive); + break; + case NODE_TYPE_REDUCE_FUSION: + return ConvertReduceFusion(primitive); + break; + case NODE_TYPE_RESHAPE: + return ConvertReshape(primitive); + break; + case NODE_TYPE_RESIZE: + return ConvertResize(primitive); + break; + case NODE_TYPE_RSQRT: + return ConvertRsqrt(primitive); + break; + case NODE_TYPE_SCALE_FUSION: + return ConvertScaleFusion(primitive); + break; + case NODE_TYPE_SHAPE: + return ConvertShape(primitive); + break; + case NODE_TYPE_SLICE_FUSION: + return ConvertSliceFusion(primitive); + break; + case NODE_TYPE_SOFTMAX: + return ConvertSoftmax(primitive); + break; + case NODE_TYPE_SPACE_TO_BATCH_ND: + return ConvertSpaceToBatchND(primitive); + break; + case NODE_TYPE_SPLIT: + return ConvertSplit(primitive); + break; + case NODE_TYPE_SQRT: + return ConvertSqrt(primitive); + break; + case NODE_TYPE_SQUARED_DIFFERENCE: + return ConvertSquaredDifference(primitive); + break; + case NODE_TYPE_SQUEEZE: + return ConvertSqueeze(primitive); + break; + case NODE_TYPE_STACK: + return ConvertStack(primitive); + break; + case NODE_TYPE_STRIDED_SLICE: + return ConvertStridedSlice(primitive); + break; + case NODE_TYPE_SUB_FUSION: + return ConvertSubFusion(primitive); + break; + case NODE_TYPE_TILE_FUSION: + return ConvertTileFusion(primitive); + break; + case NODE_TYPE_TOPK_FUSION: + return ConvertTopKFusion(primitive); + break; + case NODE_TYPE_TRANSPOSE: + return ConvertTranspose(primitive); + break; + case NODE_TYPE_UNSQUEEZE: + return ConvertUnsqueeze(primitive); + break; + default: + return {}; + } +} + +inline std::vector MindIR_Tensor_GetQuantParams_OHOS(TensorPtr tensor) +{ + if (tensor != nullptr) { + std::vector result; + auto src = mindspore::lite::MindIR_Tensor_GetQuantParams(tensor); + if (src.empty()) { + return {}; + } + size_t size = src.size(); + for (size_t i = 0; i < size; i++) { + OHOS::HDI::Nnrt::V2_0::QuantParam quantParam{src[i].numBits, src[i].zeroPoint, src[i].scale}; + result.emplace_back(quantParam); + } + return result; + } else { + return {}; + } +} + +void HDIModel_Destroy(OHOS::HDI::Nnrt::V2_0::Model **model) +{ + if (model != nullptr && *model != nullptr) { + auto model_data = *model; + delete (model_data); + *model = nullptr; + } +} + +OHOS::HDI::Nnrt::V2_0::SharedBuffer Copy_MindIR_Tensor_Data_To_HDIBuffer(const TensorPtr tensor, + const OHOS::HDI::Nnrt::V2_0::SharedBuffer &buffer_templete, uint8_t *mmap_ptr, unsigned int offset) +{ + if (tensor == nullptr) { + LOGE(""); + return {-1, 0, offset, 0}; + } + if (mmap_ptr == nullptr) { + LOGE("Tensor GetData failed, mmap pointer should not be nullptr"); + return {-1, 0, offset, 0}; + } + + OHOS::HDI::Nnrt::V2_0::SharedBuffer result{}; + std::vector data = mindspore::lite::MindIR_Tensor_GetData(tensor); + if (data.empty()) { + result.fd = -1; + result.bufferSize = buffer_templete.bufferSize; + result.offset = offset; + result.dataSize = 0; + return result; + } + result.fd = buffer_templete.fd; + result.bufferSize = buffer_templete.bufferSize; + auto ret = memcpy_s(mmap_ptr + offset, data.size(), data.data(), data.size()); + if (ret != EOK) { + LOGE("Tensor memcpy failed."); + return {-1, 0, offset, 0}; + } + result.offset = offset; + result.dataSize = data.size(); + return result; +} + +OHOS::HDI::Nnrt::V2_0::Model *LiteGraph_To_HDIModel(const mindspore::lite::LiteGraph *lite_graph, + const OHOS::HDI::Nnrt::V2_0::SharedBuffer &buffer) +{ + if (lite_graph == nullptr) { + LOGE("MindIR_LiteGraph_To_Model v2 failed, lite graph is nullptr."); + return nullptr; + } + + LOGI("MindIR_LiteGraph_To_Model begin"); // todo 改称hitrace + + std::vector inputIndex; + std::vector outputIndex; + std::vector nodes; + std::vector allTensors; + std::vector subGraph; + + // nodes + for (auto node : lite_graph->all_nodes_) { + if (node == nullptr) { + LOGE("MindIR_LiteGraph_To_Model v2 failed, node is nullptr."); + return nullptr; + } + OHOS::HDI::Nnrt::V2_0::Node tmp; + tmp.name = node->name_; + if (node->primitive_ == nullptr) { + LOGE("MindIR_LiteGraph_To_Model v2 failed, node primitive is nullptr."); + return nullptr; + } + tmp.nodeType = static_cast(mindspore::lite::MindIR_Primitive_GetType(node->primitive_)); + tmp.nodeAttr = Convert(tmp.nodeType, node->primitive_); + tmp.inputIndex = node->input_indices_; + tmp.outputIndex = node->output_indices_; + tmp.quantType = static_cast(node->quant_type_); + nodes.emplace_back(tmp); + } + + // Tensor + unsigned int tensor_buffer_offset = 0; + uint8_t *mmap_ptr = nullptr; + if (buffer.fd != -1) { + mmap_ptr = + static_cast(mmap(nullptr, buffer.bufferSize, PROT_READ | PROT_WRITE, MAP_SHARED, buffer.fd, 0)); + if (mmap_ptr == MAP_FAILED) { + LOGE("MindIR_LiteGraph_To_Model v2 failed, mmap failed."); + return nullptr; + } + } + for (auto tensor : lite_graph->all_tensors_) { + OHOS::HDI::Nnrt::V2_0::Tensor tmp; + tmp.name = mindspore::lite::MindIR_Tensor_GetName(tensor); + tmp.dataType = static_cast(mindspore::lite::MindIR_Tensor_GetDataType(tensor)); + tmp.dims = mindspore::lite::MindIR_Tensor_GetDims(tensor); + tmp.format = static_cast(mindspore::lite::MindIR_Tensor_GetFormat(tensor)); + tmp.data = Copy_MindIR_Tensor_Data_To_HDIBuffer(tensor, buffer, mmap_ptr, tensor_buffer_offset); // todo 实现 + tmp.quantParams = MindIR_Tensor_GetQuantParams_OHOS(tensor); + allTensors.emplace_back(tmp); + tensor_buffer_offset = tmp.data.offset + tmp.data.dataSize; + } + if (buffer.fd != -1) { + auto munmap_res = munmap(mmap_ptr, buffer.bufferSize); + if (munmap_res != 0) { + LOGE("MindIR_LiteGraph_To_Model v2 failed, unmap failed."); + return nullptr; + } + } + + // SubGraph + for (auto graph : lite_graph->sub_graphs_) { + OHOS::HDI::Nnrt::V2_0::SubGraph tmp; + tmp.name = graph->name_; + tmp.inputIndices = std::vector(graph->input_indices_); + tmp.outputIndices = std::vector(graph->output_indices_); + tmp.nodeIndices = std::vector(graph->node_indices_); + subGraph.emplace_back(tmp); + } + + auto *ret_model = new (std::nothrow) Model(); + if (ret_model == nullptr) { + LOGE("MindIR_LiteGraph_To_Model v2 failed, new Model failed."); + return nullptr; + } + ret_model->name = lite_graph->name_; + ret_model->inputIndex = lite_graph->input_indices_; + ret_model->outputIndex = lite_graph->output_indices_; + ret_model->nodes = nodes; + ret_model->allTensors = allTensors; + ret_model->subGraph = subGraph; + return ret_model; +} + +} // V2 +} // NeuralNetworkRuntime +} // OHOS \ No newline at end of file diff --git a/frameworks/native/neural_network_runtime/lite_graph_to_hdi_model_v2_0.h b/frameworks/native/neural_network_runtime/lite_graph_to_hdi_model_v2_0.h new file mode 100644 index 0000000000000000000000000000000000000000..3724da79b9119ef56284e21c4e987ee6f40ce4c9 --- /dev/null +++ b/frameworks/native/neural_network_runtime/lite_graph_to_hdi_model_v2_0.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 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_LITEGRAPH_TO_HDIMODEL_V2_0_H +#define NEURAL_NETWORK_RUNTIME_LITEGRAPH_TO_HDIMODEL_V2_0_H + +#include "mindir.h" +#include "nnrt/v2_0/model_types.h" + +namespace OHOS { +namespace NeuralNetworkRuntime { +namespace V2 { +void HDIModel_Destroy(OHOS::HDI::Nnrt::V2_0::Model **model); +OHOS::HDI::Nnrt::V2_0::Model *LiteGraph_To_HDIModel(const mindspore::lite::LiteGraph *lite_graph, + const OHOS::HDI::Nnrt::V2_0::SharedBuffer &buffer); +} // V2 +} // NeuralNetworkRuntime +} // OHOS + +#endif // NEURAL_NETWORK_RUNTIME_LITEGRAPH_TO_HDIMODEL_V2_0_H \ No newline at end of file diff --git a/frameworks/native/neural_network_runtime/memory_manager.cpp b/frameworks/native/neural_network_runtime/memory_manager.cpp index 1c6cc874438c3adced65f6963ebe1a64e84807b1..969efa43085d5e43fe5207b1338b0039924b3034 100644 --- a/frameworks/native/neural_network_runtime/memory_manager.cpp +++ b/frameworks/native/neural_network_runtime/memory_manager.cpp @@ -31,7 +31,7 @@ void* MemoryManager::MapMemory(int fd, size_t length) return nullptr; } - if (length <= 0 || length > ALLOCATE_BUFFER_LIMIT) { + if (length == 0 || length > ALLOCATE_BUFFER_LIMIT) { LOGE("Invalid buffer size, it must greater than 0 and less than 1Gb. length=%zu", length); return nullptr; } diff --git a/frameworks/native/neural_network_runtime/neural_network_runtime.cpp b/frameworks/native/neural_network_runtime/neural_network_runtime.cpp index 6207fe41aaae3188e75e864fd0f3a47ba2ad160d..c8f502eed01c6ad27c876c24f0f1e8331abc5079 100644 --- a/frameworks/native/neural_network_runtime/neural_network_runtime.cpp +++ b/frameworks/native/neural_network_runtime/neural_network_runtime.cpp @@ -330,6 +330,9 @@ NNRT_API OH_NN_ReturnCode OH_NNModel_BuildFromMetaGraph(OH_NNModel *model, const Buffer buffer; std::string modelName; + std::string isProfiling; + std::string opLayout; + std::map opLayouts; for (size_t i = 0; i < extensionSize; ++i) { std::string name = extensions[i].name; if (name == "QuantBuffer") { @@ -337,11 +340,18 @@ NNRT_API OH_NN_ReturnCode OH_NNModel_BuildFromMetaGraph(OH_NNModel *model, const buffer.length = extensions[i].valueSize; } else if (name == "ModelName") { modelName.assign(extensions[i].value, extensions[i].value + extensions[i].valueSize); + } else if (name == "Profiling") { + isProfiling.assign(extensions[i].value, extensions[i].value + extensions[i].valueSize); + LOGI("OH_NNModel_BuildFromMetaGraph isProfiling enable."); + } else if (name == "opLayout") { + opLayout.assign(extensions[i].value, extensions[i].value + extensions[i].valueSize); + opLayouts.insert({opLayout, "hiai::ExecuteDevice::CPU"}); + LOGI("OH_NNModel_BuildFromMetaGraph opLayout:%{public}s.", opLayout.c_str()); } } InnerModel *innerModel = reinterpret_cast(model); - return innerModel->BuildFromMetaGraph(metaGraph, buffer, modelName); + return innerModel->BuildFromMetaGraph(metaGraph, buffer, modelName, isProfiling, opLayouts); } NNRT_API OH_NN_ReturnCode OH_NNModel_SetInputsAndOutputsInfo(OH_NNModel *model, const OH_NN_TensorInfo *inputsInfo, diff --git a/frameworks/native/neural_network_runtime/nn_tensor.cpp b/frameworks/native/neural_network_runtime/nn_tensor.cpp index f010a06fca1c9572374a7a1f2273207e4a2bbd24..13834cb714393455d95040318447ed4757900e6b 100644 --- a/frameworks/native/neural_network_runtime/nn_tensor.cpp +++ b/frameworks/native/neural_network_runtime/nn_tensor.cpp @@ -28,7 +28,6 @@ namespace OHOS { namespace NeuralNetworkRuntime { const uint32_t SUPPORT_NUM_BIT = 8; // Currently support 8-bit quantization only -const uint32_t INVALID_NUM_BIT = 0; void DestroyLiteGraphTensor(void* tensor) { @@ -317,12 +316,13 @@ OH_NN_ReturnCode NNTensor::ParseQuantParams(const OH_NN_QuantParam* quantParam) OH_NN_ReturnCode NNTensor::ValidateQuantParams(const std::vector& quantParams) { - for (const QuantParam& param : quantParams) { - // Only support 8-bit quantization in NNR version 1.0 - if ((param.numBits != SUPPORT_NUM_BIT) || (param.numBits == INVALID_NUM_BIT)) { - LOGE("ValidateQuantParams failed, get invalid numBits %d.", param.numBits); + // Only support 8-bit quantization in NNR version 1.0 + auto paramIt = std::find_if(quantParams.begin(), quantParams.end(), [](QuantParam quant) { + return quant.numBits != SUPPORT_NUM_BIT; + }); + if (paramIt != quantParams.end()) { + LOGE("ValidateQuantParams failed, get invalid numBits %d.", paramIt->numBits); return OH_NN_INVALID_PARAMETER; - } } return OH_NN_SUCCESS; diff --git a/frameworks/native/neural_network_runtime/nncompiler.cpp b/frameworks/native/neural_network_runtime/nncompiler.cpp index cb70f2c6588e5f2037cf8da05bdbaa76d354caee..bc7a40987b5e539b60ee913832b1da848bdcae84 100644 --- a/frameworks/native/neural_network_runtime/nncompiler.cpp +++ b/frameworks/native/neural_network_runtime/nncompiler.cpp @@ -128,6 +128,8 @@ NNCompiler::NNCompiler(const void* model, std::shared_ptr device, size_t m_metaGraph = m_innerModel->GetMetaGraph(); m_quantBuffer = m_innerModel->GetQuantBuffer(); m_modelName = m_innerModel->GetModelName(); + m_isProfiling = m_innerModel->GetProfiling(); + m_opLayouts = m_innerModel->GetOpLayouts(); } NNCompiler::~NNCompiler() @@ -373,7 +375,7 @@ OH_NN_ReturnCode NNCompiler::NormalBuild() } ModelConfig config {m_enableFp16, static_cast(m_performance), - static_cast(m_priority)}; + static_cast(m_priority), m_isProfiling, m_cachePath, m_opLayouts}; if (m_liteGraph != nullptr) { ret = m_device->PrepareModel(m_liteGraph, config, m_preparedModel); } diff --git a/frameworks/native/neural_network_runtime/nncompiler.h b/frameworks/native/neural_network_runtime/nncompiler.h index f95c8da767399f0210db201ee37361637ae0ae01..b5655a72f99ceb3b797f69d35ced10ae805b1b50 100644 --- a/frameworks/native/neural_network_runtime/nncompiler.h +++ b/frameworks/native/neural_network_runtime/nncompiler.h @@ -82,6 +82,8 @@ private: std::shared_ptr m_preparedModel {nullptr}; Buffer m_quantBuffer {nullptr, 0}; std::string m_modelName; + std::string m_isProfiling; + std::map m_opLayouts; void* m_metaGraph {nullptr}; InnerModel* m_innerModel {nullptr}; std::shared_ptr m_liteGraph {nullptr}; diff --git a/frameworks/native/neural_network_runtime/ops/concat_builder.cpp b/frameworks/native/neural_network_runtime/ops/concat_builder.cpp index d18411492cfeebc05b774ad8f92d5e47ce72ecaa..a66e07103b335ae856c768655f277e85428407d7 100644 --- a/frameworks/native/neural_network_runtime/ops/concat_builder.cpp +++ b/frameworks/native/neural_network_runtime/ops/concat_builder.cpp @@ -105,18 +105,20 @@ OH_NN_ReturnCode ConcatBuilder::SetInputsAndOutputs(const std::vector& const std::vector>& allTensors) { size_t allTensorsSize = allTensors.size(); - for (auto index : inputsIndex) { - if (index >= allTensorsSize) { - LOGE("[Concat] Invalid input index, it is out of range %zu.", allTensorsSize); - return OH_NN_INVALID_PARAMETER; - } + bool isOverTensorSize = std::any_of(inputsIndex.begin(), inputsIndex.end(), [allTensorsSize](uint32_t index) { + return index >= allTensorsSize; + }); + if (isOverTensorSize) { + LOGE("[Concat] Invalid input index, it is out of range %zu.", allTensorsSize); + return OH_NN_INVALID_PARAMETER; } - for (auto index : outputsIndex) { - if (index >= allTensorsSize) { - LOGE("[Concat] Invalid output index, it is out of range %zu.", allTensorsSize); - return OH_NN_INVALID_PARAMETER; - } + isOverTensorSize = std::any_of(outputsIndex.begin(), outputsIndex.end(), [allTensorsSize](uint32_t index) { + return index >= allTensorsSize; + }); + if (isOverTensorSize) { + LOGE("[Concat] Invalid output index, it is out of range %zu.", allTensorsSize); + return OH_NN_INVALID_PARAMETER; } m_inputsIndex.clear(); diff --git a/frameworks/native/neural_network_runtime/ops/fullconnection_builder.cpp b/frameworks/native/neural_network_runtime/ops/fullconnection_builder.cpp index f78c1ea927dfb067574d69a7168398967f0c4e16..37d50691210b860a7dd0c7778d1e4556eca663e8 100644 --- a/frameworks/native/neural_network_runtime/ops/fullconnection_builder.cpp +++ b/frameworks/native/neural_network_runtime/ops/fullconnection_builder.cpp @@ -40,11 +40,12 @@ OH_NN_ReturnCode FullConnectionBuilder::SetFullConnectionInput(const std::vector return OH_NN_INVALID_PARAMETER; } size_t allTensorsSize = allTensors.size(); - for (auto index : inputsIndex) { - if (index >= allTensorsSize) { - LOGE("[FullConnection] SetFullConnectionInput failed, the index of inputs is out of range."); - return OH_NN_INVALID_PARAMETER; - } + bool isOverTensorSize = std::any_of(inputsIndex.begin(), inputsIndex.end(), [allTensorsSize](uint32_t index) { + return index >= allTensorsSize; + }); + if (isOverTensorSize) { + LOGE("[FullConnection] SetFullConnectionInput failed, the index of inputs is out of range."); + return OH_NN_INVALID_PARAMETER; } m_inputsIndex = inputsIndex; diff --git a/frameworks/native/neural_network_runtime/ops/pooling_builder.h b/frameworks/native/neural_network_runtime/ops/pooling_builder.h index d0963465d23aadfabc768cff10a554d0110de38f..4fbbcd80e39c92cebd010cd376cd83554b2fe044 100644 --- a/frameworks/native/neural_network_runtime/ops/pooling_builder.h +++ b/frameworks/native/neural_network_runtime/ops/pooling_builder.h @@ -28,9 +28,9 @@ public: PoolingBuilder() = default; virtual ~PoolingBuilder() = default; - OH_NN_ReturnCode PoolingBuild(const std::vector& inputsIndex, + OH_NN_ReturnCode PoolingBuild(const std::vector& paramsIndex, + const std::vector& inputsIndex, const std::vector& outputsIndex, - const std::vector& paramsIndex, const std::vector>& allTensors); OH_NN_ReturnCode SetInputAndOutput(const std::vector& inputsIndex, diff --git a/frameworks/native/neural_network_runtime/ops/space_to_batch_nd_builder.cpp b/frameworks/native/neural_network_runtime/ops/space_to_batch_nd_builder.cpp index 094c1681db12b12e87a10683d11cf9f92bd7557d..8c0bb7bcb6aa829b537e103f7b3838956ebedae0 100644 --- a/frameworks/native/neural_network_runtime/ops/space_to_batch_nd_builder.cpp +++ b/frameworks/native/neural_network_runtime/ops/space_to_batch_nd_builder.cpp @@ -161,8 +161,8 @@ OH_NN_ReturnCode SpaceToBatchNDBuilder::SetPadData(std::shared_ptr ten for (int i = 0; i < PADDINGS_DATA_SIZE; i++) { std::vector vect_data; vect_data.reserve(VECT_DATA_SIZE); - for (int i = 0; i < VECT_DATA_SIZE; ++i) { - vect_data.push_back(paddingsData[i]); + for (int j = 0; j < VECT_DATA_SIZE; ++j) { + vect_data.push_back(paddingsData[j]); } paddings.push_back(vect_data); } diff --git a/frameworks/native/neural_network_runtime/ops/split_builder.cpp b/frameworks/native/neural_network_runtime/ops/split_builder.cpp index fbdd9903fc5cd8bc5b4548331708e9ba5ef2a48e..102c936b78ded67d71719cdb88304694a449aabd 100644 --- a/frameworks/native/neural_network_runtime/ops/split_builder.cpp +++ b/frameworks/native/neural_network_runtime/ops/split_builder.cpp @@ -35,18 +35,20 @@ OH_NN_ReturnCode SplitBuilder::SetInputAndOutput(const std::vector &in } auto allTensorSize = allTensors.size(); - for (auto index : inputsIndex) { - if (index >= allTensorSize) { - LOGE("[SplitBuilder] InputsIndex of Split is out of range."); - return OH_NN_INVALID_PARAMETER; - } + bool isOverTensorSize = std::any_of(inputsIndex.begin(), inputsIndex.end(), [allTensorSize](uint32_t index) { + return index >= allTensorSize; + }); + if (isOverTensorSize) { + LOGE("[SplitBuilder] InputsIndex of Split is out of range."); + return OH_NN_INVALID_PARAMETER; } - for (auto index : outputsIndex) { - if (index >= allTensorSize) { - LOGE("[SplitBuilder] OutputsIndex of Split is out of range."); - return OH_NN_INVALID_PARAMETER; - } + isOverTensorSize = std::any_of(outputsIndex.begin(), outputsIndex.end(), [allTensorSize](uint32_t index) { + return index >= allTensorSize; + }); + if (isOverTensorSize) { + LOGE("[SplitBuilder] InputsIndex of Split is out of range."); + return OH_NN_INVALID_PARAMETER; } m_inputsIndex = inputsIndex; diff --git a/frameworks/native/neural_network_runtime/ops_builder.cpp b/frameworks/native/neural_network_runtime/ops_builder.cpp index 806e946956d8d44caff4d41e7b3ff43aff6d0f69..69c860772c1e1f59a90e75bc56484de6f7575a1b 100644 --- a/frameworks/native/neural_network_runtime/ops_builder.cpp +++ b/frameworks/native/neural_network_runtime/ops_builder.cpp @@ -28,19 +28,21 @@ void DestroyLiteGraphPrimitive(void* primitive) void OpsBuilder::GetInputIndex(std::vector& inputsIndex, const std::unordered_map& modelIDToGraphID) const { - for (auto index : m_inputsIndex) { - // index has been prevented from taking value out of modelIDToGraphID, no need to check. - inputsIndex.emplace_back(modelIDToGraphID.at(index)); - } + // index has been prevented from taking value out of modelIDToGraphID, no need to check. + std::transform(m_inputsIndex.begin(), m_inputsIndex.end(), std::back_inserter(inputsIndex), + [modelIDToGraphID](uint32_t index) { + return modelIDToGraphID.at(index); + }); } void OpsBuilder::GetOutputIndex(std::vector& outputsIndex, const std::unordered_map& modelIDToGraphID) const { - for (auto index : m_outputsIndex) { - // index has been prevented from taking value out of modelIDToGraphID, no need to check. - outputsIndex.emplace_back(modelIDToGraphID.at(index)); - } + // index has been prevented from taking value out of modelIDToGraphID, no need to check. + std::transform(m_outputsIndex.begin(), m_outputsIndex.end(), std::back_inserter(outputsIndex), + [modelIDToGraphID](uint32_t index) { + return modelIDToGraphID.at(index); + }); } std::string OpsBuilder::GetName() const @@ -71,18 +73,20 @@ OH_NN_ReturnCode OpsBuilder::CheckIOIndex(const std::vector& inputsInd } size_t allTensorsSize = allTensors.size(); - for (auto index : inputsIndex) { - if (index >= allTensorsSize) { - LOGE("The index of inputs is out of range."); - return OH_NN_INVALID_PARAMETER; - } + bool isOverTensorSize = std::any_of(inputsIndex.begin(), inputsIndex.end(), [allTensorsSize](uint32_t index) { + return index >= allTensorsSize; + }); + if (isOverTensorSize) { + LOGE("The index of inputs is out of range."); + return OH_NN_INVALID_PARAMETER; } - for (auto index : outputsIndex) { - if (index >= allTensorsSize) { - LOGE("The index of outputs is out of range."); - return OH_NN_INVALID_PARAMETER; - } + isOverTensorSize = std::any_of(outputsIndex.begin(), outputsIndex.end(), [allTensorsSize](uint32_t index) { + return index >= allTensorsSize; + }); + if (isOverTensorSize) { + LOGE("The index of outputs is out of range."); + return OH_NN_INVALID_PARAMETER; } return OH_NN_SUCCESS; diff --git a/frameworks/native/neural_network_runtime/transform.cpp b/frameworks/native/neural_network_runtime/transform.cpp index 8cc6b20166fd8ca463576b43c7cb6251c5bd8bbd..10ee3913b811a633873d446827d19c2dd80815fc 100644 --- a/frameworks/native/neural_network_runtime/transform.cpp +++ b/frameworks/native/neural_network_runtime/transform.cpp @@ -161,9 +161,10 @@ OH_NN_DataType MSToNN::TransformDataType(mindspore::lite::DataType type) std::vector MSToNN::TransformQuantParams(std::vector msQuantParams) { std::vector nnQuantParam; - for (const mindspore::lite::QuantParam& param : msQuantParams) { - nnQuantParam.emplace_back((QuantParam){param.numBits, param.scale, param.zeroPoint}); - } + std::transform(msQuantParams.begin(), msQuantParams.end(), std::back_inserter(nnQuantParam), + [](mindspore::lite::QuantParam quantParam) { + return (QuantParam){quantParam.numBits, quantParam.scale, quantParam.zeroPoint}; + }); return nnQuantParam; } diff --git a/neural-network-runtime-guidelines.md b/neural-network-runtime-guidelines.md index b5e71add11293a0252c33697a76003efe60b6328..411f569caa8c30247374495b02c9adaf205a3c61 100644 --- a/neural-network-runtime-guidelines.md +++ b/neural-network-runtime-guidelines.md @@ -15,34 +15,33 @@ Neural Network Runtime作为AI推理引擎和加速芯片的桥梁,为AI推理 Neural Network Runtime部件的环境要求如下: -- 系统版本:OpenHarmony master分支。 - 开发环境:Ubuntu 18.04及以上。 -- 接入设备:OpenHarmony定义的标准设备,并且系统中内置的硬件加速器驱动,已通过HDI接口对接Neural Network Runtime。 +- 接入设备:系统定义的标准设备,系统中内置AI硬件驱动并已接入Neural Network Runtime。 -由于Neural Network Runtime通过OpenHarmony Native API对外开放,需要通过OpenHarmony的Native开发套件编译Neural Network Runtime应用。在社区的[每日构建](http://ci.openharmony.cn/dailys/dailybuilds)下载对应系统版本的ohos-sdk压缩包,从压缩包中提取对应平台的Native开发套件。以Linux为例,Native开发套件的压缩包命名为`native-linux-{版本号}.zip`。 +由于Neural Network Runtime通过OpenHarmony Native API对外开放,需要通过OpenHarmony的Native开发套件编译Neural Network Runtime应用。在社区的每日构建中下载对应系统版本的ohos-sdk压缩包,从压缩包中提取对应平台的Native开发套件。以Linux为例,Native开发套件的压缩包命名为`native-linux-{版本号}.zip`。 ### 环境搭建 1. 打开Ubuntu编译服务器的终端。 2. 把下载好的Native开发套件压缩包拷贝至当前用户根目录下。 3. 执行以下命令解压Native开发套件的压缩包。 -```shell -unzip native-linux-{版本号}.zip -``` - -解压缩后的内容如下(随版本迭代,目录下的内容可能发生变化,请以最新版本的Native API为准): -```text -native/ -├── build // 交叉编译工具链 -├── build-tools // 编译构建工具 -├── docs -├── llvm -├── nativeapi_syscap_config.json -├── ndk_system_capability.json -├── NOTICE.txt -├── oh-uni-package.json -└── sysroot // Native API头文件和库 -``` + ```shell + unzip native-linux-{版本号}.zip + ``` + + 解压缩后的内容如下(随版本迭代,目录下的内容可能发生变化,请以最新版本的Native API为准): + ```text + native/ + ├── build // 交叉编译工具链 + ├── build-tools // 编译构建工具 + ├── docs + ├── llvm + ├── nativeapi_syscap_config.json + ├── ndk_system_capability.json + ├── NOTICE.txt + ├── oh-uni-package.json + └── sysroot // Native API头文件和库 + ``` ## 接口说明 这里给出Neural Network Runtime开发流程中通用的接口,具体请见下列表格。 @@ -54,44 +53,97 @@ native/ | typedef struct OH_NNModel OH_NNModel | Neural Network Runtime的模型句柄,用于构造模型。 | | typedef struct OH_NNCompilation OH_NNCompilation | Neural Network Runtime的编译器句柄,用于编译AI模型。 | | typedef struct OH_NNExecutor OH_NNExecutor | Neural Network Runtime的执行器句柄,用于在指定设备上执行推理计算。 | +| typedef struct NN_QuantParam NN_QuantParam | Neural Network Runtime的量化参数句柄,用于在构造模型时指定张量的量化参数。 | +| typedef struct NN_TensorDesc NN_TensorDesc | Neural Network Runtime的张量描述句柄,用于描述张量的各类属性,例如数据布局、数据类型、形状等。 | +| typedef struct NN_Tensor NN_Tensor | Neural Network Runtime的张量句柄,用于设置执行器的推理输入和输出张量。 | -### 模型构造相关接口 +### 模型构造接口 | 接口名称 | 描述 | | ------- | --- | | OH_NNModel_Construct() | 创建OH_NNModel类型的模型实例。 | -| OH_NN_ReturnCode OH_NNModel_AddTensor(OH_NNModel *model, const OH_NN_Tensor *tensor) | 向模型实例中添加张量。 | +| OH_NN_ReturnCode OH_NNModel_AddTensorToModel(OH_NNModel *model, const NN_TensorDesc *tensorDesc) | 向模型实例中添加张量。 | | OH_NN_ReturnCode OH_NNModel_SetTensorData(OH_NNModel *model, uint32_t index, const void *dataBuffer, size_t length) | 设置张量的数值。 | | OH_NN_ReturnCode OH_NNModel_AddOperation(OH_NNModel *model, OH_NN_OperationType op, const OH_NN_UInt32Array *paramIndices, const OH_NN_UInt32Array *inputIndices, const OH_NN_UInt32Array *outputIndices) | 向模型实例中添加算子。 | -| OH_NN_ReturnCode OH_NNModel_SpecifyInputsAndOutputs(OH_NNModel *model, const OH_NN_UInt32Array *inputIndices, const OH_NN_UInt32Array *outputIndices) | 指定模型的输入输出。 | +| OH_NN_ReturnCode OH_NNModel_SpecifyInputsAndOutputs(OH_NNModel *model, const OH_NN_UInt32Array *inputIndices, const OH_NN_UInt32Array *outputIndices) | 指定模型的输入和输出张量的索引值。 | | OH_NN_ReturnCode OH_NNModel_Finish(OH_NNModel *model) | 完成模型构图。| -| void OH_NNModel_Destroy(OH_NNModel **model) | 释放模型实例。 | +| void OH_NNModel_Destroy(OH_NNModel **model) | 销毁模型实例。 | + -### 模型编译相关接口 +### 模型编译接口 | 接口名称 | 描述 | | ------- | --- | -| OH_NNCompilation *OH_NNCompilation_Construct(const OH_NNModel *model) | 创建OH_NNCompilation类型的编译实例。 | -| OH_NN_ReturnCode OH_NNCompilation_SetDevice(OH_NNCompilation *compilation, size_t deviceID) | 指定模型编译和计算的硬件。 | -| OH_NN_ReturnCode OH_NNCompilation_SetCache(OH_NNCompilation *compilation, const char *cachePath, uint32_t version) | 设置编译后的模型缓存路径和缓存版本。 | -| OH_NN_ReturnCode OH_NNCompilation_Build(OH_NNCompilation *compilation) | 进行模型编译。 | -| void OH_NNCompilation_Destroy(OH_NNCompilation **compilation) | 释放OH_NNCompilation对象。 | +| OH_NNCompilation *OH_NNCompilation_Construct(const OH_NNModel *model) | 基于模型实例创建OH_NNCompilation类型的编译实例。 | +| OH_NNCompilation *OH_NNCompilation_ConstructWithOfflineModelFile(const char *modelPath) | 基于离线模型文件路径创建OH_NNCompilation类型的编译实例。 | +| OH_NNCompilation *OH_NNCompilation_ConstructWithOfflineModelBuffer(const void *modelBuffer, size_t modelSize) | 基于离线模型文件内存创建OH_NNCompilation类型的编译实例。 | +| OH_NNCompilation *OH_NNCompilation_ConstructForCache() | 创建一个空的编译实例,以便稍后从模型缓存中恢复。 | +| OH_NN_ReturnCode OH_NNCompilation_ExportCacheToBuffer(OH_NNCompilation *compilation, const void *buffer, size_t length, size_t *modelSize) | 将模型缓存写入到指定内存区域。 | +| OH_NN_ReturnCode OH_NNCompilation_ImportCacheFromBuffer(OH_NNCompilation *compilation, const void *buffer, size_t modelSize) | 从指定内存区域读取模型缓存。 | +| OH_NN_ReturnCode OH_NNCompilation_AddExtensionConfig(OH_NNCompilation *compilation, const char *configName, const void *configValue, const size_t configValueSize) | 为自定义硬件属性添加扩展配置,具体硬件的扩展属性名称和属性值需要从硬件厂商的文档中获取。 | +| OH_NN_ReturnCode OH_NNCompilation_SetDevice(OH_NNCompilation *compilation, size_t deviceID) | 指定模型编译和计算的硬件,可通过设备管理接口获取。 | +| OH_NN_ReturnCode OH_NNCompilation_SetCache(OH_NNCompilation *compilation, const char *cachePath, uint32_t version) | 设置编译模型的缓存目录和版本。 | +| OH_NN_ReturnCode OH_NNCompilation_SetPerformanceMode(OH_NNCompilation *compilation, OH_NN_PerformanceMode performanceMode) | 设置模型计算的性能模式。 | +| OH_NN_ReturnCode OH_NNCompilation_SetPriority(OH_NNCompilation *compilation, OH_NN_Priority priority) | 设置模型计算的优先级。 | +| OH_NN_ReturnCode OH_NNCompilation_EnableFloat16(OH_NNCompilation *compilation, bool enableFloat16) | 是否以float16的浮点数精度计算。 | +| OH_NN_ReturnCode OH_NNCompilation_Build(OH_NNCompilation *compilation) | 执行模型编译。 | +| void OH_NNCompilation_Destroy(OH_NNCompilation **compilation) | 销毁编译实例。 | + +### 张量描述接口 -### 执行推理相关接口 +| 接口名称 | 描述 | +| ------- | --- | +| NN_TensorDesc *OH_NNTensorDesc_Create() | 创建一个张量描述实例,用于后续创建张量。 | +| OH_NN_ReturnCode OH_NNTensorDesc_SetName(NN_TensorDesc *tensorDesc, const char *name) | 设置张量描述的名称。 | +| OH_NN_ReturnCode OH_NNTensorDesc_GetName(const NN_TensorDesc *tensorDesc, const char **name) | 获取张量描述的名称。 | +| OH_NN_ReturnCode OH_NNTensorDesc_SetDataType(NN_TensorDesc *tensorDesc, OH_NN_DataType dataType) | 设置张量描述的数据类型。 | +| OH_NN_ReturnCode OH_NNTensorDesc_GetDataType(const NN_TensorDesc *tensorDesc, OH_NN_DataType *dataType) | 获取张量描述的数据类型。 | +| OH_NN_ReturnCode OH_NNTensorDesc_SetShape(NN_TensorDesc *tensorDesc, const int32_t *shape, size_t shapeLength) | 设置张量描述的形状。 | +| OH_NN_ReturnCode OH_NNTensorDesc_GetShape(const NN_TensorDesc *tensorDesc, int32_t **shape, size_t *shapeLength) | 获取张量描述的形状。 | +| OH_NN_ReturnCode OH_NNTensorDesc_SetFormat(NN_TensorDesc *tensorDesc, OH_NN_Format format) | 设置张量描述的数据布局。 | +| OH_NN_ReturnCode OH_NNTensorDesc_GetFormat(const NN_TensorDesc *tensorDesc, OH_NN_Format *format) | 获取张量描述的数据布局。 | +| OH_NN_ReturnCode OH_NNTensorDesc_GetElementCount(const NN_TensorDesc *tensorDesc, size_t *elementCount) | 获取张量描述的元素个数。 | +| OH_NN_ReturnCode OH_NNTensorDesc_GetByteSize(const NN_TensorDesc *tensorDesc, size_t *byteSize) | 获取基于张量描述的形状和数据类型计算的数据占用字节数。 | +| OH_NN_ReturnCode OH_NNTensorDesc_Destroy(NN_TensorDesc **tensorDesc) | 销毁张量描述实例。 | + +### 张量接口 | 接口名称 | 描述 | | ------- | --- | -| OH_NNExecutor *OH_NNExecutor_Construct(OH_NNCompilation *compilation) | 创建OH_NNExecutor类型的执行器实例。 | -| OH_NN_ReturnCode OH_NNExecutor_SetInput(OH_NNExecutor *executor, uint32_t inputIndex, const OH_NN_Tensor *tensor, const void *dataBuffer, size_t length) | 设置模型单个输入的数据。 | -| OH_NN_ReturnCode OH_NNExecutor_SetOutput(OH_NNExecutor *executor, uint32_t outputIndex, void *dataBuffer, size_t length) | 设置模型单个输出的缓冲区。 | -| OH_NN_ReturnCode OH_NNExecutor_Run(OH_NNExecutor *executor) | 执行推理。 | -| void OH_NNExecutor_Destroy(OH_NNExecutor **executor) | 销毁OH_NNExecutor实例,释放实例占用的内存。 | +| NN_Tensor* OH_NNTensor_Create(size_t deviceID, NN_TensorDesc *tensorDesc) | 从张量描述创建张量实例,会申请设备共享内存。 | +| NN_Tensor* OH_NNTensor_CreateWithSize(size_t deviceID, NN_TensorDesc *tensorDesc, size_t size) | 按照指定内存大小和张量描述创建张量实例,会申请设备共享内存。 | +| NN_Tensor* OH_NNTensor_CreateWithFd(size_t deviceID, NN_TensorDesc *tensorDesc, int fd, size_t size, size_t offset) | 按照指定共享内存的文件描述符和张量描述创建张量实例,从而可以复用其他张量的设备共享内存。 | +| NN_TensorDesc* OH_NNTensor_GetTensorDesc(const NN_Tensor *tensor) | 获取张量内部的张量描述实例指针,从而可读取张量的属性,例如数据类型、形状等。 | +| void* OH_NNTensor_GetDataBuffer(const NN_Tensor *tensor) | 获取张量数据的内存地址,可以读写张量数据。 | +| OH_NN_ReturnCode OH_NNTensor_GetFd(const NN_Tensor *tensor, int *fd) | 获取张量数据所在共享内存的文件描述符,文件描述符fd对应了一块设备共享内存。 | +| OH_NN_ReturnCode OH_NNTensor_GetSize(const NN_Tensor *tensor, size_t *size) | 获取张量数据所在共享内存的大小。 | +| OH_NN_ReturnCode OH_NNTensor_GetOffset(const NN_Tensor *tensor, size_t *offset) | 获取张量数据所在共享内存上的偏移量,张量数据可使用的大小为所在共享内存的大小减去偏移量。 | +| OH_NN_ReturnCode OH_NNTensor_Destroy(NN_Tensor **tensor) | 销毁张量实例。 | + +### 执行推理接口 -### 设备管理相关接口 +| 接口名称 | 描述 | +| ------- | --- | +| OH_NNExecutor *OH_NNExecutor_Construct(OH_NNCompilation *compilation) | 创建OH_NNExecutor类型的执行器实例。 | +| OH_NN_ReturnCode OH_NNExecutor_GetOutputShape(OH_NNExecutor *executor, uint32_t outputIndex, int32_t **shape, uint32_t *shapeLength) | 获取输出张量的维度信息,用于输出张量具有动态形状的情况。 | +| OH_NN_ReturnCode OH_NNExecutor_GetInputCount(const OH_NNExecutor *executor, size_t *inputCount) | 获取输入张量的数量。 | +| OH_NN_ReturnCode OH_NNExecutor_GetOutputCount(const OH_NNExecutor *executor, size_t *outputCount) | 获取输出张量的数量。 | +| NN_TensorDesc* OH_NNExecutor_CreateInputTensorDesc(const OH_NNExecutor *executor, size_t index) | 由指定索引值创建一个输入张量的描述,用于读取张量的属性或创建张量实例。 | +| NN_TensorDesc* OH_NNExecutor_CreateOutputTensorDesc(const OH_NNExecutor *executor, size_t index) | 由指定索引值创建一个输出张量的描述,用于读取张量的属性或创建张量实例。 | +| OH_NN_ReturnCode OH_NNExecutor_GetInputDimRange(const OH_NNExecutor *executor, size_t index, size_t **minInputDims, size_t **maxInputDims, size_t *shapeLength) |获取所有输入张量的维度范围。当输入张量具有动态形状时,不同设备可能支持不同的维度范围。 | +| OH_NN_ReturnCode OH_NNExecutor_SetOnRunDone(OH_NNExecutor *executor, NN_OnRunDone onRunDone) | 设置异步推理结束后的回调处理函数,回调函数定义详见接口文档。 | +| OH_NN_ReturnCode OH_NNExecutor_SetOnServiceDied(OH_NNExecutor *executor, NN_OnServiceDied onServiceDied) | 设置异步推理执行期间设备驱动服务突然死亡时的回调处理函数,回调函数定义详见接口文档。 | +| OH_NN_ReturnCode OH_NNExecutor_RunSync(OH_NNExecutor *executor, NN_Tensor *inputTensor[], size_t inputCount, NN_Tensor *outputTensor[], size_t outputCount) | 执行同步推理。 | +| OH_NN_ReturnCode OH_NNExecutor_RunAsync(OH_NNExecutor *executor, NN_Tensor *inputTensor[], size_t inputCount, NN_Tensor *outputTensor[], size_t outputCount, int32_t timeout, void *userData) | 执行异步推理。 | +| void OH_NNExecutor_Destroy(OH_NNExecutor **executor) | 销毁执行器实例。 | + +### 设备管理接口 | 接口名称 | 描述 | | ------- | --- | -| OH_NN_ReturnCode OH_NNDevice_GetAllDevicesID(const size_t **allDevicesID, uint32_t *deviceCount) | 获取对接到 Neural Network Runtime 的硬件ID。 | +| OH_NN_ReturnCode OH_NNDevice_GetAllDevicesID(const size_t **allDevicesID, uint32_t *deviceCount) | 获取对接到Neural Network Runtime的所有硬件ID。 | +| OH_NN_ReturnCode OH_NNDevice_GetName(size_t deviceID, const char **name) | 获取指定硬件的名称。 | +| OH_NN_ReturnCode OH_NNDevice_GetType(size_t deviceID, OH_NN_DeviceType *deviceType) | 获取指定硬件的类别信息。 | ## 开发步骤 @@ -100,7 +152,7 @@ Neural Network Runtime的开发流程主要包含**模型构造**、**模型编 1. 创建应用样例文件。 - 首先,创建Neural Network Runtime应用样例的源文件。在项目目录下执行以下命令,创建`nnrt_example/`目录,在目录下创建 `nnrt_example.cpp` 源文件。 + 首先,创建Neural Network Runtime应用样例的源文件。在项目目录下执行以下命令,创建`nnrt_example/`目录,并在目录下创建 `nnrt_example.cpp` 源文件。 ```shell mkdir ~/nnrt_example && cd ~/nnrt_example @@ -109,112 +161,245 @@ Neural Network Runtime的开发流程主要包含**模型构造**、**模型编 2. 导入Neural Network Runtime。 - 在 `nnrt_example.cpp` 文件的开头添加以下代码,引入Neural Network Runtime模块。 + 在 `nnrt_example.cpp` 文件的开头添加以下代码,引入Neural Network Runtime。 ```cpp - #include #include - #include - + #include + #include "hilog/log.h" #include "neural_network_runtime/neural_network_runtime.h" + ``` + +3. 定义日志打印、设置输入数据、数据打印等辅助函数。 - // 常量,用于指定输入、输出数据的字节长度 - const size_t DATA_LENGTH = 4 * 12; + ```cpp + #define LOG_DOMAIN 0xD002101 + #define LOG_TAG "NNRt" + #define LOGD(...) OH_LOG_DEBUG(LOG_APP, __VA_ARGS__) + #define LOGI(...) OH_LOG_INFO(LOG_APP, __VA_ARGS__) + #define LOGW(...) OH_LOG_WARN(LOG_APP, __VA_ARGS__) + #define LOGE(...) OH_LOG_ERROR(LOG_APP, __VA_ARGS__) + #define LOGF(...) OH_LOG_FATAL(LOG_APP, __VA_ARGS__) + + // 返回值检查宏 + #define CHECKNEQ(realRet, expectRet, retValue, ...) \ + do { \ + if ((realRet) != (expectRet)) { \ + printf(__VA_ARGS__); \ + return (retValue); \ + } \ + } while (0) + + #define CHECKEQ(realRet, expectRet, retValue, ...) \ + do { \ + if ((realRet) == (expectRet)) { \ + printf(__VA_ARGS__); \ + return (retValue); \ + } \ + } while (0) + + // 设置输入数据用于推理 + OH_NN_ReturnCode SetInputData(NN_Tensor* inputTensor[], size_t inputSize) + { + OH_NN_DataType dataType(OH_NN_FLOAT32); + OH_NN_ReturnCode ret{OH_NN_FAILED}; + size_t elementCount = 0; + for (size_t i = 0; i < inputSize; ++i) { + // 获取张量的数据内存 + auto data = OH_NNTensor_GetDataBuffer(inputTensor[i]); + CHECKEQ(data, nullptr, OH_NN_FAILED, "Failed to get data buffer."); + // 获取张量的描述 + auto desc = OH_NNTensor_GetTensorDesc(inputTensor[i]); + CHECKEQ(desc, nullptr, OH_NN_FAILED, "Failed to get desc."); + // 获取张量的数据类型 + ret = OH_NNTensorDesc_GetDataType(desc, &dataType); + CHECKNEQ(ret, OH_NN_SUCCESS, OH_NN_FAILED, "Failed to get data type."); + // 获取张量的元素个数 + ret = OH_NNTensorDesc_GetElementCount(desc, &elementCount); + CHECKNEQ(ret, OH_NN_SUCCESS, OH_NN_FAILED, "Failed to get element count."); + switch(dataType) { + case OH_NN_FLOAT32: { + float* floatValue = reinterpret_cast(data); + for (size_t j = 0; j < elementCount; ++j) { + floatValue[j] = static_cast(j); + } + break; + } + case OH_NN_INT32: { + int* intValue = reinterpret_cast(data); + for (size_t j = 0; j < elementCount; ++j) { + intValue[j] = static_cast(j); + } + break; + } + default: + return OH_NN_FAILED; + } + } + return OH_NN_SUCCESS; + } + + OH_NN_ReturnCode Print(NN_Tensor* outputTensor[], size_t outputSize) + { + OH_NN_DataType dataType(OH_NN_FLOAT32); + OH_NN_ReturnCode ret{OH_NN_FAILED}; + size_t elementCount = 0; + for (size_t i = 0; i < outputSize; ++i) { + auto data = OH_NNTensor_GetDataBuffer(outputTensor[i]); + CHECKEQ(data, nullptr, OH_NN_FAILED, "Failed to get data buffer."); + auto desc = OH_NNTensor_GetTensorDesc(outputTensor[i]); + CHECKEQ(desc, nullptr, OH_NN_FAILED, "Failed to get desc."); + ret = OH_NNTensorDesc_GetDataType(desc, &dataType); + CHECKNEQ(ret, OH_NN_SUCCESS, OH_NN_FAILED, "Failed to get data type."); + ret = OH_NNTensorDesc_GetElementCount(desc, &elementCount); + CHECKNEQ(ret, OH_NN_SUCCESS, OH_NN_FAILED, "Failed to get element count."); + switch(dataType) { + case OH_NN_FLOAT32: { + float* floatValue = reinterpret_cast(data); + for (size_t j = 0; j < elementCount; ++j) { + std::cout << "Output index: " << j << ", value is: " << floatValue[j] << "." << std::endl; + } + break; + } + case OH_NN_INT32: { + int* intValue = reinterpret_cast(data); + for (size_t j = 0; j < elementCount; ++j) { + std::cout << "Output index: " << j << ", value is: " << intValue[j] << "." << std::endl; + } + break; + } + default: + return OH_NN_FAILED; + } + } + + return OH_NN_SUCCESS; + } ``` -3. 构造模型。 +4. 构造模型。 - 使用Neural Network Runtime接口,构造`Add`单算子样例模型。 + 使用Neural Network Runtime的模型构造接口,构造`Add`单算子样例模型。 ```cpp - OH_NN_ReturnCode BuildModel(OH_NNModel** pModel) + OH_NN_ReturnCode BuildModel(OH_NNModel** pmodel) { - // 创建模型实例,进行模型构造 + // 创建模型实例model,进行模型构造 OH_NNModel* model = OH_NNModel_Construct(); - if (model == nullptr) { - std::cout << "Create model failed." << std::endl; - return OH_NN_MEMORY_ERROR; - } + CHECKEQ(model, nullptr, -1, "Create model failed."); + + // 添加Add算子的第一个输入张量,类型为float32,张量形状为[1, 2, 2, 3] + NN_TensorDesc* tensorDesc = OH_NNTensorDesc_Create(); + CHECKEQ(tensorDesc, nullptr, -1, "Create TensorDesc failed."); - // 添加Add算子的第一个输入Tensor,类型为float32,张量形状为[1, 2, 2, 3] int32_t inputDims[4] = {1, 2, 2, 3}; - OH_NN_Tensor input1 = {OH_NN_FLOAT32, 4, inputDims, nullptr, OH_NN_TENSOR}; - OH_NN_ReturnCode ret = OH_NNModel_AddTensor(model, &input1); - if (ret != OH_NN_SUCCESS) { - std::cout << "BuildModel failed, add Tensor of first input failed." << std::endl; - return ret; - } + returnCode = OH_NNTensorDesc_SetShape(tensorDesc, inputDims, 4); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "Set TensorDesc shape failed."); - // 添加Add算子的第二个输入Tensor,类型为float32,张量形状为[1, 2, 2, 3] - OH_NN_Tensor input2 = {OH_NN_FLOAT32, 4, inputDims, nullptr, OH_NN_TENSOR}; - ret = OH_NNModel_AddTensor(model, &input2); - if (ret != OH_NN_SUCCESS) { - std::cout << "BuildModel failed, add Tensor of second input failed." << std::endl; - return ret; - } + returnCode = OH_NNTensorDesc_SetDataType(tensorDesc, OH_NN_FLOAT32); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "Set TensorDesc data type failed."); + + returnCode = OH_NNTensorDesc_SetFormat(tensorDesc, OH_NN_FORMAT_NONE); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "Set TensorDesc format failed."); + + returnCode = OH_NNModel_AddTensorToModel(model, tensorDesc); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "Add first TensorDesc to model failed."); + + returnCode = OH_NNModel_SetTensorType(model, 0, OH_NN_TENSOR); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "Set model tensor type failed."); + + // 添加Add算子的第二个输入张量,类型为float32,张量形状为[1, 2, 2, 3] + tensorDesc = OH_NNTensorDesc_Create(); + CHECKEQ(tensorDesc, nullptr, -1, "Create TensorDesc failed."); + + returnCode = OH_NNTensorDesc_SetShape(tensorDesc, inputDims, 4); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "Set TensorDesc shape failed."); + + returnCode = OH_NNTensorDesc_SetDataType(tensorDesc, OH_NN_FLOAT32); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "Set TensorDesc data type failed."); + + returnCode = OH_NNTensorDesc_SetFormat(tensorDesc, OH_NN_FORMAT_NONE); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "Set TensorDesc format failed."); + + returnCode = OH_NNModel_AddTensorToModel(model, tensorDesc); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "Add second TensorDesc to model failed."); + + returnCode = OH_NNModel_SetTensorType(model, 1, OH_NN_TENSOR); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "Set model tensor type failed."); + + // 添加Add算子的参数张量,该参数张量用于指定激活函数的类型,张量的数据类型为int8。 + tensorDesc = OH_NNTensorDesc_Create(); + CHECKEQ(tensorDesc, nullptr, -1, "Create TensorDesc failed."); - // 添加Add算子的参数Tensor,该参数Tensor用于指定激活函数的类型,Tensor的数据类型为int8。 int32_t activationDims = 1; + returnCode = OH_NNTensorDesc_SetShape(tensorDesc, &activationDims, 1); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "Set TensorDesc shape failed."); + + returnCode = OH_NNTensorDesc_SetDataType(tensorDesc, OH_NN_INT8); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "Set TensorDesc data type failed."); + + returnCode = OH_NNTensorDesc_SetFormat(tensorDesc, OH_NN_FORMAT_NONE); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "Set TensorDesc format failed."); + + returnCode = OH_NNModel_AddTensorToModel(model, tensorDesc); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "Add second TensorDesc to model failed."); + + returnCode = OH_NNModel_SetTensorType(model, 2, OH_NN_ADD_ACTIVATIONTYPE); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "Set model tensor type failed."); + + // 将激活函数类型设置为OH_NNBACKEND_FUSED_NONE,表示该算子不添加激活函数。 int8_t activationValue = OH_NN_FUSED_NONE; - OH_NN_Tensor activation = {OH_NN_INT8, 1, &activationDims, nullptr, OH_NN_ADD_ACTIVATIONTYPE}; - ret = OH_NNModel_AddTensor(model, &activation); - if (ret != OH_NN_SUCCESS) { - std::cout << "BuildModel failed, add Tensor of activation failed." << std::endl; - return ret; - } + returnCode = OH_NNModel_SetTensorData(model, 2, &activationValue, sizeof(int8_t)); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "Set model tensor data failed."); - // 将激活函数类型设置为OH_NN_FUSED_NONE,表示该算子不添加激活函数。 - ret = OH_NNModel_SetTensorData(model, 2, &activationValue, sizeof(int8_t)); - if (ret != OH_NN_SUCCESS) { - std::cout << "BuildModel failed, set value of activation failed." << std::endl; - return ret; - } + // 设置Add算子的输出张量,类型为float32,张量形状为[1, 2, 2, 3] + tensorDesc = OH_NNTensorDesc_Create(); + CHECKEQ(tensorDesc, nullptr, -1, "Create TensorDesc failed."); - // 设置Add算子的输出,类型为float32,张量形状为[1, 2, 2, 3] - OH_NN_Tensor output = {OH_NN_FLOAT32, 4, inputDims, nullptr, OH_NN_TENSOR}; - ret = OH_NNModel_AddTensor(model, &output); - if (ret != OH_NN_SUCCESS) { - std::cout << "BuildModel failed, add Tensor of output failed." << std::endl; - return ret; - } + returnCode = OH_NNTensorDesc_SetShape(tensorDesc, inputDims, 4); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "Set TensorDesc shape failed."); + + returnCode = OH_NNTensorDesc_SetDataType(tensorDesc, OH_NN_FLOAT32); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "Set TensorDesc data type failed."); + + returnCode = OH_NNTensorDesc_SetFormat(tensorDesc, OH_NN_FORMAT_NONE); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "Set TensorDesc format failed."); - // 指定Add算子的输入、参数和输出索引 + returnCode = OH_NNModel_AddTensorToModel(model, tensorDesc); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "Add forth TensorDesc to model failed."); + + returnCode = OH_NNModel_SetTensorType(model, 3, OH_NN_TENSOR); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "Set model tensor type failed."); + + // 指定Add算子的输入张量、参数张量和输出张量的索引 uint32_t inputIndicesValues[2] = {0, 1}; uint32_t paramIndicesValues = 2; uint32_t outputIndicesValues = 3; - OH_NN_UInt32Array paramIndices = {¶mIndicesValues, 1}; - OH_NN_UInt32Array inputIndices = {inputIndicesValues, 2}; - OH_NN_UInt32Array outputIndices = {&outputIndicesValues, 1}; + OH_NN_UInt32Array paramIndices = {¶mIndicesValues, 1 * 4}; + OH_NN_UInt32Array inputIndices = {inputIndicesValues, 2 * 4}; + OH_NN_UInt32Array outputIndices = {&outputIndicesValues, 1 * 4}; // 向模型实例添加Add算子 - ret = OH_NNModel_AddOperation(model, OH_NN_OPS_ADD, ¶mIndices, &inputIndices, &outputIndices); - if (ret != OH_NN_SUCCESS) { - std::cout << "BuildModel failed, add operation failed." << std::endl; - return ret; - } + returnCode = OH_NNModel_AddOperation(model, OH_NN_OPS_ADD, ¶mIndices, &inputIndices, &outputIndices); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "Add operation to model failed."); - // 设置模型实例的输入、输出索引 - ret = OH_NNModel_SpecifyInputsAndOutputs(model, &inputIndices, &outputIndices); - if (ret != OH_NN_SUCCESS) { - std::cout << "BuildModel failed, specify inputs and outputs failed." << std::endl; - return ret; - } + // 设置模型实例的输入张量、输出张量的索引 + returnCode = OH_NNModel_SpecifyInputsAndOutputs(model, &inputIndices, &outputIndices); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "Specify model inputs and outputs failed."); // 完成模型实例的构建 - ret = OH_NNModel_Finish(model); - if (ret != OH_NN_SUCCESS) { - std::cout << "BuildModel failed, error happened when finishing model construction." << std::endl; - return ret; - } + returnCode = OH_NNModel_Finish(model); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "Build model failed."); - *pModel = model; + // 返回模型实例 + *pmodel = model; return OH_NN_SUCCESS; } ``` -4. 查询Neural Network Runtime已经对接的加速芯片。 +5. 查询Neural Network Runtime已经对接的AI加速芯片。 - Neural Network Runtime支持通过HDI接口,对接多种加速芯片。在执行模型编译前,需要查询当前设备下,Neural Network Runtime已经对接的加速芯片。每个加速芯片对应唯一的ID值,在编译阶段需要通过设备ID,指定模型编译的芯片。 + Neural Network Runtime支持通过HDI接口,对接多种AI加速芯片。在执行模型编译前,需要查询当前设备下,Neural Network Runtime已经对接的AI加速芯片。每个AI加速芯片对应唯一的ID值,在编译阶段需要通过设备ID,指定模型编译的芯片。 ```cpp void GetAvailableDevices(std::vector& availableDevice) { @@ -235,116 +420,140 @@ Neural Network Runtime的开发流程主要包含**模型构造**、**模型编 } ``` -5. 在指定的设备上编译模型。 +6. 在指定的设备上编译模型。 - Neural Network Runtime使用抽象的模型表达描述AI模型的拓扑结构,在加速芯片上执行前,需要通过Neural Network Runtime提供的编译模块,将抽象的模型表达下发至芯片驱动层,转换成可以直接推理计算的格式。 + Neural Network Runtime使用抽象的模型表达描述AI模型的拓扑结构。在AI加速芯片上执行前,需要通过Neural Network Runtime提供的编译模块来创建编译实例,并由编译实例将抽象的模型表达下发至芯片驱动层,转换成可以直接推理计算的格式,即模型编译。 ```cpp - OH_NN_ReturnCode CreateCompilation(OH_NNModel* model, const std::vector& availableDevice, OH_NNCompilation** pCompilation) + OH_NN_ReturnCode CreateCompilation(OH_NNModel* model, const std::vector& availableDevice, + OH_NNCompilation** pCompilation) { - // 创建编译实例,用于将模型传递至底层硬件编译 + // 创建编译实例compilation,将构图的模型实例或MSLite传下来的模型实例传入 OH_NNCompilation* compilation = OH_NNCompilation_Construct(model); - if (compilation == nullptr) { - std::cout << "CreateCompilation failed, error happended when creating compilation." << std::endl; - return OH_NN_MEMORY_ERROR; - } + CHECKEQ(compilation, nullptr, -1, "OH_NNCore_ConstructCompilationWithNNModel failed."); // 设置编译的硬件、缓存路径、性能模式、计算优先级、是否开启float16低精度计算等选项 - // 选择在第一个设备上编译模型 - OH_NN_ReturnCode ret = OH_NNCompilation_SetDevice(compilation, availableDevice[0]); - if (ret != OH_NN_SUCCESS) { - std::cout << "CreateCompilation failed, error happened when setting device." << std::endl; - return ret; - } + returnCode = OH_NNCompilation_SetDevice(compilation, availableDevice[0]); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "OH_NNCompilation_SetDevice failed."); // 将模型编译结果缓存在/data/local/tmp目录下,版本号指定为1 - ret = OH_NNCompilation_SetCache(compilation, "/data/local/tmp", 1); - if (ret != OH_NN_SUCCESS) { - std::cout << "CreateCompilation failed, error happened when setting cache path." << std::endl; - return ret; - } + returnCode = OH_NNCompilation_SetCache(compilation, "/data/local/tmp", 1); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "OH_NNCompilation_SetCache failed."); - // 完成编译设置,进行模型编译 - ret = OH_NNCompilation_Build(compilation); - if (ret != OH_NN_SUCCESS) { - std::cout << "CreateCompilation failed, error happened when building compilation." << std::endl; - return ret; - } + // 设置硬件性能模式 + returnCode = OH_NNCompilation_SetPerformanceMode(compilation, OH_NN_PERFORMANCE_EXTREME); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "OH_NNCompilation_SetPerformanceMode failed."); + + // 设置推理执行优先级 + returnCode = OH_NNCompilation_SetPriority(compilation, OH_NN_PRIORITY_HIGH); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "OH_NNCompilation_SetPriority failed."); + + // 是否开启FP16计算模式 + returnCode = OH_NNCompilation_EnableFloat16(compilation, false); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "OH_NNCompilation_EnableFloat16 failed."); + + // 执行模型编译 + returnCode = OH_NNCompilation_Build(compilation); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "OH_NNCompilation_Build failed."); *pCompilation = compilation; return OH_NN_SUCCESS; } ``` -6. 创建执行器。 +7. 创建执行器。 - 完成模型编译后,需要调用Neural Network Runtime的执行模块,创建推理执行器。执行阶段,设置模型输入、获取模型输出和触发推理计算的操作均围绕执行器完成。 + 完成模型编译后,需要调用Neural Network Runtime的执行模块,通过编译实例创建执行器。模型推理阶段中的设置模型输入、触发推理计算以及获取模型输出等操作均需要围绕执行器完成。 ```cpp OH_NNExecutor* CreateExecutor(OH_NNCompilation* compilation) { - // 创建执行实例 - OH_NNExecutor* executor = OH_NNExecutor_Construct(compilation); + // 通过编译实例compilation创建执行器executor + OH_NNExecutor *executor = OH_NNExecutor_Construct(compilation); + CHECKEQ(executor, nullptr, -1, "OH_NNExecutor_Construct failed."); return executor; } ``` -7. 执行推理计算,并打印计算结果。 +8. 执行推理计算,并打印推理结果。 - 通过执行模块提供的接口,将推理计算所需要的输入数据传递给执行器,触发执行器完成一次推理计算,获取模型的推理计算结果。 + 通过执行模块提供的接口,将推理计算所需要的输入数据传递给执行器,触发执行器完成一次推理计算,获取模型的推理结果并打印。 ```cpp - OH_NN_ReturnCode Run(OH_NNExecutor* executor) + OH_NN_ReturnCode Run(OH_NNExecutor* executor, const std::vector& availableDevice) { - // 构造示例数据 - float input1[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - float input2[12] = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}; - - int32_t inputDims[4] = {1, 2, 2, 3}; - OH_NN_Tensor inputTensor1 = {OH_NN_FLOAT32, 4, inputDims, nullptr, OH_NN_TENSOR}; - OH_NN_Tensor inputTensor2 = {OH_NN_FLOAT32, 4, inputDims, nullptr, OH_NN_TENSOR}; - - // 设置执行的输入 - - // 设置执行的第一个输入,输入数据由input1指定 - OH_NN_ReturnCode ret = OH_NNExecutor_SetInput(executor, 0, &inputTensor1, input1, DATA_LENGTH); - if (ret != OH_NN_SUCCESS) { - std::cout << "Run failed, error happened when setting first input." << std::endl; - return ret; + // 从executor获取输入输出信息 + // 获取输入张量的个数 + size_t inputCount = 0; + returnCode = OH_NNExecutor_GetInputCount(executor, &inputCount); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "OH_NNExecutor_GetInputCount failed."); + std::vector inputTensorDescs; + NN_TensorDesc* tensorDescTmp = nullptr; + for (size_t i = 0; i < inputCount; ++i) { + // 创建输入张量的描述 + tensorDescTmp = OH_NNExecutor_CreateInputTensorDesc(executor, i); + CHECKEQ(tensorDescTmp, nullptr, -1, "OH_NNExecutor_CreateInputTensorDesc failed."); + inputTensorDescs.emplace_back(tensorDescTmp); } - - // 设置执行的第二个输入,输入数据由input2指定 - ret = OH_NNExecutor_SetInput(executor, 1, &inputTensor2, input2, DATA_LENGTH); - if (ret != OH_NN_SUCCESS) { - std::cout << "Run failed, error happened when setting second input." << std::endl; - return ret; + // 获取输出张量的个数 + size_t outputCount = 0; + returnCode = OH_NNExecutor_GetOutputCount(executor, &outputCount); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "OH_NNExecutor_GetOutputCount failed."); + std::vector outputTensorDescs; + for (size_t i = 0; i < outputCount; ++i) { + // 创建输出张量的描述 + tensorDescTmp = OH_NNExecutor_CreateOutputTensorDesc(executor, i); + CHECKEQ(tensorDescTmp, nullptr, -1, "OH_NNExecutor_CreateOutputTensorDesc failed."); + outputTensorDescs.emplace_back(tensorDescTmp); } - // 设置输出的数据缓冲区,OH_NNExecutor_Run执行计算后,输出结果将保留在output中 - float output[12]; - ret = OH_NNExecutor_SetOutput(executor, 0, output, DATA_LENGTH); - if (ret != OH_NN_SUCCESS) { - std::cout << "Run failed, error happened when setting output buffer." << std::endl; - return ret; + // 创建输入和输出张量 + NN_Tensor* inputTensors[inputCount]; + NN_Tensor* tensor = nullptr; + for (size_t i = 0; i < inputCount; ++i) { + tensor = nullptr; + tensor = OH_NNTensor_Create(availableDevice[0], inputTensorDescs[i]); + CHECKEQ(tensor, nullptr, -1, "OH_NNTensor_Create failed."); + inputTensors[i] = tensor; } - - // 执行计算 - ret = OH_NNExecutor_Run(executor); - if (ret != OH_NN_SUCCESS) { - std::cout << "Run failed, error doing execution." << std::endl; - return ret; + NN_Tensor* outputTensors[outputCount]; + for (size_t i = 0; i < outputCount; ++i) { + tensor = nullptr; + tensor = OH_NNTensor_Create(availableDevice[0], outputTensorDescs[i]); + CHECKEQ(tensor, nullptr, -1, "OH_NNTensor_Create failed."); + outputTensors[i] = tensor; } - // 打印输出结果 - for (uint32_t i = 0; i < 12; i++) { - std::cout << "Output index: " << i << ", value is: " << output[i] << "." << std::endl; + // 设置输入张量的数据 + returnCode = SetInputData(inputTensors, inputCount); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "SetInputData failed."); + + // 执行推理 + returnCode = OH_NNExecutor_RunSync(executor, inputTensors, inputCount, outputTensors, outputCount); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "OH_NNExecutor_RunSync failed."); + + // 打印输出张量的数据 + Print(outputTensors, outputCount); + + // 清理输入和输出张量以及张量描述 + for (size_t i = 0; i < inputCount; ++i) { + returnCode = OH_NNTensor_Destroy(&inputTensors[i]); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "OH_NNTensor_Destroy failed."); + returnCode = OH_NNTensorDesc_Destroy(&inputTensorDescs[i]); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "OH_NNTensorDesc_Destroy failed."); + } + for (size_t i = 0; i < outputCount; ++i) { + returnCode = OH_NNTensor_Destroy(&outputTensors[i]); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "OH_NNTensor_Destroy failed."); + returnCode = OH_NNTensorDesc_Destroy(&outputTensorDescs[i]); + CHECKNEQ(returnCode, OH_NN_SUCCESS, -1, "OH_NNTensorDesc_Destroy failed."); } return OH_NN_SUCCESS; } ``` -8. 构建端到端模型构造-编译-执行流程。 +9. 构建端到端模型构造-编译-执行流程。 - 步骤3-步骤7实现了模型的模型构造、编译和执行流程,并封装成4个函数,便于模块化开发。以下示例代码将4个函数串联成完整的Neural Network Runtime开发流程。 + 步骤4-步骤8实现了模型的模型构造、编译和执行流程,并封装成多个函数,便于模块化开发。以下示例代码将串联这些函数, 形成一个完整的Neural Network Runtime使用流程。 ```cpp int main() { @@ -353,7 +562,8 @@ Neural Network Runtime的开发流程主要包含**模型构造**、**模型编 OH_NNExecutor* executor = nullptr; std::vector availableDevices; - // 模型构造阶段 + // 模型构造 + OH_NNModel* model = nullptr; OH_NN_ReturnCode ret = BuildModel(&model); if (ret != OH_NN_SUCCESS) { std::cout << "BuildModel failed." << std::endl; @@ -369,7 +579,7 @@ Neural Network Runtime的开发流程主要包含**模型构造**、**模型编 return -1; } - // 模型编译阶段 + // 模型编译 ret = CreateCompilation(model, availableDevices, &compilation); if (ret != OH_NN_SUCCESS) { std::cout << "CreateCompilation failed." << std::endl; @@ -378,28 +588,29 @@ Neural Network Runtime的开发流程主要包含**模型构造**、**模型编 return -1; } + // 销毁模型实例 + OH_NNModel_Destroy(&model); + // 创建模型的推理执行器 executor = CreateExecutor(compilation); if (executor == nullptr) { std::cout << "CreateExecutor failed, no executor is created." << std::endl; - OH_NNModel_Destroy(&model); OH_NNCompilation_Destroy(&compilation); return -1; } - // 使用上一步创建的执行器,执行单步推理计算 - ret = Run(executor); + // 销毁编译实例 + OH_NNCompilation_Destroy(&compilation); + + // 使用上一步创建的执行器,执行推理计算 + ret = Run(executor, availableDevices); if (ret != OH_NN_SUCCESS) { std::cout << "Run failed." << std::endl; - OH_NNModel_Destroy(&model); - OH_NNCompilation_Destroy(&compilation); OH_NNExecutor_Destroy(&executor); return -1; } - // 释放申请的资源 - OH_NNModel_Destroy(&model); - OH_NNCompilation_Destroy(&compilation); + // 销毁执行器实例 OH_NNExecutor_Destroy(&executor); return 0; @@ -420,7 +631,8 @@ Neural Network Runtime的开发流程主要包含**模型构造**、**模型编 ) target_link_libraries(nnrt_example - neural_network_runtime.z + neural_network_runtime + neural_network_core ) ``` @@ -447,18 +659,18 @@ Neural Network Runtime的开发流程主要包含**模型构造**、**模型编 如果样例执行正常,应该得到以下输出。 ```text - Output index: 0, value is: 11.000000. - Output index: 1, value is: 13.000000. - Output index: 2, value is: 15.000000. - Output index: 3, value is: 17.000000. - Output index: 4, value is: 19.000000. - Output index: 5, value is: 21.000000. - Output index: 6, value is: 23.000000. - Output index: 7, value is: 25.000000. - Output index: 8, value is: 27.000000. - Output index: 9, value is: 29.000000. - Output index: 10, value is: 31.000000. - Output index: 11, value is: 33.000000. + Output index: 0, value is: 0.000000. + Output index: 1, value is: 2.000000. + Output index: 2, value is: 4.000000. + Output index: 3, value is: 6.000000. + Output index: 4, value is: 8.000000. + Output index: 5, value is: 10.000000. + Output index: 6, value is: 12.000000. + Output index: 7, value is: 14.000000. + Output index: 8, value is: 16.000000. + Output index: 9, value is: 18.000000. + Output index: 10, value is: 20.000000. + Output index: 11, value is: 22.000000. ``` 4. 检查模型缓存(可选)。 @@ -476,15 +688,10 @@ Neural Network Runtime的开发流程主要包含**模型构造**、**模型编 以下为打印结果: ```text - # 0.nncache cache_info.nncache + # 0.nncache 1.nncache 2.nncache cache_info.nncache ``` 如果缓存不再使用,需要手动删除缓存,可以参考以下命令,删除缓存文件。 ```shell rm /data/local/tmp/*nncache - ``` - -## 相关实例 - -第三方AI推理框架对接Neural Network Runtime的流程,可以参考以下相关实例: -- [Tensorflow Lite接入NNRt Delegate开发指南](https://gitee.com/openharmony-sig/neural_network_runtime/tree/master/example/deep_learning_framework) + ``` \ No newline at end of file diff --git a/test/unittest/common/v2_0/compilation_mock_idevice.cpp b/test/unittest/common/v2_0/compilation_mock_idevice.cpp index a08b78cd9217349db2947982cb0f840cf2a15ba0..771c5dbf3f901040a2b4260555bbaae0b00ca70f 100644 --- a/test/unittest/common/v2_0/compilation_mock_idevice.cpp +++ b/test/unittest/common/v2_0/compilation_mock_idevice.cpp @@ -201,13 +201,13 @@ OH_NN_ReturnCode HDIPreparedModelV2_0::ExportModelCache(std::vector int bufferSize = 13; ModelBuffer modelBuffer; std::string aBuffer = "mock_buffer_a"; - modelBuffer.buffer = (void*)aBuffer.c_str(); + modelBuffer.buffer = static_cast(aBuffer.c_str()); modelBuffer.length = bufferSize; modelCache.emplace_back(modelBuffer); ModelBuffer modelBuffer2; std::string bBuffer = "mock_buffer_b"; - modelBuffer2.buffer = (void*)bBuffer.c_str(); + modelBuffer2.buffer = static_cast(bBuffer.c_str()); modelBuffer2.length = bufferSize; modelCache.emplace_back(modelBuffer2); @@ -226,7 +226,7 @@ void* HDIDeviceV2_0::AllocateBuffer(size_t length) return nullptr; } - void* buffer = (void*)malloc(length); + void* buffer = malloc(length); if (buffer == nullptr) { LOGE("HDIDeviceV2_0 mock AllocateBuffer failed, the buffer is nullptr"); return nullptr; diff --git a/test/unittest/common/v2_0/executor_mock_device.cpp b/test/unittest/common/v2_0/executor_mock_device.cpp index 0b6bb30aa80e6d72f1e9df7f5cfcb595bb2e28a4..08d7b38cf3303985625e286d97d255ee1d340099 100644 --- a/test/unittest/common/v2_0/executor_mock_device.cpp +++ b/test/unittest/common/v2_0/executor_mock_device.cpp @@ -45,7 +45,7 @@ void* HDIDeviceV2_0::AllocateBuffer(size_t length) return nullptr; } - void* buffer = (void*)malloc(length); + void* buffer = malloc(length); if (buffer == nullptr) { LOGE("alloct buffer failed"); return nullptr;