diff --git a/BUILD.gn b/BUILD.gn index 0e8e877f8fe3a2ae14981f94f47066810aeb0619..6fba2b59ca86b3168a43040cfb60c951b7765b13 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -14,7 +14,10 @@ import("//build/ohos.gni") group("nnrt_target") { - deps = [ "frameworks:libneural_network_runtime" ] + deps = [ + "frameworks:libneural_network_runtime", + "frameworks:libneural_network_core", + ] } group("nnrt_test_target") { diff --git a/demo.cpp b/demo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4c302c23aab5f26beef091c25e8b1b91ef987748 --- /dev/null +++ b/demo.cpp @@ -0,0 +1,268 @@ +#include "v2_0/neural_network_core.h" +#include "v2_0/neural_network_runtime.h" +#include "common/log.h" +#include + +#define CHECKNEQ(realRet, expectRet, retValue, ...) \ + do { \ + if ((realRet) != (expectRet)) { \ + LOGE(__VA_ARGS__); \ + return (retValue); \ + } \ + } while (0) + +#define CHECKEQ(realRet, expectRet, retValue, ...) \ + do { \ + if ((realRet) == (expectRet)) { \ + LOGE(__VA_ARGS__); \ + return (retValue); \ + } \ + } while (0) + +int main(int argc, char** argv) { + // 查询当前已经对接的backend + // 1. 先查询backend总数 + size_t backendNum = 0; + OH_NNCore_ReturnCode returnCode = OH_NNCore_GetBackendNum(&backendNum); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_GetBackendNum failed."); + // 2. 遍历backend + std::string backendName; + for(size_t i = 0; i < backendNum; ++i) { + const char* backendNameTmp = nullptr; + returnCode = OH_NNCore_GetBackendName(i, &backendNameTmp); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_GetBackendName failed."); + } + + // 创建模型实例,进行模型构造 + OH_NNBackend_Model* model = OH_NNBackend_ConstructModel(); + CHECKNEQ(model, nullptr, -1, "Create model failed."); + + + // 添加Add算子的第一个输入Tensor,类型为float32,张量形状为[1, 2, 2, 3] + OH_NNCore_TensorDesc* tensorDesc = OH_NNCore_CreateTensorDesc(backendName); + CHECKNEQ(tensorDesc, nullptr, -1, "Create TensorDesc failed."); + + int32_t inputDims[4] = {1, 2, 2, 3}; + returnCode = OH_NNCore_SetTensorDescShape(tensorDesc, inputDims, 4); + CHECKEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc shape failed."); + + returnCode = OH_NNCore_SetTensorDescDataType(tensorDesc, OH_NNCORE_FLOAT32); + CHECKEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc data type failed."); + + returnCode = OH_NNCore_SetTensorDescFormat(tensorDesc, OH_NNCORE_FORMAT_NONE); + CHECKEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc format failed."); + + returnCode = OH_NNBackend_SetTensorDescTensorType(tensorDesc, OH_NNBAKEND_TENSOR); + CHECKEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc tensor type failed."); + + returnCode = OH_NNBackend_AddTensorToModel(model, tensorDesc); + CHECKEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Add first TensorDesc to model failed."); + + + // 添加Add算子的第二个输入Tensor,类型为float32,张量形状为[1, 2, 2, 3] + tensorDesc = OH_NNCore_CreateTensorDesc(backendName); + CHECKNEQ(tensorDesc, nullptr, -1, "Create TensorDesc failed."); + + returnCode = OH_NNCore_SetTensorDescShape(tensorDesc, inputDims, 4); + CHECKEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc shape failed."); + + returnCode = OH_NNCore_SetTensorDescDataType(tensorDesc, OH_NNCORE_FLOAT32); + CHECKEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc data type failed."); + + returnCode = OH_NNCore_SetTensorDescFormat(tensorDesc, OH_NNCORE_FORMAT_NONE); + CHECKEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc format failed."); + + returnCode = OH_NNBackend_SetTensorDescTensorType(tensorDesc, OH_NNBACKEND_TENSOR); + CHECKEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc tensor type failed."); + + returnCode = OH_NNBackend_AddTensorToModel(model, tensorDesc); + CHECKEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Add second TensorDesc to model failed."); + + + // 添加Add算子的参数Tensor,该参数Tensor用于指定激活函数的类型,Tensor的数据类型为int8。 + tensorDesc = OH_NNCore_CreateTensorDesc(backendName); + CHECKNEQ(tensorDesc, nullptr, -1, "Create TensorDesc failed."); + + int32_t activationDims = 1; + returnCode = OH_NNCore_SetTensorDescShape(tensorDesc, &activationDims, 1); + CHECKEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc shape failed."); + + returnCode = OH_NNCore_SetTensorDescDataType(tensorDesc, OH_NNCORE_INT8); + CHECKEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc data type failed."); + + returnCode = OH_NNCore_SetTensorDescFormat(tensorDesc, OH_NNCORE_FORMAT_NONE); + CHECKEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc format failed."); + + returnCode = OH_NNBackend_SetTensorDescTensorType(tensorDesc, OH_NNBACKEND_ADD_ACTIVATIONTYPE); + CHECKEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc tensor type failed."); + + returnCode = OH_NNBackend_AddTensorToModel(model, tensorDesc); + CHECKEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Add second TensorDesc to model failed."); + + // 将激活函数类型设置为OH_NNBACKEND_FUSED_NONE,表示该算子不添加激活函数。 + int8_t activationValue = OH_NNBACKEND_FUSED_NONE; + returnCode = OH_NNBackend_SetModelTensorData(model, 2, &activationValue, sizeof(int8_t)); + CHECKEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set model tensor data failed."); + + + // 设置Add算子的输出,类型为float32,张量形状为[1, 2, 2, 3] + tensorDesc = OH_NNCore_CreateTensorDesc(backendName); + CHECKNEQ(tensorDesc, nullptr, -1, "Create TensorDesc failed."); + + returnCode = OH_NNCore_SetTensorDescShape(tensorDesc, inputDims, 4); + CHECKEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc shape failed."); + + returnCode = OH_NNCore_SetTensorDescDataType(tensorDesc, OH_NNCORE_FLOAT32); + CHECKEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc data type failed."); + + returnCode = OH_NNCore_SetTensorDescFormat(tensorDesc, OH_NNCORE_FORMAT_NONE); + CHECKEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc format failed."); + + returnCode = OH_NNBackend_SetTensorDescTensorType(tensorDesc, OH_NNBACKEND_TENSOR); + CHECKEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc tensor type failed."); + + returnCode = OH_NNBackend_AddTensorToModel(model, tensorDesc); + CHECKEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Add forth TensorDesc to model failed."); + + // 指定Add算子的输入、参数和输出索引 + uint32_t inputIndicesValues[2] = {0, 1}; + uint32_t paramIndicesValues = 2; + uint32_t outputIndicesValues = 3; + OH_NNBackend_UInt32Array paramIndices = {¶mIndicesValues, 1}; + OH_NNBackend_UInt32Array inputIndices = {inputIndicesValues, 2}; + OH_NNBackend_UInt32Array outputIndices = {&outputIndicesValues, 1}; + + // 向模型实例添加Add算子 + returnCode = OH_NNBackend_AddOperationToModel(model, OH_NNBACKEND_OPS_ADD, ¶mIndices, &inputIndices, &outputIndices); + CHECKEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Add operation to model failed."); + + // 设置模型实例的输入、输出索引 + returnCode = OH_NNBackend_SpecifyModelInputsAndOutputs(model, &inputIndices, &outputIndices); + CHECKEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Specify model inputs and outputs failed."); + + // 完成模型实例的构建 + returnCode = OH_NNBackend_BuildModel(model); + CHECKEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Build model failed."); + + // 创建compilation,将构图的model或MSLite传下来的model传入 + OH_NNCore_Compilation* compilation = OH_NNCore_ConstructCompilationWithNNModel(model); + CHECKEQ(compilation, nullptr, -1, "OH_NNCore_ConstructCompilationWithNNModel failed."); + OH_NNBackend_DestroyModel(&model); + CHECKEQ(model, nullptr, -1, "Destroy model failed."); + + // 设置backendName + returnCode = OH_NNCore_SetCompilationBackend(compilation, backendName.c_str()); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_SetCompilationBackend failed."); + // 创建并设置compilation options + OH_NNCore_CompilationOptions* compilationOptions = OH_NNBackend_CreateCompilationOptions(); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNBackend_CreateCompilationOptions failed."); + returnCode = OH_NNBackend_SetCompilationPriority(compilationOptions, OH_NNBACKEND_PRIORITY_HIGH); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNBackend_SetCompilationPriority failed."); + returnCode = OH_NNBackend_SetCompilationPerformanceMode(compilationOptions, OH_NNBACKEND_PERFORMANCE_EXTREME); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNBackend_SetCompilationPerformanceMode failed."); + returnCode = OH_NNBackend_SetCompilationEnableFloat16(compilationOptions, true); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNBackend_SetCompilationEnableFloat16 failed."); + returnCode = OH_NNCore_SetCompilationOptions(compilation, compilationOptions); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_SetCompilationOptions failed."); + // 编译生成compiled对象后销毁compilation + OH_NNCore_Compiled* compiled = OH_NNCore_BuildCompilation(compilation); + CHECKEQ(compiled, nullptr, -1, "OH_NNCore_BuildCompilation failed."); + returnCode = OH_NNCore_DestroyCompilation(&compilation); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_DestroyCompilation failed."); + + // 创建并设置compiled options,目前只有cache版本号设置 + OH_NNCore_CompiledOptions* compiledOptions = nullptr; // OH_NNBackend_CreateCompiledOptions(); + CHECKEQ(compiledOptions, nullptr, -1, "OH_NNBackend_CreateCompiledOptions failed."); + // size_t version = 1; + // returnCode = OH_NNBackend_SetCompiledCacheVersion(compiledOptions, version); + // CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNBackend_SetCompiledVersion failed."); + returnCode = OH_NNCore_SetCompiledOptions(compiled, compiledOptions); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_SetCompiledOptions failed."); + // 保存cache + const char* filePath = ""; + returnCode = OH_NNCore_SaveCompiledToFile(compiled, filePath); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_SaveCompiledToFile failed."); + // 从compiled获取输入输出信息 + size_t inputCount = 0; + returnCode = OH_NNCore_GetCompiledInputCount(compiled, &inputCount); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_GetCompiledInputCount failed."); + std::vector inputTensorDescs; + OH_NNCore_TensorDesc* tensorDesc = nullptr; + for (size_t i = 0; i < inputCount; ++i) { + tensorDesc = nullptr; + returnCode = OH_NNCore_GetCompiledInputDesc(compiled, i, &tensorDesc); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_GetCompiledInputDesc failed."); + inputTensorDescs.emplace_back(tensorDesc); + } + size_t outputCount = 0; + returnCode = OH_NNCore_GetCompiledOutputCount(compiled, &outputCount); + std::vector outputTensorDescs; + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_GetCompiledOutputCount failed."); + for (size_t i = 0; i < outputCount; ++i) { + tensorDesc = nullptr; + returnCode = OH_NNCore_GetCompiledOutputDesc(compiled, i, &tensorDesc); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_GetCompiledOutputDesc failed."); + outputTensorDescs.emplace_back(tensorDesc); + } + + // 从compiled中创建executor + OH_NNCore_Executor* executor = OH_NNCore_ConstructExecutor(compiled); + CHECKEQ(executor, nullptr, -1, "OH_NNCore_ConstructExecutor failed."); + // 销毁compiled + returnCode = OH_NNCore_DestroyCompiled(&compiled); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_DestroyCompiled failed."); + // 创建输入输出Tensor + OH_NNCore_Tensor* inputTensors[inputCount]; + OH_NNCore_Tensor* tensor = nullptr; + size_t byteSize = 0; + OH_NNBackend_Memory* memory = nullptr; + for (size_t i = 0; i < inputCount; ++i) { + tensor = nullptr; + byteSize = 0; + tensor = OH_NNBackend_CreateTensor(inputTensorDescs[i]); + CHECKEQ(tensor, nullptr, -1, "OH_NNBackend_CreateTensor failed."); + returnCode = OH_NNCore_GetTensorDescByteSize(inputTensorDescs[i], &byteSize); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_GetTensorDescByteSize failed."); + memory = OH_NNBackend_AllocateMemory(executor, byteSize); + CHECKEQ(memory, nullptr, -1, "OH_NNBackend_AllocateMemory failed."); + returnCode = OH_NNBackend_SetTensorData(tensor, memory); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNBackend_SetTensorData failed."); + inputTensors[i] = tensor; + } + OH_NNCore_Tensor* outputTensors[outputCount]; + for (size_t i = 0; i < outputCount; ++i) { + tensor = nullptr; + memory = nullptr; + byteSize = 0; + tensor = OH_NNBackend_CreateTensor(outputTensorDescs[i]); + CHECKEQ(tensor, nullptr, -1, "OH_NNBackend_CreateTensor failed."); + returnCode = OH_NNCore_GetTensorDescByteSize(outputTensorDescs[i], &byteSize); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_GetTensorDescByteSize failed."); + memory = OH_NNBackend_AllocateMemory(executor, byteSize); + CHECKEQ(memory, nullptr, -1, "OH_NNBackend_AllocateMemory failed."); + returnCode = OH_NNBackend_SetTensorData(tensor, memory); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNBackend_SetTensorData failed."); + outputTensors[i] = tensor; + } + // 执行run + returnCode = OH_NNCore_ExecutorRunSync(executor, inputTensors, inputCount, outputTensors, outputCount); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_ExecutorRunSync failed."); + // 清理输入输出Tensor + for (size_t i = 0; i < inputCount; ++i) { + OH_NNBackend_Memory* memoryTmp = OH_NNBackend_GetTensorData(inputTensors[i]); + CHECKEQ(memoryTmp, nullptr, -1, "OH_NNBackend_GetTensorData failed."); + returnCode = OH_NNBackend_ReleaseMemory(executor, &memoryTmp); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNBackend_ReleaseMemory failed."); + } + for (size_t i = 0; i < outputCount; ++i) { + OH_NNBackend_Memory* memoryTmp = OH_NNBackend_GetTensorData(outputTensors[i]); + CHECKEQ(memoryTmp, nullptr, -1, "OH_NNBackend_GetTensorData failed."); + returnCode = OH_NNBackend_ReleaseMemory(executor, &memoryTmp); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNBackend_ReleaseMemory failed."); + } + // 销毁Executor + returnCode = OH_NNCore_DestroyExecutor(&executor); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_DestroyExecutor failed."); + + return 0; +} \ No newline at end of file diff --git a/frameworks/BUILD.gn b/frameworks/BUILD.gn index b5dee031f3af52d41e82f21a664ac013d72234ab..fd7f10cc0ace4aab0e968dd7acc7198b66064287 100644 --- a/frameworks/BUILD.gn +++ b/frameworks/BUILD.gn @@ -14,33 +14,39 @@ import("//build/ohos.gni") config("nnrt_config") { - cflags_cc = [ "-fexceptions" ] + cflags_cc = [ "-fexceptions", "-frtti" ] include_dirs = [ + "./native", "..", "../interfaces/innerkits/c", + "../interfaces/kits/c", + "../interfaces/kits/c/v1_0", + "../interfaces/kits/c/v2_0", ] } nnrt_sources = [ - "native/compilation.cpp", - "native/device_discover_v1_0.cpp", - "native/device_discover_v2_0.cpp", - "native/device_manager.cpp", - "native/device_registrar.cpp", - "native/execution_plan.cpp", - "native/executor.cpp", - "native/hdi_device_v1_0.cpp", - "native/hdi_device_v2_0.cpp", - "native/hdi_prepared_model_v1_0.cpp", - "native/hdi_prepared_model_v2_0.cpp", - "native/inner_model.cpp", - "native/memory_manager.cpp", - "native/neural_network_runtime.cpp", - "native/nn_tensor.cpp", - "native/ops_builder.cpp", - "native/ops_registry.cpp", - "native/transform.cpp", - "native/validation.cpp", + "native/compat/compilation.cpp", + "native/compat/device_discover_v1_0.cpp", + "native/compat/device_discover_v2_0.cpp", + "native/compat/device_manager.cpp", + "native/compat/device_registrar.cpp", + "native/compat/execution_plan.cpp", + "native/compat/executor.cpp", + "native/compat/hdi_device_v1_0.cpp", + "native/compat/hdi_device_v2_0.cpp", + "native/compat/hdi_prepared_model_v1_0.cpp", + "native/compat/hdi_prepared_model_v2_0.cpp", + "native/compat/inner_model.cpp", + "native/compat/memory_manager.cpp", + "native/compat/neural_network_runtime_compat.cpp", + "native/compat/nn_tensor.cpp", + "native/compat/ops_builder.cpp", + "native/compat/ops_registry.cpp", + "native/compat/transform.cpp", + "native/compat/validation.cpp", + "native/compat/transform_nnbackend_to_nncore.cpp", + "native/compat/transform_nncore_to_nnbackend.cpp", ] ops_sources = [ @@ -103,12 +109,28 @@ ops_sources = [ "native/ops/unsqueeze_builder.cpp", ] +nnbackend_sources = [ + "native/neural_network_runtime.cpp", + "native/nnbackend.cpp", + "native/nn_validation.cpp", + "native/nncompiled_cache.cpp", + "native/nncompiled.cpp", + "native/nncompiler.cpp", + "native/nnexecutor.cpp", + "native/nnoptions.cpp", + "native/nntensor.cpp", + "native/quant_param.cpp", + "native/register_hdi_device_v1_0.cpp", + "native/register_hdi_device_v2_0.cpp", + #"native/demo.cpp", +] + ohos_shared_library("libneural_network_runtime") { sources = nnrt_sources sources += ops_sources + sources += nnbackend_sources output_extension = "so" include_dirs = [ - "..", "//third_party/mindspore/mindspore-src/source/mindspore/lite/mindir/include", ] @@ -120,6 +142,10 @@ ohos_shared_library("libneural_network_runtime") { public_configs = [ ":nnrt_config" ] all_dependent_configs = [ ":nnrt_config" ] + deps = [ + ":libneural_network_core", + ] + external_deps = [ "c_utils:utils", "drivers_interface_nnrt:libnnrt_proxy_1.0", @@ -134,3 +160,37 @@ ohos_shared_library("libneural_network_runtime") { innerapi_tags = [ "ndk" ] part_name = "neural_network_runtime" } + +nnrt_core_sources = [ + "native/backend_manager.cpp", + "native/backend_registrar.cpp", + "native/neural_network_core.cpp", + "native/tensor_desc.cpp", + "native/transform.cpp", + "native/validation.cpp", +] + +ohos_shared_library("libneural_network_core") { + sources = nnrt_core_sources + output_extension = "so" + include_dirs = [ + ] + + install_images = [ + "system", + "updater", + ] + + public_configs = [ ":nnrt_config" ] + all_dependent_configs = [ ":nnrt_config" ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "hitrace:libhitracechain", + ] + + subsystem_name = "ai" + innerapi_tags = [ "ndk" ] + part_name = "neural_network_runtime" +} diff --git a/frameworks/native/CMakeLists.txt b/frameworks/native/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..7343c06afe4b473260a3d801975633ea71d3682c --- /dev/null +++ b/frameworks/native/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.0.0) +project(testdemo) + +list(APPEND OHOS_C_COMPILER_FLAGS -march=armv7a) + +add_executable(testdemo demo.cpp) +target_include_directories(testdemo PUBLIC + ../../interfaces/kits/c) + +target_link_directories(testdemo PUBLIC /home/wcx/wcx/ohos1104/out/rk3568/ai/neural_network_runtime/) +target_link_libraries(testdemo PUBLIC + hilog_ndk.z.so + libneural_network_core.so + libneural_network_runtime.so) + +set(CMAKE_EXE_LINKER_FLAGS "${cmake_exe_linker_flags} -Wl,--allow-shlib-undefined") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv7a") \ No newline at end of file diff --git a/frameworks/native/backend.h b/frameworks/native/backend.h new file mode 100644 index 0000000000000000000000000000000000000000..e76be1e10affcea1ae3e463bf7422d838cdb68fc --- /dev/null +++ b/frameworks/native/backend.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_CORE_BACKEND_H +#define NEURAL_NETWORK_CORE_BACKEND_H + +#include +#include + +#include "compiler.h" +#include "compiled.h" +#include "executor.h" +#include "options.h" +#include "tensor.h" +#include "v2_0/neural_network_core_type.h" + +namespace OHOS { +namespace NeuralNetworkCore { +class Backend { +public: + Backend() = default; + virtual ~Backend() = default; + + virtual OH_NNCore_ReturnCode GetBackendName(std::string& backendName) const = 0; + virtual OH_NNCore_ReturnCode GetBackendStatus(OH_NNCore_BackendStatus& status) const = 0; + + virtual Options* CreateOptions() = 0; + virtual OH_NNCore_ReturnCode DestroyOptions(Options* options) = 0; + + virtual Compiler* CreateCompiler() = 0; + virtual OH_NNCore_ReturnCode DestroyCompiler(Compiler* compiler) = 0; + + virtual Compiled* CreateCompiled(const std::string& filePath, const OH_NNCore_Options* options) = 0; + virtual Compiled* CreateCompiled(const void* buffer, size_t modelSize, const OH_NNCore_Options* options) = 0; + virtual OH_NNCore_ReturnCode DestroyCompiled(Compiled* compiled) = 0; + + virtual OH_NNCore_ReturnCode DestroyExecutor(Executor* executor) = 0; + + virtual Tensor* CreateTensor( + const std::string& backendName, OHOS::NeuralNetworkCore::TensorDesc* desc) = 0; + virtual OH_NNCore_ReturnCode DestroyTensor(Tensor* tensor) = 0; +}; +} // namespace NeuralNetworkCore +} // namespace OHOS +#endif // NEURAL_NETWORK_CORE_BACKEND_H diff --git a/frameworks/native/backend_manager.cpp b/frameworks/native/backend_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9a8ab53cf74492feeb4e4a266263782b4077e55f --- /dev/null +++ b/frameworks/native/backend_manager.cpp @@ -0,0 +1,111 @@ +#include "backend_manager.h" + +#include +#include "common/log.h" + +namespace OHOS { +namespace NeuralNetworkCore { +const int EACH_REGISTERED_BACKEND_NUM = 1; + +BackendManager::~BackendManager() +{ + m_backends.clear(); +} + +OH_NNCore_ReturnCode BackendManager::GetBackendNum(size_t* backendNum) +{ + *backendNum = m_backendNames.size(); + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode BackendManager::GetBackendName(size_t index, const char** backendName) +{ + if (index >= m_backendNames.size()) { + LOGE("[BackendManager] GetbackendName failed, index is larger than backend names size."); + return OH_NNCORE_INVALID_PARAMETER; + } + *backendName = m_backendNames[index].c_str(); + + return OH_NNCORE_SUCCESS; +} + +std::shared_ptr BackendManager::GetBackend(const std::string& backendName) +{ + if (backendName.empty()) { + const auto& backendIter = m_backends.begin(); + std::vector> backends = backendIter->second; + if (backends.size() != EACH_REGISTERED_BACKEND_NUM) { + LOGE("Get backend failed, the default backends named %s is not unique.", backendName.c_str()); + return nullptr; + } + return backends[0]; + } + + if (m_backends.find(backendName) == m_backends.end()) { + LOGE("Get backend failed, not find target backend named %s", backendName.c_str()); + return nullptr; + } + + for (auto iter = m_backends.begin(); iter != m_backends.end(); iter++) { + if (iter->first == backendName) { + std::vector> backends = iter->second; + if (backends.size() != EACH_REGISTERED_BACKEND_NUM) { + LOGE("Get backend failed, the target backends named %s is not unique.", backendName.c_str()); + return nullptr; + } + return backends[0]; + } + } + + return nullptr; +} + +OH_NNCore_ReturnCode BackendManager::RegisterBackend(std::function()> creator) +{ + auto regBackend = creator(); + if (regBackend == nullptr) { + LOGE("Cannot create backend, register backend failed."); + return OH_NNCORE_FAILED; + } + + if (!IsValidBackend(regBackend)) { + LOGE("Backend is not available."); + return OH_NNCORE_UNAVAILABLE_BACKEND; + } + + std::string backendName; + OH_NNCore_ReturnCode ret = regBackend->GetBackendName(backendName); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("Get backend name failed."); + return ret; + } + + const std::lock_guard lock(m_mtx); + + auto iter = m_backends.find(backendName); + if (iter == m_backends.end()) { + std::vector> backends = {regBackend}; + m_backends.emplace(backendName, backends); + m_backendNames.emplace_back(backendName); + } else { + std::vector>& backends = iter->second; + backends.emplace_back(regBackend); + m_backends[backendName] = backends; + } + + return OH_NNCORE_SUCCESS; +} + +bool BackendManager::IsValidBackend(std::shared_ptr backend) const +{ + OH_NNCore_BackendStatus status = OH_NNCORE_UNKNOWN_BACKEND_STATUS; + + OH_NNCore_ReturnCode ret = backend->GetBackendStatus(status); + if (ret != OH_NNCORE_SUCCESS || status == OH_NNCORE_UNKNOWN_BACKEND_STATUS || status == OH_NNCORE_OFFLINE) { + return false; + } + + return true; +} +} // NeuralNetworkCore +} // OHOS \ No newline at end of file diff --git a/frameworks/native/backend_manager.h b/frameworks/native/backend_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..a60154249ea39fb344c2ad46ef9d033a6e626ced --- /dev/null +++ b/frameworks/native/backend_manager.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_CORE_BACKEND_MANAGER_H +#define NEURAL_NETWORK_CORE_BACKEND_MANAGER_H + +#include +#include +#include +#include +#include + +#include "backend.h" + +namespace OHOS { +namespace NeuralNetworkCore { +class BackendManager { +public: + // Register backend by C++ API + OH_NNCore_ReturnCode RegisterBackend(std::function()> creator); + + OH_NNCore_ReturnCode GetBackendNum(size_t *backendNum); + + OH_NNCore_ReturnCode GetBackendName(size_t index, const char** name); + + // Get registered backend by backend name + std::shared_ptr GetBackend(const std::string& backendName); + + static BackendManager& GetInstance() + { + static BackendManager instance; + return instance; + } + +private: + BackendManager() = default; + BackendManager(const BackendManager&) = delete; + BackendManager& operator=(const BackendManager&) = delete; + virtual ~BackendManager(); + bool IsValidBackend(std::shared_ptr backend) const; + +private: + // key is the name of backend, each backend list only contain one backend. + std::map>> m_backends; + std::vector m_backendNames; + std::mutex m_mtx; +}; +} // namespace NeuralNetworkCore +} // namespace OHOS +#endif // NEURAL_NETWORK_CORE_BACKEND_MANAGER_H diff --git a/frameworks/native/backend_registrar.cpp b/frameworks/native/backend_registrar.cpp new file mode 100644 index 0000000000000000000000000000000000000000..87c051d5416d2dd52e97f045db26be1a8b176942 --- /dev/null +++ b/frameworks/native/backend_registrar.cpp @@ -0,0 +1,18 @@ +#include "backend_registrar.h" + +#include "common/log.h" +#include "backend_manager.h" +#include "neural_network_core_type.h" + +namespace OHOS { +namespace NeuralNetworkCore { +BackendRegistrar::BackendRegistrar(const CreateBackend creator) +{ + auto& backendManager = BackendManager::GetInstance(); + OH_NNCore_ReturnCode ret = backendManager.RegisterBackend(creator); + if (ret != OH_NNCORE_SUCCESS) { + LOGW("Register backend failed. ErrorCode=%d", ret); + } +} +} // namespace NeuralNetworkCore +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/backend_registrar.h b/frameworks/native/backend_registrar.h new file mode 100644 index 0000000000000000000000000000000000000000..5d9ccfaa9647b000ff70ba11b3cb8ec217fb60bd --- /dev/null +++ b/frameworks/native/backend_registrar.h @@ -0,0 +1,22 @@ +#include +#include +#include + +#include "backend.h" + +namespace OHOS { +namespace NeuralNetworkCore { +using CreateBackend = std::function()>; + +class BackendRegistrar { +public: + explicit BackendRegistrar(const CreateBackend creator); + ~BackendRegistrar() = default; +}; + +#define REGISTER_BACKEND(backend, creator) \ + namespace { \ + static OHOS::NeuralNetworkCore::BackendRegistrar g_##backendName##_backend_registrar(creator); \ + } // namespace +} // NeuralNetworkCore +} // OHOS \ No newline at end of file diff --git a/frameworks/native/compilation.cpp b/frameworks/native/compat/compilation.cpp similarity index 100% rename from frameworks/native/compilation.cpp rename to frameworks/native/compat/compilation.cpp diff --git a/frameworks/native/compilation.h b/frameworks/native/compat/compilation.h similarity index 100% rename from frameworks/native/compilation.h rename to frameworks/native/compat/compilation.h diff --git a/frameworks/native/cpp_type.h b/frameworks/native/compat/cpp_type.h similarity index 96% rename from frameworks/native/cpp_type.h rename to frameworks/native/compat/cpp_type.h index 2f256cc2297e54c527d7fed8e0b429eca9d0a3df..2550d9c41d2e85f05fcacfe25b9e87d003606985 100644 --- a/frameworks/native/cpp_type.h +++ b/frameworks/native/compat/cpp_type.h @@ -20,7 +20,7 @@ #include #include -#include "interfaces/kits/c/neural_network_runtime_type.h" +#include "v1_0/neural_network_runtime_type_compat.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/device.h b/frameworks/native/compat/device.h similarity index 94% rename from frameworks/native/device.h rename to frameworks/native/compat/device.h index f8f3ecc52c55117021bedd8862138e4ecb12cd2a..8e06dea789d027bbf9b5c1bfaf03cd1975b05214 100644 --- a/frameworks/native/device.h +++ b/frameworks/native/compat/device.h @@ -20,7 +20,7 @@ #include #include -#include "interfaces/kits/c/neural_network_runtime_type.h" +#include "v1_0/neural_network_runtime_type_compat.h" #include "cpp_type.h" #include "nn_tensor.h" #include "prepared_model.h" @@ -64,6 +64,9 @@ public: virtual void* AllocateBuffer(size_t length) = 0; virtual void* AllocateTensorBuffer(size_t length, std::shared_ptr tensor) = 0; virtual OH_NN_ReturnCode ReleaseBuffer(const void* buffer) = 0; + + virtual OH_NN_ReturnCode AllocateBuffer(size_t length, int& fd) = 0; + virtual OH_NN_ReturnCode ReleaseBuffer(int fd, size_t length) = 0; }; } // namespace NeuralNetworkRuntime } // namespace OHOS diff --git a/frameworks/native/device_discover.h b/frameworks/native/compat/device_discover.h similarity index 100% rename from frameworks/native/device_discover.h rename to frameworks/native/compat/device_discover.h diff --git a/frameworks/native/device_discover_v1_0.cpp b/frameworks/native/compat/device_discover_v1_0.cpp similarity index 100% rename from frameworks/native/device_discover_v1_0.cpp rename to frameworks/native/compat/device_discover_v1_0.cpp diff --git a/frameworks/native/device_discover_v2_0.cpp b/frameworks/native/compat/device_discover_v2_0.cpp similarity index 100% rename from frameworks/native/device_discover_v2_0.cpp rename to frameworks/native/compat/device_discover_v2_0.cpp diff --git a/frameworks/native/device_manager.cpp b/frameworks/native/compat/device_manager.cpp similarity index 100% rename from frameworks/native/device_manager.cpp rename to frameworks/native/compat/device_manager.cpp diff --git a/frameworks/native/device_manager.h b/frameworks/native/compat/device_manager.h similarity index 97% rename from frameworks/native/device_manager.h rename to frameworks/native/compat/device_manager.h index 4d8b9fbd35e1c029c9c8ab46c6a620ce12c63ed6..e6ecd7c11687c51737de5f5e07771edb74d2bbdd 100644 --- a/frameworks/native/device_manager.h +++ b/frameworks/native/compat/device_manager.h @@ -24,7 +24,7 @@ #include #include "device.h" -#include "interfaces/kits/c/neural_network_runtime_type.h" +#include "v1_0/neural_network_runtime_type_compat.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/device_registrar.cpp b/frameworks/native/compat/device_registrar.cpp similarity index 100% rename from frameworks/native/device_registrar.cpp rename to frameworks/native/compat/device_registrar.cpp diff --git a/frameworks/native/device_registrar.h b/frameworks/native/compat/device_registrar.h similarity index 100% rename from frameworks/native/device_registrar.h rename to frameworks/native/compat/device_registrar.h diff --git a/frameworks/native/execution_plan.cpp b/frameworks/native/compat/execution_plan.cpp similarity index 100% rename from frameworks/native/execution_plan.cpp rename to frameworks/native/compat/execution_plan.cpp diff --git a/frameworks/native/execution_plan.h b/frameworks/native/compat/execution_plan.h similarity index 94% rename from frameworks/native/execution_plan.h rename to frameworks/native/compat/execution_plan.h index 54f4648b21372a1a23b6a9d7bef5dd0ec023e36b..ba54128a6b2e8d82363af4dcca309415918ea342 100644 --- a/frameworks/native/execution_plan.h +++ b/frameworks/native/compat/execution_plan.h @@ -16,8 +16,8 @@ #ifndef NEURAL_NETWORK_RUNTIME_EXECUTION_PLAN_H #define NEURAL_NETWORK_RUNTIME_EXECUTION_PLAN_H -#include "frameworks/native/nn_tensor.h" -#include "interfaces/kits/c/neural_network_runtime_type.h" +#include "nn_tensor.h" +#include "v1_0/neural_network_runtime_type_compat.h" #include "prepared_model.h" #include "device.h" diff --git a/frameworks/native/executor.cpp b/frameworks/native/compat/executor.cpp similarity index 100% rename from frameworks/native/executor.cpp rename to frameworks/native/compat/executor.cpp diff --git a/frameworks/native/compat/executor.h b/frameworks/native/compat/executor.h new file mode 100644 index 0000000000000000000000000000000000000000..42cd2807924673210d4f82b1b33d98399f2f5f3f --- /dev/null +++ b/frameworks/native/compat/executor.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_RUNTIME_EXECUTOR_H +#define NEURAL_NETWORK_RUNTIME_EXECUTOR_H + +#include "compilation.h" +#include "execution_plan.h" +#include "nn_tensor.h" +#include "v1_0/neural_network_runtime_compat.h" +#include "device.h" + +namespace OHOS { +namespace NeuralNetworkRuntime { +class Executor { +public: + explicit Executor(const Compilation* compilation); + ~Executor(); + + OH_NN_ReturnCode SetInput(uint32_t index, const OH_NN_Tensor& nnTensor, const void* buffer, size_t length); + OH_NN_ReturnCode SetInputFromMemory(uint32_t index, const OH_NN_Tensor& nnTensor, const OH_NN_Memory& memory); + OH_NN_ReturnCode SetOutput(uint32_t index, void* buffer, size_t length); + OH_NN_ReturnCode SetOutputFromMemory(uint32_t index, const OH_NN_Memory& memory); + OH_NN_ReturnCode GetOutputShape(uint32_t index, int32_t** dimensions, uint32_t& dimensionCount); + + OH_NN_ReturnCode CreateInputMemory(uint32_t index, size_t length, OH_NN_Memory** memory); + OH_NN_ReturnCode CreateOutputMemory(uint32_t index, size_t length, OH_NN_Memory** memory); + OH_NN_ReturnCode DestroyInputMemory(uint32_t index, OH_NN_Memory** memory); + OH_NN_ReturnCode DestroyOutputMemory(uint32_t index, OH_NN_Memory** memory); + + OH_NN_ReturnCode Run(); + +private: + OH_NN_ReturnCode BuildInputTensor(uint32_t index, const OH_NN_Tensor& nnTensor, + std::shared_ptr inputTensor) const; + OH_NN_ReturnCode SetInputTensorWithCurrentBuffer(uint32_t index, std::shared_ptr inputTensor, + const void* buffer, size_t dataLength, size_t curBufferLength); + void SetInputTensorWithNewBuffer(uint32_t index, std::shared_ptr inputTensor, + const void* inputBuffer, size_t length, bool isInnerMem); + OH_NN_ReturnCode CheckInputDimRanges(uint32_t index, const OH_NN_Tensor& nnTensor) const; + +private: + struct ExeTensor { + std::shared_ptr tensor; + void* userBuffer; + size_t userBufferLength; + bool isInnerMem; + }; + bool m_isRun {false}; + std::vector> m_modelInputs; + std::vector> m_modelOutputs; + std::shared_ptr m_executionPlan {nullptr}; + std::unordered_map> m_outputDimensions; + std::unordered_map m_inputTensors; + std::unordered_map m_outputTensors; + std::unordered_map> m_inputCreatedMem; + std::unordered_map> m_outputCreatedMem; +}; +} // namespace NeuralNetworkRuntime +} // namespace OHOS +#endif \ No newline at end of file diff --git a/frameworks/native/hdi_device_v1_0.cpp b/frameworks/native/compat/hdi_device_v1_0.cpp similarity index 94% rename from frameworks/native/hdi_device_v1_0.cpp rename to frameworks/native/compat/hdi_device_v1_0.cpp index 3a4582e694612e34a6e052471445802fdaed7edb..093c9325dae73cfc4f9b02c2034d7081be329f4c 100644 --- a/frameworks/native/hdi_device_v1_0.cpp +++ b/frameworks/native/compat/hdi_device_v1_0.cpp @@ -393,6 +393,35 @@ OH_NN_ReturnCode HDIDeviceV1_0::ReleaseBuffer(const void* buffer) return OH_NN_SUCCESS; } +OH_NN_ReturnCode HDIDeviceV1_0::AllocateBuffer(size_t length, int& fd) +{ + if (length == 0) { + LOGE("The length param is invalid, length=0"); + return OH_NN_INVALID_PARAMETER; + } + + V1_0::SharedBuffer buffer; + auto ret = m_iDevice->AllocateBuffer(length, buffer); + if (ret != HDF_SUCCESS) { + LOGE("Allocate buffer error. ErrorCode: %d", ret); + return OH_NN_MEMORY_ERROR; + } + + fd = buffer.fd; + return OH_NN_SUCCESS; +} + +OH_NN_ReturnCode HDIDeviceV1_0::ReleaseBuffer(int fd, size_t length) +{ + V1_0::SharedBuffer hdiBuffer {fd, length, 0, length}; + auto deviceResult = m_iDevice->ReleaseBuffer(hdiBuffer); + if (deviceResult != HDF_SUCCESS) { + LOGE("Device release buffer error. ErrorCode: %d", deviceResult); + return OH_NN_MEMORY_ERROR; + } + return OH_NN_SUCCESS; +} + OH_NN_ReturnCode HDIDeviceV1_0::ReleaseSharedBuffer(const V1_0::SharedBuffer& buffer) { if (buffer.fd == INVALID_FD) { diff --git a/frameworks/native/hdi_device_v1_0.h b/frameworks/native/compat/hdi_device_v1_0.h similarity index 96% rename from frameworks/native/hdi_device_v1_0.h rename to frameworks/native/compat/hdi_device_v1_0.h index 77a9d85332aa7a4c9a0bb332a2ce8da401bbae9e..1c048b8614e4ce4b46fc70277c0806e36f4e9663 100644 --- a/frameworks/native/hdi_device_v1_0.h +++ b/frameworks/native/compat/hdi_device_v1_0.h @@ -62,6 +62,9 @@ public: void* AllocateTensorBuffer(size_t length, std::shared_ptr tensor) override; OH_NN_ReturnCode ReleaseBuffer(const void* buffer) override; + OH_NN_ReturnCode AllocateBuffer(size_t length, int& fd) override; + OH_NN_ReturnCode ReleaseBuffer(int fd, size_t length) override; + private: OH_NN_ReturnCode ReleaseSharedBuffer(const V1_0::SharedBuffer& buffer); diff --git a/frameworks/native/hdi_device_v2_0.cpp b/frameworks/native/compat/hdi_device_v2_0.cpp similarity index 96% rename from frameworks/native/hdi_device_v2_0.cpp rename to frameworks/native/compat/hdi_device_v2_0.cpp index e55d6a683152dc11537d86df085662885d0973a4..74a7cebde192acdaaeab1bb952380fcea8ca8819 100644 --- a/frameworks/native/hdi_device_v2_0.cpp +++ b/frameworks/native/compat/hdi_device_v2_0.cpp @@ -427,6 +427,33 @@ OH_NN_ReturnCode HDIDeviceV2_0::ReleaseBuffer(const void* buffer) return OH_NN_SUCCESS; } +OH_NN_ReturnCode HDIDeviceV2_0::AllocateBuffer(size_t length, int& fd) +{ + if (length == 0) { + LOGE("The length param is invalid, length=0"); + return OH_NN_INVALID_PARAMETER; + } + + V2_0::SharedBuffer buffer; + auto ret = m_iDevice->AllocateBuffer(length, buffer); + if (ret != V2_0::NNRT_ReturnCode::NNRT_SUCCESS) { + return CheckReturnCode(ret, OH_NN_MEMORY_ERROR, "Allocate buffer error"); + } + + fd = buffer.fd; + return OH_NN_SUCCESS; +} + +OH_NN_ReturnCode HDIDeviceV2_0::ReleaseBuffer(int fd, size_t length) +{ + V2_0::SharedBuffer hdiBuffer {fd, length, 0, length}; + auto deviceResult = m_iDevice->ReleaseBuffer(hdiBuffer); + if (deviceResult != V2_0::NNRT_ReturnCode::NNRT_SUCCESS) { + return CheckReturnCode(deviceResult, OH_NN_FAILED, "Device release buffer error"); + } + return OH_NN_SUCCESS; +} + OH_NN_ReturnCode HDIDeviceV2_0::ReleaseSharedBuffer(const V2_0::SharedBuffer& buffer) { if (buffer.fd == INVALID_FD) { diff --git a/frameworks/native/hdi_device_v2_0.h b/frameworks/native/compat/hdi_device_v2_0.h similarity index 96% rename from frameworks/native/hdi_device_v2_0.h rename to frameworks/native/compat/hdi_device_v2_0.h index d3c34614536997c4faa1d34feb738def1b9746af..b8bfdf83b780c3580183453a50464897119ce356 100644 --- a/frameworks/native/hdi_device_v2_0.h +++ b/frameworks/native/compat/hdi_device_v2_0.h @@ -62,6 +62,9 @@ public: void* AllocateTensorBuffer(size_t length, std::shared_ptr tensor) override; OH_NN_ReturnCode ReleaseBuffer(const void* buffer) override; + OH_NN_ReturnCode AllocateBuffer(size_t length, int& fd) override; + OH_NN_ReturnCode ReleaseBuffer(int fd, size_t length) override; + private: OH_NN_ReturnCode ReleaseSharedBuffer(const V2_0::SharedBuffer& buffer); OH_NN_ReturnCode GetOfflineModelFromLiteGraph(std::shared_ptr graph, diff --git a/frameworks/native/hdi_prepared_model_v1_0.cpp b/frameworks/native/compat/hdi_prepared_model_v1_0.cpp similarity index 51% rename from frameworks/native/hdi_prepared_model_v1_0.cpp rename to frameworks/native/compat/hdi_prepared_model_v1_0.cpp index d697ea334bb2bac5a5d6ab10ed320d01ec3ac645..904f12c067d278230c429e1ed534c7aaf4ffcc14 100644 --- a/frameworks/native/hdi_prepared_model_v1_0.cpp +++ b/frameworks/native/compat/hdi_prepared_model_v1_0.cpp @@ -17,6 +17,7 @@ #include "common/log.h" #include "memory_manager.h" +#include "nntensor.h" namespace OHOS { namespace NeuralNetworkRuntime { @@ -65,6 +66,50 @@ V1_0::Format TransFormat(const OH_NN_Format& format) } } +V1_0::DataType TransDataType(const OH_NNCore_DataType& dataType) +{ + switch (dataType) { + case OH_NNCORE_BOOL: + return V1_0::DataType::DATA_TYPE_BOOL; + case OH_NNCORE_INT8: + return V1_0::DataType::DATA_TYPE_INT8; + case OH_NNCORE_INT16: + return V1_0::DataType::DATA_TYPE_INT16; + case OH_NNCORE_INT32: + return V1_0::DataType::DATA_TYPE_INT32; + case OH_NNCORE_INT64: + return V1_0::DataType::DATA_TYPE_INT64; + case OH_NNCORE_UINT8: + return V1_0::DataType::DATA_TYPE_UINT8; + case OH_NNCORE_UINT16: + return V1_0::DataType::DATA_TYPE_UINT16; + case OH_NNCORE_UINT32: + return V1_0::DataType::DATA_TYPE_UINT32; + case OH_NNCORE_UINT64: + return V1_0::DataType::DATA_TYPE_UINT64; + case OH_NNCORE_FLOAT16: + return V1_0::DataType::DATA_TYPE_FLOAT16; + case OH_NNCORE_FLOAT32: + return V1_0::DataType::DATA_TYPE_FLOAT32; + case OH_NNCORE_FLOAT64: + return V1_0::DataType::DATA_TYPE_FLOAT64; + default: + return V1_0::DataType::DATA_TYPE_UNKNOWN; + } +} + +V1_0::Format TransFormat(const OH_NNCore_Format& format) +{ + switch (format) { + case OH_NNCORE_FORMAT_NCHW: + return V1_0::Format::FORMAT_NCHW; + case OH_NNCORE_FORMAT_NHWC: + return V1_0::Format::FORMAT_NHWC; + default: + return V1_0::Format::FORMAT_NONE; + } +} + V1_0::IOTensor TransIOTensor(const IOTensor& tensor) { V1_0::IOTensor iTensor; @@ -91,6 +136,72 @@ V1_0::IOTensor TransIOTensor(const IOTensor& tensor) return iTensor; } + +OH_NNCore_ReturnCode TransIOTensor(const OH_NNCore_Tensor* tensor, V1_0::IOTensor& ioTensor) +{ + if (tensor == nullptr) { + LOGE("TransIOTensor failed, failed to transform to v1_0 IOTensor."); + return OH_NNCORE_NULL_PTR; + } + + const OHOS::NeuralNetworkBackend::NNTensor* nnTensor = + reinterpret_cast(tensor); + OHOS::NeuralNetworkCore::TensorDesc* nnTensorDesc = nnTensor->GetTensorDesc(); + if (nnTensorDesc == nullptr) { + LOGE("TransIOTensor failed, failed to get desc from tensor."); + return OH_NNCORE_NULL_PTR; + } + + // convert name + const char* tensorName = nullptr; + OH_NNCore_ReturnCode ret = nnTensorDesc->GetName(&tensorName); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("TransIOTensor failed, failed to get name from desc."); + return ret; + } + ioTensor.name = tensorName; + + // convert data type + OH_NNCore_DataType dataType; + ret = nnTensorDesc->GetDataType(&dataType); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("TransIOTensor failed, failed to get data type from desc."); + return ret; + } + ioTensor.dataType = TransDataType(dataType); + + // convert format + OH_NNCore_Format format; + ret = nnTensorDesc->GetFormat(&format); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("TransIOTensor failed, failed to get format from desc."); + return ret; + } + ioTensor.format = TransFormat(format); + + // convert shape + int32_t* shape = nullptr; + size_t shapeNum = 0; + ret = nnTensorDesc->GetShape(&shape, &shapeNum); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("TransIOTensor failed, failed to get shape from desc."); + return ret; + } + ioTensor.dimensions.clear(); + for (size_t i = 0; i < shapeNum; ++i) { + ioTensor.dimensions.emplace_back(shape[i]); + } + + // convert data + if (!nnTensor->CheckTensorData()) { + LOGE("TransIOTensor failed, failed to check tensor data."); + return OH_NNCORE_INVALID_PARAMETER; + } + V1_0::SharedBuffer iBuffer {nnTensor->GetFd(), nnTensor->GetSize(), nnTensor->GetOffset(), nnTensor->GetSize()}; + ioTensor.data = iBuffer; + + return OH_NNCORE_SUCCESS; +} } // unamed namespace HDIPreparedModelV1_0::HDIPreparedModelV1_0(OHOS::sptr hdiPreparedModel) @@ -160,5 +271,47 @@ OH_NN_ReturnCode HDIPreparedModelV1_0::Run(const std::vector& inputs, return OH_NN_SUCCESS; } + +OH_NN_ReturnCode HDIPreparedModelV1_0::Run(const std::vector& inputs, + const std::vector& outputs, std::vector>& outputsDims, + std::vector& isOutputBufferEnough) +{ + V1_0::IOTensor iTensor; + std::vector iInputTensors; + for (const auto& input: inputs) { + auto returnCode = TransIOTensor(input, iTensor); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("Run failed, failed to transform to ioTensor."); + return OH_NN_FAILED; + } + if (iTensor.data.fd == INVALID_FD) { + LOGE("Transform inputs tensor failed, cannot find data file descriptor."); + return OH_NN_INVALID_PARAMETER; + } + iInputTensors.emplace_back(iTensor); + } + + std::vector iOutputTensors; + for (const auto& output: outputs) { + auto returnCode = TransIOTensor(output, iTensor); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("Run failed, failed to transform to ioTensor."); + return OH_NN_FAILED; + } + if (iTensor.data.fd == INVALID_FD) { + LOGE("Transform outputs tensor failed, cannot find data file descriptor."); + return OH_NN_INVALID_PARAMETER; + } + iOutputTensors.emplace_back(iTensor); + } + + auto ret = m_hdiPreparedModel->Run(iInputTensors, iOutputTensors, outputsDims, isOutputBufferEnough); + if (ret != HDF_SUCCESS || outputsDims.empty()) { + LOGE("Run model failed. ErrorCode=%d", ret); + return OH_NN_UNAVALIDABLE_DEVICE; + } + + return OH_NN_SUCCESS; +} } // namespace NeuralNetworkRuntime } // OHOS \ No newline at end of file diff --git a/frameworks/native/hdi_prepared_model_v1_0.h b/frameworks/native/compat/hdi_prepared_model_v1_0.h similarity index 85% rename from frameworks/native/hdi_prepared_model_v1_0.h rename to frameworks/native/compat/hdi_prepared_model_v1_0.h index b98a7ecfb739ba9cc15d8cf428806e71545f4512..7f90459a2e823aeebd55eec0b2ea8444007fe1fd 100644 --- a/frameworks/native/hdi_prepared_model_v1_0.h +++ b/frameworks/native/compat/hdi_prepared_model_v1_0.h @@ -41,6 +41,11 @@ public: std::vector>& outputsDims, std::vector& isOutputBufferEnough) override; + OH_NN_ReturnCode Run(const std::vector& inputs, + const std::vector& outputs, + std::vector>& outputsDims, + std::vector& isOutputBufferEnough) override; + private: // first: major version, second: minor version std::pair m_hdiVersion; diff --git a/frameworks/native/hdi_prepared_model_v2_0.cpp b/frameworks/native/compat/hdi_prepared_model_v2_0.cpp similarity index 53% rename from frameworks/native/hdi_prepared_model_v2_0.cpp rename to frameworks/native/compat/hdi_prepared_model_v2_0.cpp index 9b0f0a45a3fb87b439ce752829069635a98381f8..9f2126b8af23e214d381dff0f5b9c3a9c9eb6b70 100644 --- a/frameworks/native/hdi_prepared_model_v2_0.cpp +++ b/frameworks/native/compat/hdi_prepared_model_v2_0.cpp @@ -18,6 +18,7 @@ #include "common/log.h" #include "hdi_returncode_utils.h" #include "memory_manager.h" +#include "nntensor.h" namespace OHOS { namespace NeuralNetworkRuntime { @@ -66,6 +67,50 @@ V2_0::Format TransFormat(const OH_NN_Format& format) } } +V2_0::DataType TransDataType(const OH_NNCore_DataType& dataType) +{ + switch (dataType) { + case OH_NNCORE_BOOL: + return V2_0::DataType::DATA_TYPE_BOOL; + case OH_NNCORE_INT8: + return V2_0::DataType::DATA_TYPE_INT8; + case OH_NNCORE_INT16: + return V2_0::DataType::DATA_TYPE_INT16; + case OH_NNCORE_INT32: + return V2_0::DataType::DATA_TYPE_INT32; + case OH_NNCORE_INT64: + return V2_0::DataType::DATA_TYPE_INT64; + case OH_NNCORE_UINT8: + return V2_0::DataType::DATA_TYPE_UINT8; + case OH_NNCORE_UINT16: + return V2_0::DataType::DATA_TYPE_UINT16; + case OH_NNCORE_UINT32: + return V2_0::DataType::DATA_TYPE_UINT32; + case OH_NNCORE_UINT64: + return V2_0::DataType::DATA_TYPE_UINT64; + case OH_NNCORE_FLOAT16: + return V2_0::DataType::DATA_TYPE_FLOAT16; + case OH_NNCORE_FLOAT32: + return V2_0::DataType::DATA_TYPE_FLOAT32; + case OH_NNCORE_FLOAT64: + return V2_0::DataType::DATA_TYPE_FLOAT64; + default: + return V2_0::DataType::DATA_TYPE_UNKNOWN; + } +} + +V2_0::Format TransFormat(const OH_NNCore_Format& format) +{ + switch (format) { + case OH_NNCORE_FORMAT_NCHW: + return V2_0::Format::FORMAT_NCHW; + case OH_NNCORE_FORMAT_NHWC: + return V2_0::Format::FORMAT_NHWC; + default: + return V2_0::Format::FORMAT_NONE; + } +} + V2_0::IOTensor TransIOTensor(const IOTensor& tensor) { V2_0::IOTensor iTensor; @@ -92,6 +137,74 @@ V2_0::IOTensor TransIOTensor(const IOTensor& tensor) return iTensor; } + + + +OH_NNCore_ReturnCode TransIOTensor(const OH_NNCore_Tensor* tensor, V2_0::IOTensor& ioTensor) +{ + if (tensor == nullptr) { + LOGE("TransIOTensor failed, failed to transform to V2_0 IOTensor."); + return OH_NNCORE_NULL_PTR; + } + + const OHOS::NeuralNetworkBackend::NNTensor* nnTensor = + reinterpret_cast(tensor); + OHOS::NeuralNetworkCore::TensorDesc* nnTensorDesc = nnTensor->GetTensorDesc(); + if (nnTensorDesc == nullptr) { + LOGE("TransIOTensor failed, failed to get desc from tensor."); + return OH_NNCORE_NULL_PTR; + } + + // convert name + const char* tensorName = nullptr; + OH_NNCore_ReturnCode ret = nnTensorDesc->GetName(&tensorName); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("TransIOTensor failed, failed to get name from desc."); + return ret; + } + ioTensor.name = tensorName; + + // convert data type + OH_NNCore_DataType dataType; + ret = nnTensorDesc->GetDataType(&dataType); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("TransIOTensor failed, failed to get data type from desc."); + return ret; + } + ioTensor.dataType = TransDataType(dataType); + + // convert format + OH_NNCore_Format format; + ret = nnTensorDesc->GetFormat(&format); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("TransIOTensor failed, failed to get format from desc."); + return ret; + } + ioTensor.format = TransFormat(format); + + // convert shape + int32_t* shape = nullptr; + size_t shapeNum = 0; + ret = nnTensorDesc->GetShape(&shape, &shapeNum); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("TransIOTensor failed, failed to get shape from desc."); + return ret; + } + ioTensor.dimensions.clear(); + for (size_t i = 0; i < shapeNum; ++i) { + ioTensor.dimensions.emplace_back(shape[i]); + } + + // convert data + if (!nnTensor->CheckTensorData()) { + LOGE("TransIOTensor failed, failed to check tensor data."); + return OH_NNCORE_INVALID_PARAMETER; + } + V2_0::SharedBuffer iBuffer {nnTensor->GetFd(), nnTensor->GetSize(), nnTensor->GetOffset(), nnTensor->GetSize()}; + ioTensor.data = iBuffer; + + return OH_NNCORE_SUCCESS; +} } // unamed namespace HDIPreparedModelV2_0::HDIPreparedModelV2_0(OHOS::sptr hdiPreparedModel) @@ -164,6 +277,51 @@ OH_NN_ReturnCode HDIPreparedModelV2_0::Run(const std::vector& inputs, return OH_NN_SUCCESS; } +OH_NN_ReturnCode HDIPreparedModelV2_0::Run(const std::vector& inputs, + const std::vector& outputs, std::vector>& outputsDims, + std::vector& isOutputBufferEnough) +{ + V2_0::IOTensor iTensor; + std::vector iInputTensors; + for (const auto& input: inputs) { + auto returnCode = TransIOTensor(input, iTensor); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("Run failed, failed to transform to ioTensor."); + return OH_NN_FAILED; + } + if (iTensor.data.fd == INVALID_FD) { + LOGE("Transform inputs tensor failed, cannot find data file descriptor."); + return OH_NN_INVALID_PARAMETER; + } + iInputTensors.emplace_back(iTensor); + } + + std::vector iOutputTensors; + for (const auto& output: outputs) { + auto returnCode = TransIOTensor(output, iTensor); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("Run failed, failed to transform to ioTensor."); + return OH_NN_FAILED; + } + if (iTensor.data.fd == INVALID_FD) { + LOGE("Transform outputs tensor failed, cannot find data file descriptor."); + return OH_NN_INVALID_PARAMETER; + } + iOutputTensors.emplace_back(iTensor); + } + + auto ret = m_hdiPreparedModel->Run(iInputTensors, iOutputTensors, outputsDims); + if (ret != V2_0::NNRT_ReturnCode::NNRT_SUCCESS) { + return CheckReturnCode(ret, OH_NN_UNAVALIDABLE_DEVICE, "Run model failed"); + } + if (outputsDims.empty()) { + LOGE("Run failed, outputsDims is empty."); + return OH_NN_UNAVALIDABLE_DEVICE; + } + + return OH_NN_SUCCESS; +} + OH_NN_ReturnCode HDIPreparedModelV2_0::GetInputDimRanges(std::vector>& minInputDims, std::vector>& maxInputDims) { diff --git a/frameworks/native/hdi_prepared_model_v2_0.h b/frameworks/native/compat/hdi_prepared_model_v2_0.h similarity index 87% rename from frameworks/native/hdi_prepared_model_v2_0.h rename to frameworks/native/compat/hdi_prepared_model_v2_0.h index 9648eae722a1dfdab99981f8c0508e3cbc85708e..fdedb7e70c1b7879bd488ac34fddd88da502e9dd 100644 --- a/frameworks/native/hdi_prepared_model_v2_0.h +++ b/frameworks/native/compat/hdi_prepared_model_v2_0.h @@ -42,6 +42,11 @@ public: std::vector>& outputsDims, std::vector& isOutputBufferEnough) override; + OH_NN_ReturnCode Run(const std::vector& inputs, + const std::vector& outputs, + std::vector>& outputsDims, + std::vector& isOutputBufferEnough) override; + OH_NN_ReturnCode GetInputDimRanges(std::vector>& minInputDims, std::vector>& maxInputDims) override; diff --git a/frameworks/native/hdi_returncode_utils.h b/frameworks/native/compat/hdi_returncode_utils.h similarity index 96% rename from frameworks/native/hdi_returncode_utils.h rename to frameworks/native/compat/hdi_returncode_utils.h index 7d82e967b094719f06e0f0b1670672f7c5ce825a..1e392be675d466257cf97235d052f9ae86bf9c02 100644 --- a/frameworks/native/hdi_returncode_utils.h +++ b/frameworks/native/compat/hdi_returncode_utils.h @@ -73,9 +73,9 @@ inline std::string ConverterRetToString(OHOS::HDI::Nnrt::V2_0::NNRT_ReturnCode r template T CheckReturnCode(int32_t ret, T funcRet, const std::string& errorInfo) { - if (ret < V2_0::NNRT_ReturnCode::NNRT_SUCCESS) { + if (ret < static_cast(V2_0::NNRT_ReturnCode::NNRT_SUCCESS)) { LOGE("%{public}s. An error occurred in HDI, errorcode is %{public}d.", errorInfo.c_str(), ret); - } else if (ret > V2_0::NNRT_ReturnCode::NNRT_SUCCESS) { + } else if (ret > static_cast(V2_0::NNRT_ReturnCode::NNRT_SUCCESS)) { OHOS::HDI::Nnrt::V2_0::NNRT_ReturnCode nnrtRet = static_cast(ret); LOGE("%{public}s. Errorcode is %{public}s.", errorInfo.c_str(), ConverterRetToString(nnrtRet).c_str()); } diff --git a/frameworks/native/inner_model.cpp b/frameworks/native/compat/inner_model.cpp similarity index 69% rename from frameworks/native/inner_model.cpp rename to frameworks/native/compat/inner_model.cpp index a09643ea374087e4378b1e05b2d5b49cfbabcc68..0f57cddb460c34b3f9c9962648a1cf7e0a234e3e 100644 --- a/frameworks/native/inner_model.cpp +++ b/frameworks/native/compat/inner_model.cpp @@ -21,13 +21,16 @@ #include "securec.h" -#include "common/utils.h" #include "common/scoped_trace.h" +#include "common/utils.h" #include "device_manager.h" -#include "validation.h" #include "ops_builder.h" #include "ops_registry.h" #include "transform.h" +#include "validation.h" +#include "../nnbackend.h" +#include "../backend_manager.h" +#include "../transform.h" namespace MSLITE = mindspore::lite; @@ -39,10 +42,7 @@ const std::string LOADED_NNR_MODEL = "Loaded_NNR_Model"; namespace { class LiteGraphDeleter { public: - void operator()(MSLITE::LiteGraph* liteGraph) const - { - MindIR_LiteGraph_Destroy(&liteGraph); - } + void operator()(MSLITE::LiteGraph* liteGraph) const { MindIR_LiteGraph_Destroy(&liteGraph); } }; std::shared_ptr ConstructNNTensorFromLiteGraphTensor(const MSLITE::TensorPtr msTensor) @@ -56,13 +56,15 @@ std::shared_ptr ConstructNNTensorFromLiteGraphTensor(const MSLITE::Ten std::shared_ptr nnTensor = CreateSharedPtr(); if (nnTensor == nullptr) { - LOGE("ConstructNNTensorFromLiteGraphTensor failed, error happened when creating NNTensor."); + LOGE("ConstructNNTensorFromLiteGraphTensor failed, error happened when " + "creating NNTensor."); return nullptr; } OH_NN_ReturnCode ret = nnTensor->Build(dataType, msDims, nnQuantParams, OH_NN_TENSOR); if (ret != OH_NN_SUCCESS) { - LOGE("ConstructNNTensorFromLiteGraphTensor failed, error happened when building NNTensor with attributes."); + LOGE("ConstructNNTensorFromLiteGraphTensor failed, error happened when " + "building NNTensor with attributes."); return nullptr; } @@ -76,13 +78,15 @@ OH_NN_ReturnCode ConstructNNTensorsFromLiteGraph(const MSLITE::LiteGraph* liteGr std::vector>& nnTensors) { if (indices.empty()) { - LOGE("ConstructNNTensorsFromLiteGraph failed, passed empty indices list."); + LOGE("ConstructNNTensorsFromLiteGraph failed, passed empty indices " + "list."); return OH_NN_INVALID_PARAMETER; } uint32_t maximumIndex = *(std::max_element(indices.begin(), indices.end())); if (maximumIndex >= liteGraph->all_tensors_.size()) { - LOGE("ConstructNNTensorsFromLiteGraph failed, index exceed size of all_tensors inside liteGraph."); + LOGE("ConstructNNTensorsFromLiteGraph failed, index exceed size of " + "all_tensors inside liteGraph."); return OH_NN_INVALID_PARAMETER; } @@ -90,7 +94,8 @@ OH_NN_ReturnCode ConstructNNTensorsFromLiteGraph(const MSLITE::LiteGraph* liteGr for (uint32_t i : indices) { nnTensor = ConstructNNTensorFromLiteGraphTensor(liteGraph->all_tensors_[i]); if (nnTensor == nullptr) { - LOGE("ConstructNNTensorsFromLiteGraph failed, failed to construct NNTensor from LiteGraphTensor."); + LOGE("ConstructNNTensorsFromLiteGraph failed, failed to construct " + "NNTensor from LiteGraphTensor."); return OH_NN_NULL_PTR; } @@ -101,7 +106,7 @@ OH_NN_ReturnCode ConstructNNTensorsFromLiteGraph(const MSLITE::LiteGraph* liteGr } } // anonymous namespace -InnerModel::InnerModel() {} +InnerModel::InnerModel() { } bool InnerModel::IsBuild() const { @@ -146,8 +151,9 @@ OH_NN_ReturnCode InnerModel::BuildFromLiteGraph(const MSLITE::LiteGraph* liteGra return OH_NN_SUCCESS; } -OH_NN_ReturnCode InnerModel::BuildFromMetaGraph( - const void* metaGraph, const Buffer& quantBuffer, const std::string& modelName) +OH_NN_ReturnCode InnerModel::BuildFromMetaGraph(const void* metaGraph, + const Buffer& quantBuffer, + const std::string& modelName) { NNRT_TRACE_NAME("Build model from meta graph"); if (metaGraph == nullptr) { @@ -198,7 +204,131 @@ OH_NN_ReturnCode InnerModel::AddTensor(const OH_NN_Tensor& nnTensor) return OH_NN_SUCCESS; } -// DOTO: 圈复杂度待优化 +OH_NNCore_ReturnCode InnerModel::AddTensorDesc(const OH_NNCore_TensorDesc* tensorDesc) +{ + if (tensorDesc == nullptr) { + LOGE("AddTensorDesc failed, passed nullptr to tensorDesc."); + return OH_NNCORE_INVALID_PARAMETER; + } + + std::shared_ptr tensor = CreateSharedPtr(); + if (tensor == nullptr) { + LOGE("AddTensorDesc failed, error happened when creating NNTensor."); + return OH_NNCORE_MEMORY_EXCEPTION; + } + + OH_NNCore_ReturnCode returnCode = tensor->BuildFromTensorDesc(tensorDesc); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("AddTensorDesc failed, error happened when build NNTensor from OH_NNCore_TensorDesc."); + return returnCode; + } + + // The NNTensor is named as "Tensor: "". + tensor->SetName("Tensor: " + std::to_string(m_allTensors.size())); + m_allTensors.emplace_back(tensor); + + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode InnerModel::SetTensorQuantParam(uint32_t index, const OH_NNBackend_QuantParam* quantParam) +{ + if (IsBuild()) { + LOGE("SetTensorQuantParam failed, SetTensorValue is forbidden after model has been built."); + return OH_NNCORE_OPERATION_FORBIDDEN; + } + + if (index >= m_allTensors.size()) { + LOGE("SetTensorQuantParam failed, passed index %u out of the number of added tensors.", index); + return OH_NNCORE_INVALID_PARAMETER; + } + + std::shared_ptr tensor = m_allTensors[index]; + // quantParam is validated in outer function, no need to check it here. + OH_NNCore_ReturnCode returnCode = tensor->SetQuantParam(quantParam); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("SetTensorQuantParam failed, error happened when set quant param."); + } + + return returnCode; +} + +OH_NNCore_ReturnCode InnerModel::SetTensorType(uint32_t index, OH_NNBackend_TensorType tensorType) +{ + if (IsBuild()) { + LOGE("SetTensorType failed, SetTensorType is forbidden after model has been built."); + return OH_NNCORE_OPERATION_FORBIDDEN; + } + + if (index >= m_allTensors.size()) { + LOGE("SetTensorType failed, passed index %u out of the number of added tensors.", index); + return OH_NNCORE_INVALID_PARAMETER; + } + + std::shared_ptr tensor = m_allTensors[index]; + OH_NNCore_ReturnCode returnCode = tensor->SetTensorType(tensorType); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("SetTensorType failed, error happened when setting tensor type."); + } + + return returnCode; +} + +OH_NNCore_ReturnCode InnerModel::AddOperation(OH_NNBackend_OperationType opType, + const OH_NNBackend_Array& paramIndices, + const OH_NNBackend_Array& inputIndices, + const OH_NNBackend_Array& outputIndices) +{ + if (paramIndices.datatype != OH_NNCORE_UINT32) { + LOGE("AddOperation failed, paramIndices datatype should be OH_NNCORE_UINT32."); + return OH_NNCORE_INVALID_PARAMETER; + } + + if (inputIndices.datatype != OH_NNCORE_UINT32) { + LOGE("AddOperation failed, inputIndices datatype should be OH_NNCORE_UINT32."); + return OH_NNCORE_INVALID_PARAMETER; + } + + if (outputIndices.datatype != OH_NNCORE_UINT32) { + LOGE("AddOperation failed, outputIndices datatype should be OH_NNCORE_UINT32."); + return OH_NNCORE_INVALID_PARAMETER; + } + + OH_NN_UInt32Array nnParamIndices = {static_cast(paramIndices.data), (paramIndices.length / 4)}; + OH_NN_UInt32Array nnInputIndices = {static_cast(inputIndices.data), (inputIndices.length / 4)}; + OH_NN_UInt32Array nnOutputIndices = {static_cast(outputIndices.data), (outputIndices.length / 4)}; + + OH_NN_ReturnCode ret = AddOperation((OH_NN_OperationType)(opType), nnParamIndices, nnInputIndices, nnOutputIndices); + if (ret != OH_NN_SUCCESS) { + LOGE("AddOperation failed, error happened when adding operation."); + } + + return OHOS::NeuralNetworkBackend::BackendToCore::ConvertReturnCode(ret); +} + +OH_NNCore_ReturnCode InnerModel::SpecifyInputsAndOutputs(const OH_NNBackend_Array& inputIndices, + const OH_NNBackend_Array& outputIndices) +{ + if (inputIndices.datatype != OH_NNCORE_UINT32) { + LOGE("SpecifyInputsAndOutputs failed, inputIndices datatype should be OH_NNCORE_UINT32."); + return OH_NNCORE_INVALID_PARAMETER; + } + + if (outputIndices.datatype != OH_NNCORE_UINT32) { + LOGE("SpecifyInputsAndOutputs failed, outputIndices datatype should be OH_NNCORE_UINT32."); + return OH_NNCORE_INVALID_PARAMETER; + } + + OH_NN_UInt32Array nnInputIndices = {static_cast(inputIndices.data), (inputIndices.length / 4)}; + OH_NN_UInt32Array nnOutputIndices = {static_cast(outputIndices.data), (outputIndices.length / 4)}; + + OH_NN_ReturnCode ret = SpecifyInputsAndOutputs(nnInputIndices, nnOutputIndices); + if (ret != OH_NN_SUCCESS) { + LOGE("SpecifyInputsAndOutputs failed, error happened when specifying inputs and outputs."); + } + + return OHOS::NeuralNetworkBackend::BackendToCore::ConvertReturnCode(ret); +} + OH_NN_ReturnCode InnerModel::SetTensorValue(uint32_t index, const void* buffer, size_t length) { if (IsBuild()) { @@ -229,11 +359,13 @@ OH_NN_ReturnCode InnerModel::SetTensorValue(uint32_t index, const void* buffer, if (length != tensor->GetDataLength()) { LOGE("SetTensorValue failed, get buffer length %zu different from the byte size of tensor %zu.", - length, tensor->GetDataLength()); + length, + tensor->GetDataLength()); return OH_NN_INVALID_PARAMETER; } - // Data will be released inside NNTensor if it is set inside NNTensor using SetBuffer(). + // Data will be released inside NNTensor if it is set inside NNTensor using + // SetBuffer(). void* data = new (std::nothrow) char[length]; if (data == nullptr) { LOGE("SetTensorValue failed, please check whether it runs out of memory."); @@ -243,7 +375,7 @@ OH_NN_ReturnCode InnerModel::SetTensorValue(uint32_t index, const void* buffer, errno_t ret = memcpy_s(data, length, buffer, length); if (ret != EOK) { LOGE("SetTensorValue failed, please the information of error number %d from memcpy_s.", ret); - delete [] reinterpret_cast(data); + delete[] reinterpret_cast(data); return OH_NN_FAILED; } @@ -251,8 +383,8 @@ OH_NN_ReturnCode InnerModel::SetTensorValue(uint32_t index, const void* buffer, return OH_NN_SUCCESS; } -OH_NN_ReturnCode InnerModel::ValidateInputAndOutput( - const OH_NN_UInt32Array& inputIndices, const OH_NN_UInt32Array& outputIndices) const +OH_NN_ReturnCode InnerModel::ValidateInputAndOutput(const OH_NN_UInt32Array& inputIndices, + const OH_NN_UInt32Array& outputIndices) const { OH_NN_ReturnCode ret = ValidateTensorArray(inputIndices); if (ret != OH_NN_SUCCESS) { @@ -281,7 +413,9 @@ OH_NN_ReturnCode InnerModel::ValidateInputAndOutput( tensor = m_allTensors[inputIndices.data[i]]; if (tensor->GetType() != OH_NN_TENSOR) { LOGE("ValidateInputAndOutput failed, tensor set as input should has type of OH_NN_TENSOR, but receive %d." - "Tensor index: %u.", tensor->GetType(), i); + "Tensor index: %u.", + tensor->GetType(), + i); return OH_NN_INVALID_PARAMETER; } } @@ -290,17 +424,22 @@ OH_NN_ReturnCode InnerModel::ValidateInputAndOutput( tensor = m_allTensors[outputIndices.data[i]]; if (tensor->GetType() != OH_NN_TENSOR) { LOGE("ValidateInputAndOutput failed, tensor set as output should has type of OH_NN_TENSOR, but receive %d." - "Tensor index: %u.", tensor->GetType(), i); + "Tensor index: %u.", + tensor->GetType(), + i); return OH_NN_INVALID_PARAMETER; } } - // The number of inputIndices and outputIndices are usually small, so O(n**2) iteration is fine. + // The number of inputIndices and outputIndices are usually small, so + // O(n**2) iteration is fine. for (uint32_t i = 0; i < inputIndices.size; i++) { for (uint32_t j = 0; j < outputIndices.size; j++) { if (inputIndices.data[i] == outputIndices.data[j]) { LOGE("ValidateInputAndOutput failed, should not set an tensor as input and output at the same time, " - "input index %u, output index %u", inputIndices.data[i], outputIndices.data[j]); + "input index %u, output index %u", + inputIndices.data[i], + outputIndices.data[j]); return OH_NN_INVALID_PARAMETER; } } @@ -328,8 +467,10 @@ OH_NN_ReturnCode InnerModel::ValidateTensorArray(const OH_NN_UInt32Array& indice return OH_NN_SUCCESS; } -OH_NN_ReturnCode InnerModel::AddOperation(OH_NN_OperationType opType, const OH_NN_UInt32Array& paramIndices, - const OH_NN_UInt32Array& inputIndices, const OH_NN_UInt32Array& outputIndices) +OH_NN_ReturnCode InnerModel::AddOperation(OH_NN_OperationType opType, + const OH_NN_UInt32Array& paramIndices, + const OH_NN_UInt32Array& inputIndices, + const OH_NN_UInt32Array& outputIndices) { if (IsBuild()) { LOGE("AddOperation failed, AddOperation is forbidden after model has been built."); @@ -368,8 +509,8 @@ OH_NN_ReturnCode InnerModel::AddOperation(OH_NN_OperationType opType, const OH_N return OH_NN_SUCCESS; } -OH_NN_ReturnCode InnerModel::SpecifyInputsAndOutputs( - const OH_NN_UInt32Array& inputIndices, const OH_NN_UInt32Array& outputIndices) +OH_NN_ReturnCode InnerModel::SpecifyInputsAndOutputs(const OH_NN_UInt32Array& inputIndices, + const OH_NN_UInt32Array& outputIndices) { if (IsBuild()) { LOGE("SpecifyInputsAndOutputs failed, SpecifyInputsAndOutputs is forbidden after model has been built."); @@ -431,8 +572,10 @@ OH_NN_ReturnCode InnerModel::CheckParameters() const return OH_NN_SUCCESS; } -OH_NN_ReturnCode InnerModel::SetInputsAndOutputsInfo(const OH_NN_TensorInfo* inputsInfo, size_t inputSize, - const OH_NN_TensorInfo* outputsInfo, size_t outputSize) +OH_NN_ReturnCode InnerModel::SetInputsAndOutputsInfo(const OH_NN_TensorInfo* inputsInfo, + size_t inputSize, + const OH_NN_TensorInfo* outputsInfo, + size_t outputSize) { OH_NN_ReturnCode ret = CheckParameters(); if (ret != OH_NN_SUCCESS) { @@ -483,8 +626,10 @@ OH_NN_ReturnCode InnerModel::Build() { NNRT_TRACE_NAME("Build model"); if (IsBuild()) { - LOGE("Build failed, OH_NNModel_Finish() shouldn't be called after OH_NNModel_Finish() or " - "OH_NNModel_BuildFromMetaGraph() or OH_NNModel_BuildFromLiteGraph()."); + LOGE("Build failed, OH_NNModel_Finish() shouldn't be called after " + "OH_NNModel_Finish() or " + "OH_NNModel_BuildFromMetaGraph() or " + "OH_NNModel_BuildFromLiteGraph()."); return OH_NN_OPERATION_FORBIDDEN; } @@ -520,7 +665,8 @@ OH_NN_ReturnCode InnerModel::Build() return ret; } - // subGraph will be released by LiteGraph if it is added into instance of LiteGraph. + // subGraph will be released by LiteGraph if it is added into instance of + // LiteGraph. MSLITE::LiteGraph::SubGraph* subGraph = new (std::nothrow) MSLITE::LiteGraph::SubGraph(); if (subGraph == nullptr) { LOGE("AddNodesToLiteGraph failed, error happened when creating subgraph."); @@ -546,7 +692,8 @@ void InnerModel::AddTensorsToLiteGraph(std::unordered_map& m size_t tensorCount = m_allTensors.size(); for (size_t i = 0; i < tensorCount; i++) { const std::shared_ptr& nnTensor = m_allTensors[i]; - // If the tensor is used as operation parameter, it will not convert to the tensor of LiteGraph. + // If the tensor is used as operation parameter, it will not convert to + // the tensor of LiteGraph. if (nnTensor->IsOpParameter()) { continue; } @@ -556,8 +703,8 @@ void InnerModel::AddTensorsToLiteGraph(std::unordered_map& m modelIDToGraphID[i] = graphID++; } - // Note: Indices in m_inputIndices and m_outputIndices have been checked in SpecifyInputAndOutput(), there is no - // need to check twice. + // 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)); @@ -576,8 +723,9 @@ OH_NN_ReturnCode InnerModel::AddNodesToLiteGraph(const std::unordered_map& op = m_ops[i]; - // node will be released by LiteGraph if it is added into instance of LiteGraph. - node = new(std::nothrow) MSLITE::LiteGraph::Node(); + // node will be released by LiteGraph if it is added into instance of + // LiteGraph. + node = new (std::nothrow) MSLITE::LiteGraph::Node(); if (node == nullptr) { LOGE("AddNodesToLiteGraph failed, error happened when creating LiteGraph tensor."); return OH_NN_NULL_PTR; @@ -634,6 +782,48 @@ OH_NN_ReturnCode InnerModel::GetSupportedOperations(size_t deviceID, const bool* return OH_NN_SUCCESS; } +OH_NNCore_ReturnCode InnerModel::GetSupportedOperations(const std::string& backendName, + const bool** isSupported, + uint32_t& opCount) +{ + if (m_liteGraph == nullptr) { + LOGE("GetSupportedOperations failed. GetSupportedOperations() must be called after Finish()."); + return OH_NNCORE_OPERATION_FORBIDDEN; + } + + OHOS::NeuralNetworkCore::BackendManager& backendManager = OHOS::NeuralNetworkCore::BackendManager::GetInstance(); + std::shared_ptr backend = backendManager.GetBackend(backendName); + if (backend == nullptr) { + LOGE("InnerModel::GetSupportedOperations failed, backend with backendName %s is not exist.", + backendName.c_str()); + return OH_NNCORE_INVALID_PARAMETER; + } + + std::shared_ptr nnBackend = + std::dynamic_pointer_cast(backend); + std::shared_ptr device = nnBackend->GetDevice(); + if (device == nullptr) { + LOGE("InnerModel::GetSupportedOperations failed, device with backendName %s is not exist.", + backendName.c_str()); + return OH_NNCORE_FAILED; + } + + std::vector supportedOperations; + OH_NN_ReturnCode ret = device->GetSupportedOperation(m_liteGraph, supportedOperations); + if (ret != OH_NN_SUCCESS) { + LOGE("GetSupportedOperations failed, error happened when get supported operations from devices."); + return OHOS::NeuralNetworkBackend::BackendToCore::ConvertReturnCode(ret); + } + + m_supportedOperations.clear(); + std::copy(supportedOperations.begin(), supportedOperations.end(), std::back_inserter(m_supportedOperations)); + + *isSupported = reinterpret_cast(m_supportedOperations.data()); + opCount = m_supportedOperations.size(); + + return OH_NNCORE_SUCCESS; +} + std::shared_ptr InnerModel::GetLiteGraphs() const { return m_liteGraph; @@ -663,5 +853,5 @@ std::string InnerModel::GetModelName() const { return m_modelName; } -} // namespace NeuralNetworkRuntime -} // namespace OHOS \ No newline at end of file +} // namespace NeuralNetworkRuntime +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/inner_model.h b/frameworks/native/compat/inner_model.h similarity index 59% rename from frameworks/native/inner_model.h rename to frameworks/native/compat/inner_model.h index 7deec70d8d8d062d84186065edd623386ff1799f..28a074c1ada4837fc99cd49d90f70adb79abc889 100644 --- a/frameworks/native/inner_model.h +++ b/frameworks/native/compat/inner_model.h @@ -22,7 +22,7 @@ #include "mindir.h" #include "ops_builder.h" #include "interfaces/innerkits/c/neural_network_runtime_inner.h" -#include "interfaces/kits/c/neural_network_runtime.h" +#include "v1_0/neural_network_runtime_compat.h" namespace OHOS { namespace NeuralNetworkRuntime { @@ -31,9 +31,17 @@ public: InnerModel(); bool IsBuild() const; + + std::vector> GetInputTensors() const; + std::vector> GetOutputTensors() const; + std::shared_ptr GetLiteGraphs() const; + void* GetMetaGraph() const; + Buffer GetQuantBuffer() const; + std::string GetModelName() const; + + // The public functions below will be deprecated after API14. OH_NN_ReturnCode BuildFromLiteGraph(const mindspore::lite::LiteGraph* liteGraph); - OH_NN_ReturnCode BuildFromMetaGraph(const void* metaGraph, const Buffer& quantBuffer, - const std::string& modelName); + OH_NN_ReturnCode BuildFromMetaGraph(const void* metaGraph, const Buffer& quantBuffer, const std::string& modelName); OH_NN_ReturnCode AddTensor(const OH_NN_Tensor& nnTensor); OH_NN_ReturnCode SetTensorValue(uint32_t index, const void* buffer, size_t length); OH_NN_ReturnCode AddOperation(OH_NN_OperationType opType, @@ -41,23 +49,33 @@ public: const OH_NN_UInt32Array& inputIndices, const OH_NN_UInt32Array& outputIndices); OH_NN_ReturnCode GetSupportedOperations(size_t deviceID, const bool** isSupported, uint32_t& opCount); - OH_NN_ReturnCode SpecifyInputsAndOutputs( - const OH_NN_UInt32Array& inputIndices, const OH_NN_UInt32Array& outputIndices); - OH_NN_ReturnCode SetInputsAndOutputsInfo(const OH_NN_TensorInfo* inputsInfo, size_t inputSize, - const OH_NN_TensorInfo* outputsInfo, size_t outputSize); + OH_NNCore_ReturnCode GetSupportedOperations(const std::string& backendName, + const bool** isSupported, + uint32_t& opCount); + OH_NN_ReturnCode SpecifyInputsAndOutputs(const OH_NN_UInt32Array& inputIndices, + const OH_NN_UInt32Array& outputIndices); + OH_NN_ReturnCode SetInputsAndOutputsInfo(const OH_NN_TensorInfo* inputsInfo, + size_t inputSize, + const OH_NN_TensorInfo* outputsInfo, + size_t outputSize); OH_NN_ReturnCode Build(); - std::vector> GetInputTensors() const; - std::vector> GetOutputTensors() const; - std::shared_ptr GetLiteGraphs() const; - void* GetMetaGraph() const; - Buffer GetQuantBuffer() const; - std::string GetModelName() const; + + // For NNRt v2.0 + OH_NNCore_ReturnCode AddTensorDesc(const OH_NNCore_TensorDesc* tensorDesc); + OH_NNCore_ReturnCode SetTensorQuantParam(uint32_t index, const OH_NNBackend_QuantParam* quantParam); + OH_NNCore_ReturnCode SetTensorType(uint32_t index, OH_NNBackend_TensorType tensorType); + OH_NNCore_ReturnCode AddOperation(OH_NNBackend_OperationType opType, + const OH_NNBackend_Array& paramIndices, + const OH_NNBackend_Array& inputIndices, + const OH_NNBackend_Array& outputIndices); + OH_NNCore_ReturnCode SpecifyInputsAndOutputs(const OH_NNBackend_Array& inputIndices, + const OH_NNBackend_Array& outputIndices); private: void AddTensorsToLiteGraph(std::unordered_map& modelIDToGraphID); OH_NN_ReturnCode AddNodesToLiteGraph(const std::unordered_map& modelIDToGraphID); - OH_NN_ReturnCode ValidateInputAndOutput( - const OH_NN_UInt32Array& inputIndices, const OH_NN_UInt32Array& outputIndices) const; + OH_NN_ReturnCode ValidateInputAndOutput(const OH_NN_UInt32Array& inputIndices, + const OH_NN_UInt32Array& outputIndices) const; OH_NN_ReturnCode ValidateTensorArray(const OH_NN_UInt32Array& indices) const; OH_NN_ReturnCode CheckParameters() const; @@ -67,13 +85,13 @@ private: std::vector m_outputIndices; std::vector> m_ops; std::vector> m_allTensors; - std::vector> m_inputTensors; // Used to pass input tensors to compilation. + std::vector> m_inputTensors; // Used to pass input tensors to compilation. std::vector> m_outputTensors; // Used to pass output tensors to compilation. - std::shared_ptr m_liteGraph {nullptr}; - void* m_metaGraph {nullptr}; + std::shared_ptr m_liteGraph{nullptr}; + void* m_metaGraph{nullptr}; Buffer m_quantBuffer = {nullptr, 0}; std::string m_modelName; }; -} // namespace NeuralNetworkRuntime -} // namespace OHOS +} // namespace NeuralNetworkRuntime +} // namespace OHOS #endif // NEURAL_NETWORK_RUNTIME_INNER_MODEL_H diff --git a/frameworks/native/memory_manager.cpp b/frameworks/native/compat/memory_manager.cpp similarity index 100% rename from frameworks/native/memory_manager.cpp rename to frameworks/native/compat/memory_manager.cpp diff --git a/frameworks/native/memory_manager.h b/frameworks/native/compat/memory_manager.h similarity index 96% rename from frameworks/native/memory_manager.h rename to frameworks/native/compat/memory_manager.h index 5518deb97dd870a3fa6cc66ea4fd9649b7837727..6107f1b730d59b1b5c04bbed6077031e941e17fe 100644 --- a/frameworks/native/memory_manager.h +++ b/frameworks/native/compat/memory_manager.h @@ -19,7 +19,7 @@ #include #include -#include "interfaces/kits/c/neural_network_runtime_type.h" +#include "v1_0/neural_network_runtime_type_compat.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/compat/neural_network_runtime_compat.cpp b/frameworks/native/compat/neural_network_runtime_compat.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2174fb36d517b4fb163cf846384ceeffbffb7714 --- /dev/null +++ b/frameworks/native/compat/neural_network_runtime_compat.cpp @@ -0,0 +1,732 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "v1_0/neural_network_runtime_compat.h" + +#include "compilation.h" +#include "device_manager.h" +#include "executor.h" +#include "inner_model.h" +#include "common/log.h" + + +using namespace OHOS::NeuralNetworkRuntime; + +#define NNRT_API __attribute__((visibility("default"))) + +NNRT_API OH_NNModel *OH_NNModel_Construct(void) +{ + InnerModel *innerModel = new(std::nothrow) InnerModel(); + if (innerModel == nullptr) { + LOGE("OH_NNModel_Construct failed, please check whether it has enough memory."); + return nullptr; + } + + OH_NNModel *nnModel = reinterpret_cast(innerModel); + return nnModel; +} + +NNRT_API OH_NN_ReturnCode OH_NNModel_AddTensor(OH_NNModel *model, const OH_NN_Tensor *tensor) +{ + if (model == nullptr) { + LOGE("OH_NNModel_AddTensor failed, passed nullptr to model."); + return OH_NN_INVALID_PARAMETER; + } + + if (tensor == nullptr) { + LOGE("OH_NNModel_AddTensor failed, passed nullptr to tensor."); + return OH_NN_INVALID_PARAMETER; + } + + InnerModel *innerModel = reinterpret_cast(model); + return innerModel->AddTensor(*tensor); +} + +NNRT_API 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) +{ + if (model == nullptr) { + LOGE("OH_NNModel_AddOperation failed, passed nullptr to model."); + return OH_NN_INVALID_PARAMETER; + } + + if (paramIndices == nullptr) { + LOGE("OH_NNModel_AddOperation failed, passed nullptr to paramIndices."); + return OH_NN_INVALID_PARAMETER; + } + + if (inputIndices == nullptr) { + LOGE("OH_NNModel_AddOperation failed, passed nullptr to inputIndices."); + return OH_NN_INVALID_PARAMETER; + } + + if (outputIndices == nullptr) { + LOGE("OH_NNModel_AddOperation failed, passed nullptr to outputIndices."); + return OH_NN_INVALID_PARAMETER; + } + + InnerModel *innerModel = reinterpret_cast(model); + return innerModel->AddOperation(op, *paramIndices, *inputIndices, *outputIndices); +} + +NNRT_API OH_NN_ReturnCode OH_NNModel_SetTensorData(OH_NNModel *model, + uint32_t index, + const void *dataBuffer, + size_t length) +{ + if (model == nullptr) { + LOGE("OH_NNModel_SetTensorData failed, passed nullptr to model."); + return OH_NN_INVALID_PARAMETER; + } + + if (dataBuffer == nullptr) { + LOGE("OH_NNModel_SetTensorData failed, passed nullptr to dataBuffer, which has no effect."); + return OH_NN_INVALID_PARAMETER; + } + + if (length == 0) { + LOGE("OH_NNModel_SetTensorData failed, passed dataBuffer with length 0, which has no effect."); + return OH_NN_INVALID_PARAMETER; + } + + InnerModel *innerModel = reinterpret_cast(model); + return innerModel->SetTensorValue(index, dataBuffer, length); +} + +NNRT_API OH_NN_ReturnCode OH_NNModel_SpecifyInputsAndOutputs(OH_NNModel *model, + const OH_NN_UInt32Array *inputIndices, + const OH_NN_UInt32Array *outputIndices) +{ + if (model == nullptr) { + LOGE("OH_NNModel_SpecifyInputsAndOutputs failed, passed nullptr to model."); + return OH_NN_INVALID_PARAMETER; + } + + if (inputIndices == nullptr) { + LOGE("OH_NNModel_SpecifyInputsAndOutputs failed, passed nullptr to inputIndices."); + return OH_NN_INVALID_PARAMETER; + } + + if (outputIndices == nullptr) { + LOGE("OH_NNModel_SpecifyInputsAndOutputs failed, passed nullptr to outputIndices."); + return OH_NN_INVALID_PARAMETER; + } + + InnerModel *innerModel = reinterpret_cast(model); + return innerModel->SpecifyInputsAndOutputs(*inputIndices, *outputIndices); +} + +NNRT_API OH_NN_ReturnCode OH_NNModel_Finish(OH_NNModel *model) +{ + if (model == nullptr) { + LOGE("OH_NNModel_Finish failed, passed nullptr to model."); + return OH_NN_INVALID_PARAMETER; + } + + InnerModel *innerModel = reinterpret_cast(model); + return innerModel->Build(); +} + +NNRT_API OH_NN_ReturnCode OH_NNModel_BuildFromLiteGraph(OH_NNModel *model, const void *liteGraph) +{ + if (model == nullptr) { + LOGE("OH_NNModel_BuildFromLiteGraph failed, passed nullptr to model."); + return OH_NN_INVALID_PARAMETER; + } + + if (liteGraph == nullptr) { + LOGE("OH_NNModel_BuildFromLiteGraph failed, passed nullptr to liteGraph."); + return OH_NN_INVALID_PARAMETER; + } + + auto *pLiteGraph = static_cast(liteGraph); + InnerModel *innerModel = reinterpret_cast(model); + + // Once the innerModel built from the liteGraph successfully, the innerModel + // owns the liteGraph, in which case, the invoker should not delete + // the liteGraph actively. Otherwise, the invoker still has the ownership. + return innerModel->BuildFromLiteGraph(pLiteGraph); +} + +NNRT_API OH_NN_ReturnCode OH_NNModel_BuildFromMetaGraph(OH_NNModel *model, const void *metaGraph, + const OH_NN_Extension *extensions, size_t extensionSize) +{ + if (model == nullptr) { + LOGE("OH_NNModel_BuildFromMetaGraph failed, passed nullptr to model."); + return OH_NN_INVALID_PARAMETER; + } + + if (metaGraph == nullptr) { + LOGE("OH_NNModel_BuildFromMetaGraph failed, passed nullptr to metaGraph."); + return OH_NN_INVALID_PARAMETER; + } + + Buffer buffer; + std::string modelName; + for (size_t i = 0; i < extensionSize; ++i) { + std::string name = extensions[i].name; + if (name == "QuantBuffer") { + buffer.data = extensions[i].value; + buffer.length = extensions[i].valueSize; + } else if (name == "ModelName") { + modelName.assign(extensions[i].value, extensions[i].value + extensions[i].valueSize); + } + } + + InnerModel *innerModel = reinterpret_cast(model); + return innerModel->BuildFromMetaGraph(metaGraph, buffer, modelName); +} + +NNRT_API OH_NN_ReturnCode OH_NNModel_SetInputsAndOutputsInfo(OH_NNModel *model, const OH_NN_TensorInfo *inputsInfo, + size_t inputSize, const OH_NN_TensorInfo *outputsInfo, size_t outputSize) +{ + if (model == nullptr) { + LOGE("OH_NNModel_SetInputsAndOutputsInfo failed, passed nullptr to model."); + return OH_NN_INVALID_PARAMETER; + } + + if ((inputsInfo == nullptr) || (inputSize == 0)) { + LOGE("OH_NNModel_SetInputsAndOutputsInfo failed, inputsInfo is empty."); + return OH_NN_INVALID_PARAMETER; + } + + if ((outputsInfo == nullptr) || (outputSize == 0)) { + LOGE("OH_NNModel_SetInputsAndOutputsInfo failed, outputsInfo is empty."); + return OH_NN_INVALID_PARAMETER; + } + + InnerModel *innerModel = reinterpret_cast(model); + return innerModel->SetInputsAndOutputsInfo(inputsInfo, inputSize, outputsInfo, outputSize); +} + +NNRT_API void OH_NNModel_Destroy(OH_NNModel **model) +{ + if (model == nullptr) { + LOGW("OH_NNModel_Destroy has no effect, passed nullptr to model."); + return; + } + + if (*model == nullptr) { + LOGW("OH_NNModel_Destroy has no effect, passed nullptr to *model."); + return; + } + + InnerModel *innerModel = reinterpret_cast(*model); + delete innerModel; + *model = nullptr; +} + +NNRT_API OH_NN_ReturnCode OH_NNModel_GetAvailableOperations(OH_NNModel *model, + size_t deviceID, + const bool **isAvailable, + uint32_t *opCount) +{ + if (model == nullptr) { + LOGE("OH_NNModel_GetAvailableOperations failed, passed nullptr to model."); + return OH_NN_INVALID_PARAMETER; + } + + if (isAvailable == nullptr) { + LOGE("OH_NNModel_GetAvailableOperations failed, passed nullptr to isAvailable."); + return OH_NN_INVALID_PARAMETER; + } + + if (*isAvailable != nullptr) { + LOGE("OH_NNModel_GetAvailableOperations failed, *isAvailable is not nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + if (opCount == nullptr) { + LOGE("OH_NNModel_GetAvailableOperations failed, passed nullptr to opCount."); + return OH_NN_INVALID_PARAMETER; + } + + InnerModel *innerModel = reinterpret_cast(model); + return innerModel->GetSupportedOperations(deviceID, isAvailable, *opCount); +} + +NNRT_API OH_NNCompilation *OH_NNCompilation_Construct(const OH_NNModel *model) +{ + if (model == nullptr) { + LOGE("OH_NNCompilation_Construct failed, passed nullptr to model."); + return nullptr; + } + const InnerModel *innerModel = reinterpret_cast(model); + + if (!innerModel->IsBuild()) { + LOGE("OH_NNCompilation_Construct failed, should call OH_NNModel_Finish before creating compilation."); + return nullptr; + } + + Compilation *compilation = new(std::nothrow) Compilation(innerModel); + if (compilation == nullptr) { + LOGE("OH_NNCompilation_Construct failed, please check whether it has enough memory."); + return nullptr; + } + + OH_NNCompilation* nnCompilation = reinterpret_cast(compilation); + return nnCompilation; +} + +NNRT_API OH_NN_ReturnCode OH_NNCompilation_SetDevice(OH_NNCompilation *compilation, size_t deviceID) +{ + if (compilation == nullptr) { + LOGE("OH_NNCompilation_SetDevice failed, passed nullptr to compilation."); + return OH_NN_INVALID_PARAMETER; + } + + Compilation* innerCompilation = reinterpret_cast(compilation); + return innerCompilation->SetDevice(deviceID); +} + +NNRT_API OH_NN_ReturnCode OH_NNCompilation_SetCache(OH_NNCompilation *compilation, + const char *cachePath, + uint32_t version) +{ + if (compilation == nullptr) { + LOGE("OH_NNCompilation_SetCache failed, passed nullptr to compilation."); + return OH_NN_INVALID_PARAMETER; + } + + if (cachePath == nullptr) { + LOGE("OH_NNCompilation_SetCache failed, passed nullptr to cachePath."); + return OH_NN_INVALID_PARAMETER; + } + + Compilation* innerCompilation = reinterpret_cast(compilation); + return innerCompilation->SetCacheDir(cachePath, version); +} + +NNRT_API OH_NN_ReturnCode OH_NNCompilation_SetPerformanceMode(OH_NNCompilation *compilation, + OH_NN_PerformanceMode performanceMode) +{ + if (compilation == nullptr) { + LOGE("OH_NNCompilation_SetPerformanceMode failed, passed nullptr to compilation."); + return OH_NN_INVALID_PARAMETER; + } + + Compilation* innerCompilation = reinterpret_cast(compilation); + return innerCompilation->SetPerformance(performanceMode); +} + +NNRT_API OH_NN_ReturnCode OH_NNCompilation_SetPriority(OH_NNCompilation *compilation, + OH_NN_Priority priority) +{ + if (compilation == nullptr) { + LOGE("OH_NNCompilation_SetPriority failed, passed nullptr to compilation."); + return OH_NN_INVALID_PARAMETER; + } + + Compilation* innerCompilation = reinterpret_cast(compilation); + return innerCompilation->SetPriority(priority); +} + +NNRT_API OH_NN_ReturnCode OH_NNCompilation_EnableFloat16(OH_NNCompilation *compilation, bool enableFloat16) +{ + if (compilation == nullptr) { + LOGE("OH_NNCompilation_EnableFloat16 failed, passed nullptr to compilation."); + return OH_NN_INVALID_PARAMETER; + } + + Compilation* innerCompilation = reinterpret_cast(compilation); + return innerCompilation->SetEnableFp16(enableFloat16); +} + +NNRT_API OH_NN_ReturnCode OH_NNCompilation_Build(OH_NNCompilation *compilation) +{ + if (compilation == nullptr) { + LOGE("OH_NNCompilation_Build failed, passed nullptr to compilation."); + return OH_NN_INVALID_PARAMETER; + } + + Compilation* innerCompilation = reinterpret_cast(compilation); + return innerCompilation->Build(); +} + +NNRT_API void OH_NNCompilation_Destroy(OH_NNCompilation **compilation) +{ + if (compilation == nullptr) { + LOGW("OH_NNCompilation_Destroy has no effect, passed nullptr to compilation."); + return; + } + + if (*compilation == nullptr) { + LOGW("OH_NNCompilation_Destroy has no effect, passed nullptr to *compilation."); + return; + } + + Compilation *innerCompilation = reinterpret_cast(*compilation); + delete innerCompilation; + *compilation = nullptr; +} + +NNRT_API OH_NNExecutor *OH_NNExecutor_Construct(OH_NNCompilation *compilation) +{ + if (compilation == nullptr) { + LOGE("OH_NNExecutor_Construct failed, passed nullptr to compilation."); + return nullptr; + } + Compilation *innerCompilation = reinterpret_cast(compilation); + + if (!innerCompilation->IsBuild()) { + LOGE("OH_NNExecutor_Construct failed, should call OH_NNCompilation_Build before creating executor."); + return nullptr; + } + + Executor* executor = new(std::nothrow) Executor(innerCompilation); + if (executor == nullptr) { + LOGE("OH_NNExecutor_Construct failed, please check whether it has enough memory."); + return nullptr; + } + + OH_NNExecutor* nnExecutor = reinterpret_cast(executor); + return nnExecutor; +} + +NNRT_API OH_NN_ReturnCode OH_NNExecutor_SetInput(OH_NNExecutor *executor, + uint32_t inputIndex, + const OH_NN_Tensor *tensor, + const void *dataBuffer, + size_t length) +{ + if (executor == nullptr) { + LOGE("OH_NNExecutor_SetInput failed, passed nullptr to executor."); + return OH_NN_INVALID_PARAMETER; + } + + if (tensor == nullptr) { + LOGE("OH_NNExecutor_SetInput failed, passed nullptr to tensor."); + return OH_NN_INVALID_PARAMETER; + } + + if (dataBuffer == nullptr) { + LOGE("OH_NNExecutor_SetInput failed, passed nullptr to dataBuffer."); + return OH_NN_INVALID_PARAMETER; + } + + if (length == 0) { + LOGE("OH_NNExecutor_SetInput failed, dataBuffer length is 0."); + return OH_NN_INVALID_PARAMETER; + } + + Executor* innerExecutor = reinterpret_cast(executor); + return innerExecutor->SetInput(inputIndex, *tensor, dataBuffer, length); +} + +NNRT_API OH_NN_ReturnCode OH_NNExecutor_SetOutput(OH_NNExecutor *executor, + uint32_t outputIndex, + void *dataBuffer, + size_t length) +{ + if (executor == nullptr) { + LOGE("OH_NNExecutor_SetOutput failed, passed nullptr to executor."); + return OH_NN_INVALID_PARAMETER; + } + + if (dataBuffer == nullptr) { + LOGE("OH_NNExecutor_SetOutput failed, passed nullptr to dataBuffer."); + return OH_NN_INVALID_PARAMETER; + } + + if (length == 0) { + LOGE("OH_NNExecutor_SetOutput failed, dataBuffer length is 0."); + return OH_NN_INVALID_PARAMETER; + } + + Executor* innerExecutor = reinterpret_cast(executor); + return innerExecutor->SetOutput(outputIndex, dataBuffer, length); +} + +NNRT_API OH_NN_ReturnCode OH_NNExecutor_GetOutputShape(OH_NNExecutor *executor, + uint32_t outputIndex, + int32_t **shape, + uint32_t *shapeLength) +{ + if (executor == nullptr) { + LOGE("OH_NNExecutor_GetOutputShape failed, passed nullptr to executor."); + return OH_NN_INVALID_PARAMETER; + } + + if (shape == nullptr) { + LOGE("OH_NNExecutor_GetOutputShape failed, passed nullptr to shape."); + return OH_NN_INVALID_PARAMETER; + } + + if (*shape != nullptr) { + LOGE("OH_NNExecutor_GetOutputShape failed, *shape is not nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + if (shapeLength == nullptr) { + LOGE("OH_NNExecutor_GetOutputShape failed, passed nullptr to shapeLength."); + return OH_NN_INVALID_PARAMETER; + } + + Executor* innerExecutor = reinterpret_cast(executor); + return innerExecutor->GetOutputShape(outputIndex, shape, *shapeLength); +} + +NNRT_API OH_NN_ReturnCode OH_NNExecutor_Run(OH_NNExecutor *executor) +{ + if (executor == nullptr) { + LOGE("OH_NNExecutor_Run failed, passed nullptr to executor."); + return OH_NN_INVALID_PARAMETER; + } + + Executor *innerExecutor = reinterpret_cast(executor); + return innerExecutor->Run(); +} + +NNRT_API OH_NN_Memory *OH_NNExecutor_AllocateInputMemory(OH_NNExecutor *executor, uint32_t inputIndex, size_t length) +{ + if (executor == nullptr) { + LOGE("OH_NNExecutor_AllocateInputMemory failed, passed nullptr to executor."); + return nullptr; + } + + if (length == 0) { + LOGW("OH_NNExecutor_AllocateInputMemory has no effect, passed length equals 0."); + return nullptr; + } + + OH_NN_Memory *nnMemory = nullptr; + Executor *innerExecutor = reinterpret_cast(executor); + OH_NN_ReturnCode ret = innerExecutor->CreateInputMemory(inputIndex, length, &nnMemory); + if (ret != OH_NN_SUCCESS) { + LOGE("OH_NNExecutor_AllocateInputMemory failed, error happened when creating input memory in executor."); + return nullptr; + } + + return nnMemory; +} + +NNRT_API OH_NN_Memory *OH_NNExecutor_AllocateOutputMemory(OH_NNExecutor *executor, uint32_t outputIndex, size_t length) +{ + if (executor == nullptr) { + LOGE("OH_NNExecutor_AllocateOutputMemory failed, passed nullptr to executor."); + return nullptr; + } + + if (length == 0) { + LOGW("OH_NNExecutor_AllocateOutputMemory has no effect, passed length equals 0."); + return nullptr; + } + + OH_NN_Memory *nnMemory = nullptr; + Executor *innerExecutor = reinterpret_cast(executor); + OH_NN_ReturnCode ret = innerExecutor->CreateOutputMemory(outputIndex, length, &nnMemory); + if (ret != OH_NN_SUCCESS) { + LOGE("OH_NNExecutor_AllocateOutputMemory failed, error happened when creating output memory in executor."); + return nullptr; + } + + return nnMemory; +} + +NNRT_API void OH_NNExecutor_DestroyInputMemory(OH_NNExecutor *executor, uint32_t inputIndex, OH_NN_Memory **memory) +{ + if (executor == nullptr) { + LOGE("OH_NNExecutor_DestroyInputMemory failed, passed nullptr to executor."); + return; + } + + if (memory == nullptr) { + LOGW("OH_NNExecutor_DestroyInputMemory has no effect, passed nullptr to memory."); + return; + } + + if (*memory == nullptr) { + LOGW("OH_NNExecutor_DestroyInputMemory has no effect, passed nullptr to *memory."); + return; + } + + Executor *innerExecutor = reinterpret_cast(executor); + OH_NN_ReturnCode ret = innerExecutor->DestroyInputMemory(inputIndex, memory); + if (ret != OH_NN_SUCCESS) { + LOGE("OH_NNExecutor_DestroyInputMemory failed, error happened when destroying input memory."); + return; + } + + *memory = nullptr; +} + +NNRT_API void OH_NNExecutor_DestroyOutputMemory(OH_NNExecutor *executor, uint32_t outputIndex, OH_NN_Memory **memory) +{ + if (executor == nullptr) { + LOGE("OH_NNExecutor_DestroyOutputMemory failed, passed nullptr to executor."); + return; + } + + if (memory == nullptr) { + LOGW("OH_NNExecutor_DestroyOutputMemory has no effect, passed nullptr to memory."); + return; + } + + if (*memory == nullptr) { + LOGW("OH_NNExecutor_DestroyOutputMemory has no effect, passed nullptr to *memory."); + return; + } + + Executor *innerExecutor = reinterpret_cast(executor); + OH_NN_ReturnCode ret = innerExecutor->DestroyOutputMemory(outputIndex, memory); + if (ret != OH_NN_SUCCESS) { + LOGE("OH_NNExecutor_DestroyOutputMemory failed, error happened when destroying output memory."); + return; + } + + *memory = nullptr; +} + +NNRT_API OH_NN_ReturnCode OH_NNExecutor_SetInputWithMemory(OH_NNExecutor *executor, + uint32_t inputIndex, + const OH_NN_Tensor *tensor, + const OH_NN_Memory *memory) +{ + if (executor == nullptr) { + LOGE("OH_NNExecutor_SetInputWithMemory failed, passed nullptr to executor."); + return OH_NN_INVALID_PARAMETER; + } + + if (tensor == nullptr) { + LOGE("OH_NNExecutor_SetInputWithMemory failed, passed nullptr to tensor."); + return OH_NN_INVALID_PARAMETER; + } + + if (memory == nullptr) { + LOGE("OH_NNExecutor_SetInputWithMemory failed, passed nullptr to memory."); + return OH_NN_INVALID_PARAMETER; + } + + Executor *innerExecutor = reinterpret_cast(executor); + return innerExecutor->SetInputFromMemory(inputIndex, *tensor, *memory); +} + +NNRT_API OH_NN_ReturnCode OH_NNExecutor_SetOutputWithMemory(OH_NNExecutor *executor, + uint32_t outputIndex, + const OH_NN_Memory *memory) +{ + if (executor == nullptr) { + LOGE("OH_NNExecutor_SetOutputWithMemory failed, passed nullptr to executor."); + return OH_NN_INVALID_PARAMETER; + } + + if (memory == nullptr) { + LOGE("OH_NNExecutor_SetOutputWithMemory failed, passed nullptr to memory."); + return OH_NN_INVALID_PARAMETER; + } + + Executor *innerExecutor = reinterpret_cast(executor); + return innerExecutor->SetOutputFromMemory(outputIndex, *memory); +} + +NNRT_API void OH_NNExecutor_Destroy(OH_NNExecutor **executor) +{ + if (executor == nullptr) { + LOGW("OH_NNExecutor_Destroy has no effect, since executor is nullptr."); + return; + } + + if ((*executor) == nullptr) { + LOGW("OH_NNExecutor_Destroy has no effect, since *executor is nullptr"); + return; + } + + Executor *innerExecutor = reinterpret_cast(*executor); + delete innerExecutor; + *executor = nullptr; +} + +NNRT_API OH_NN_ReturnCode OH_NNDevice_GetAllDevicesID(const size_t **allDevicesID, uint32_t *deviceCount) +{ + if (allDevicesID == nullptr) { + LOGE("OH_NNDevice_GetAllDevicesID failed, passed nullptr to allDevicesID."); + return OH_NN_INVALID_PARAMETER; + } + + if ((*allDevicesID) != nullptr) { + LOGE("OH_NNDevice_GetAllDevicesID failed, *allDevicesID should be nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + if (deviceCount == nullptr) { + LOGE("OH_NNDevice_GetAllDevicesID failed, passed nullptr to deviceCount."); + return OH_NN_INVALID_PARAMETER; + } + + DeviceManager& deviceManager = DeviceManager::GetInstance(); + const std::vector& allDevices = deviceManager.GetAllDeviceId(); + + if (allDevices.empty()) { + LOGW("OH_NNDevice_GetAllDevicesID got no device."); + *allDevicesID = nullptr; + *deviceCount = 0; + return OH_NN_SUCCESS; + } + + *allDevicesID = allDevices.data(); + // allDevices.size() will not exceed UINT32_MAX, it is safe to cast to uint32_t. + *deviceCount = static_cast(allDevices.size()); + + return OH_NN_SUCCESS; +} + +NNRT_API OH_NN_ReturnCode OH_NNDevice_GetName(size_t deviceID, const char **name) +{ + if (name == nullptr) { + LOGE("OH_NNDevice_GetName failed, passed nullptr to name."); + return OH_NN_INVALID_PARAMETER; + } + + if ((*name) != nullptr) { + LOGE("OH_NNDevice_GetName failed, *name should be nullptr."); + return OH_NN_INVALID_PARAMETER; + } + + DeviceManager& deviceManager = DeviceManager::GetInstance(); + const std::string& deviceName = deviceManager.GetDeviceName(deviceID); + if (deviceName.empty()) { + LOGE("OH_NNDevice_GetName failed, error happened when getting name of deviceID %zu.", deviceID); + *name = nullptr; + return OH_NN_FAILED; + } + + *name = deviceName.data(); + return OH_NN_SUCCESS; +} + +NNRT_API OH_NN_ReturnCode OH_NNDevice_GetType(size_t deviceID, OH_NN_DeviceType* deviceType) +{ + DeviceManager& deviceManager = DeviceManager::GetInstance(); + std::shared_ptr device = deviceManager.GetDevice(deviceID); + if (device == nullptr) { + LOGE("OH_NNDevice_GetName failed, passed invalid deviceID."); + return OH_NN_INVALID_PARAMETER; + } + + if (deviceType == nullptr) { + LOGE("OH_NNDevice_GetType failed, passed nullptr to deviceType."); + return OH_NN_INVALID_PARAMETER; + } + + OH_NN_ReturnCode ret = device->GetDeviceType(*deviceType); + if (ret != OH_NN_SUCCESS) { + LOGE("OH_NNDevice_GetType failed, device id: %zu.", deviceID); + return ret; + } + return OH_NN_SUCCESS; +} \ No newline at end of file diff --git a/frameworks/native/nn_tensor.cpp b/frameworks/native/compat/nn_tensor.cpp similarity index 70% rename from frameworks/native/nn_tensor.cpp rename to frameworks/native/compat/nn_tensor.cpp index 71755a1c955c64a23355dc1a86390c6938ff51a7..ada172748adee032f44ca9308a65da34294eb2bc 100644 --- a/frameworks/native/nn_tensor.cpp +++ b/frameworks/native/compat/nn_tensor.cpp @@ -13,16 +13,19 @@ * limitations under the License. */ +#include "nn_tensor.h" + #include #include #include -#include "nn_tensor.h" -#include "validation.h" -#include "transform.h" #include "common/log.h" +#include "transform.h" +#include "validation.h" #include "mindir.h" #include "mindir_types.h" +#include "../validation.h" +#include "../quant_param.h" namespace OHOS { namespace NeuralNetworkRuntime { @@ -37,7 +40,7 @@ void DestroyLiteGraphTensor(void* tensor) NNTensor::~NNTensor() { if (m_buffer != nullptr) { - delete [] reinterpret_cast(m_buffer); + delete[] reinterpret_cast(m_buffer); } } @@ -85,17 +88,19 @@ OH_NN_ReturnCode NNTensor::Build(OH_NN_DataType dataType, } m_dataType = dataType; - OH_NN_ReturnCode ret = ParseDimensions(dimensions); + OH_NN_ReturnCode ret = ValidateDimensions(dimensions); if (ret != OH_NN_SUCCESS) { LOGE("Build failed, passed invalid dimensions."); return ret; } + m_dimensions = dimensions; - ret = ParseQuantParams(quantParam); + ret = ValidateQuantParams(quantParam); if (ret != OH_NN_SUCCESS) { LOGE("Build failed, please check quantParam."); return ret; } + m_quantParams = quantParam; return OH_NN_SUCCESS; } @@ -154,12 +159,65 @@ OH_NN_ReturnCode NNTensor::BuildFromOHNNTensorInfo(const OH_NN_TensorInfo& nnTen return OH_NN_SUCCESS; } -OH_NN_ReturnCode NNTensor::ParseDimensions(const std::vector& dimensions) +/** + * Builds an NNTensor from a given OH_NNCore_TensorDesc, except for quantization parameters and tensor type. + * + * @param tensorDesc pointer to the OH_NNCore_TensorDesc object + * + * @return OH_NNCore_ReturnCode indicating the success or failure of the operation + * + * @throws None + */ +OH_NNCore_ReturnCode NNTensor::BuildFromTensorDesc(const OH_NNCore_TensorDesc* tensorDesc) +{ + if (tensorDesc == nullptr) { + LOGE("BuildFromTensorDesc failed, passed nullptr to tensorDesc."); + return OH_NNCORE_INVALID_PARAMETER; + } + + const auto* tensorDescImpl = reinterpret_cast(tensorDesc); + + // Get datatype from TensorDesc and transform to OH_NN_DataType + OH_NNCore_DataType dataType; + OH_NNCore_ReturnCode ret = tensorDescImpl->GetDataType(&dataType); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("BuildFromTensorDesc failed, error happened when get nnCoreDataType."); + return ret; + } + if (!OHOS::NeuralNetworkCore::Validation::ValidateDataType(dataType)) { + LOGE("BuildFromTensorDesc failed, passed invalid nnCoreDataType."); + return OH_NNCORE_INVALID_PARAMETER; + } + + // TODO: put this function to compat transform + OH_NN_DataType compatDataType = OHOS::NeuralNetworkBackend::CoreToBackend::ConvertDataType(dataType); + + // Get Dimensions from TensorDesc and transform to std::vector + int32_t* shape {nullptr}; + size_t shapeNum {0}; + ret = tensorDescImpl->GetShape(&shape, &shapeNum); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("BuildFromTensorDesc failed, error happened when get nnCoreShape."); + return ret; + } + std::vector dimensions(shape, shape + shapeNum); + + // OH_NNCore_TensorDesc does not include quant parameters and tensor tyep, should be set using indenpendent interface. + OH_NN_ReturnCode nnReturnCode = Build(compatDataType, dimensions, {}, OH_NN_TENSOR); + if (nnReturnCode != OH_NN_SUCCESS) { + LOGE("BuildFromTensorDesc failed, passed invalid nnReturnCode."); + } + + // TODO: put this function to compat transform + return OHOS::NeuralNetworkBackend::BackendToCore::ConvertReturnCode(nnReturnCode); +} + +OH_NN_ReturnCode NNTensor::ValidateDimensions(const std::vector& dimensions) { // Temporary variable to check overflow. - uint64_t absoluteDim {0}; - uint64_t elementCount {1}; - uint64_t dataLength {static_cast(GetTypeSize(m_dataType))}; + uint64_t absoluteDim{0}; + uint64_t elementCount{1}; + uint64_t dataLength{static_cast(GetTypeSize(m_dataType))}; m_isDynamicShape = false; for (int32_t dim : dimensions) { if (dim < -1 || dim == 0) { @@ -187,7 +245,6 @@ OH_NN_ReturnCode NNTensor::ParseDimensions(const std::vector& dimension m_dataLength = static_cast(dataLength); } - m_dimensions = std::move(dimensions); return OH_NN_SUCCESS; } @@ -200,11 +257,12 @@ OH_NN_ReturnCode NNTensor::ParseDimensions(const int32_t* dimensions, uint32_t d } std::vector dimensionsVec = ConstructVectorFromArray(dimensions, dimensionCount); - ret = ParseDimensions(dimensionsVec); + ret = ValidateDimensions(dimensionsVec); if (ret != OH_NN_SUCCESS) { LOGE("BuildFromOHNNTensor failed, passed invalid dimension info."); return ret; } + m_dimensions = std::move(dimensionsVec); return OH_NN_SUCCESS; } @@ -231,16 +289,17 @@ OH_NN_ReturnCode NNTensor::ParseQuantParams(const OH_NN_QuantParam* quantParam) tmpQuantParam.emplace_back((QuantParam){numBits, scale, zeroPoint}); } - OH_NN_ReturnCode ret = ParseQuantParams(tmpQuantParam); + OH_NN_ReturnCode ret = ValidateQuantParams(tmpQuantParam); if (ret != OH_NN_SUCCESS) { - LOGE("ParseQuantParams failed, please numBits in NNTensor."); + LOGE("ParseQuantParams failed, error happened when checking quantization parameters."); return ret; } + m_quantParams = std::move(tmpQuantParam); return OH_NN_SUCCESS; } -OH_NN_ReturnCode NNTensor::ParseQuantParams(const std::vector& quantParams) +OH_NN_ReturnCode NNTensor::ValidateQuantParams(const std::vector& quantParams) { for (const QuantParam& param : quantParams) { // Only support 8-bit quantization in NNR version 1.0 @@ -250,7 +309,6 @@ OH_NN_ReturnCode NNTensor::ParseQuantParams(const std::vector& quant } } - m_quantParams = quantParams; return OH_NN_SUCCESS; } @@ -283,17 +341,18 @@ OH_NN_ReturnCode NNTensor::SetDimensions(const std::vector& dimensions) size_t dimensionCount = dimensions.size(); if (dimensionCount != expectedDimensionCount) { LOGE("Passed dimensions have different dimension counts from NNTensor, expected %zu, but passed %zu.", - expectedDimensionCount, dimensionCount); + expectedDimensionCount, + dimensionCount); return OH_NN_INVALID_PARAMETER; } - auto ret = ParseDimensions(dimensions); + auto ret = ValidateDimensions(dimensions); if (ret != OH_NN_SUCCESS) { LOGE("SetDimemsions failed, passed invalid dimension info."); return ret; } - m_dimensions = dimensions; + return OH_NN_SUCCESS; } @@ -361,8 +420,8 @@ LiteGraphTensorPtr NNTensor::ConvertToLiteGraphTensor() const quantParams.emplace_back(std::move(msQuantParam)); } - mindspore::lite::TensorPtr tensor = mindspore::lite::MindIR_Tensor_Create( - m_name, dataType, m_dimensions, format, data, quantParams); + mindspore::lite::TensorPtr tensor = + mindspore::lite::MindIR_Tensor_Create(m_name, dataType, m_dimensions, format, data, quantParams); if (tensor == nullptr) { LOGE("ConvertToLiteGraphTensor failed, please check attributes of NNTensor."); return {nullptr, DestroyLiteGraphTensor}; @@ -381,6 +440,19 @@ void NNTensor::ConvertToIOTensor(IOTensor& tensor) const tensor.length = m_bufferLength; } +// TODO: Need to check whether the NNTensor can be release after converting to NNTensorDesc +void NNTensor::ConvertToTensorDesc(OHOS::NeuralNetworkCore::TensorDesc& desc) const +{ + OH_NNCore_DataType dataType = OHOS::NeuralNetworkBackend::BackendToCore::ConvertDataType(m_dataType); + desc.SetDataType(dataType); + + OH_NNCore_Format format = OHOS::NeuralNetworkBackend::BackendToCore::ConvertFormat(m_format); + desc.SetFormat(format); + + desc.SetName(m_name.c_str()); + desc.SetShape(m_dimensions.data(), m_dimensions.size()); +} + bool NNTensor::IsDynamicShape() const { return m_isDynamicShape; @@ -423,7 +495,9 @@ bool NNTensor::CompareAttribute(const NNTensor& tensor) const for (size_t i = 0; i < dimensionsSize; i++) { if ((m_dimensions[i] != -1) && (m_dimensions[i] != dimensions[i])) { LOGI("Tensors have different dimension: dimension index: %zu, dimension value: %d and %d.", - i, m_dimensions[i], dimensions[i]); + i, + m_dimensions[i], + dimensions[i]); return false; } } @@ -435,5 +509,35 @@ bool NNTensor::CompareAttribute(const NNTensor& tensor) const return true; } -} // NeuralNetworkRuntime -} // OHOS \ No newline at end of file + +OH_NNCore_ReturnCode NNTensor::SetQuantParam(const OH_NNBackend_QuantParam* quantParam) +{ + if (quantParam == nullptr) { + LOGE("SetQuantParam failed, quantParam is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + const auto* quantParamImpl = reinterpret_cast(quantParam); + m_quantParams.clear(); + OH_NNCore_ReturnCode returnCode = quantParamImpl->CopyToCompat(m_quantParams); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("SetQuantParam failed, error happened when converting quantization parameters."); + return returnCode; + } + + OH_NN_ReturnCode ret = ValidateQuantParams(m_quantParams); + if (ret != OH_NN_SUCCESS) { + m_quantParams.clear(); + LOGE("SetQuantParam failed, error happened when parsing quantization parameters."); + } + + return OHOS::NeuralNetworkBackend::BackendToCore::ConvertReturnCode(ret); +} + +OH_NNCore_ReturnCode NNTensor::SetTensorType(OH_NNBackend_TensorType tensorType) +{ + m_type = (OH_NN_TensorType)(tensorType); + return OH_NNCORE_SUCCESS; +} +} // namespace NeuralNetworkRuntime +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/nn_tensor.h b/frameworks/native/compat/nn_tensor.h similarity index 81% rename from frameworks/native/nn_tensor.h rename to frameworks/native/compat/nn_tensor.h index fc7db023825ea80e8d8dbcaffa627b82343005d5..14e80a21fc35be83edf674995e808927cf99d4b1 100644 --- a/frameworks/native/nn_tensor.h +++ b/frameworks/native/compat/nn_tensor.h @@ -19,9 +19,10 @@ #include #include +#include "../tensor_desc.h" #include "cpp_type.h" -#include "interfaces/kits/c/neural_network_runtime.h" #include "interfaces/innerkits/c/neural_network_runtime_inner.h" +#include "interfaces/kits/c/v2_0/neural_network_runtime.h" namespace OHOS { namespace NeuralNetworkRuntime { @@ -45,7 +46,6 @@ public: const std::vector& dimensions, const std::vector& quantParam, OH_NN_TensorType type); - void IdentifyOpParameter(); void SetName(const std::string& name); void SetBuffer(const void* buffer, size_t length); @@ -55,31 +55,36 @@ public: std::string GetName() const; OH_NN_TensorType GetType() const; void* GetBuffer() const; - // Return complete buffer length - size_t GetBufferLength() const; - // Return actual data length, since the data can be store in a larger buffer - size_t GetDataLength() const; + size_t GetBufferLength() const; // Return complete buffer length + size_t GetDataLength() const; // Return actual data length, since the data can be store in a larger buffer OH_NN_DataType GetDataType() const; uint32_t GetElementCount() const; std::vector GetDimensions() const; OH_NN_Format GetFormat() const; std::vector GetQuantParam() const; + LiteGraphTensorPtr ConvertToLiteGraphTensor() const; void ConvertToIOTensor(IOTensor& tensor) const; + void ConvertToTensorDesc(OHOS::NeuralNetworkCore::TensorDesc& desc) const; + void IdentifyOpParameter(); bool IsDynamicShape() const; bool IsQuantTensor() const; bool IsScalar() const; bool IsOpParameter() const; bool CompareAttribute(const NNTensor& tensor) const; + // For NNRt v2.0 + OH_NNCore_ReturnCode BuildFromTensorDesc(const OH_NNCore_TensorDesc* tensorDesc); + OH_NNCore_ReturnCode SetQuantParam(const OH_NNBackend_QuantParam* quantParam); + OH_NNCore_ReturnCode SetTensorType(OH_NNBackend_TensorType tensorType); + private: // Used in BuildFromOHNNTensor() OH_NN_ReturnCode ParseQuantParams(const OH_NN_QuantParam* quantParams); OH_NN_ReturnCode ParseDimensions(const int32_t* dimensions, uint32_t dimensionCount); - // Used in Build() - OH_NN_ReturnCode ParseQuantParams(const std::vector& quantParams); - OH_NN_ReturnCode ParseDimensions(const std::vector& dimensions); + OH_NN_ReturnCode ValidateQuantParams(const std::vector& quantParams); + OH_NN_ReturnCode ValidateDimensions(const std::vector& dimensions); private: OH_NN_TensorType m_type {OH_NN_TENSOR}; diff --git a/frameworks/native/ops_builder.cpp b/frameworks/native/compat/ops_builder.cpp similarity index 100% rename from frameworks/native/ops_builder.cpp rename to frameworks/native/compat/ops_builder.cpp diff --git a/frameworks/native/ops_builder.h b/frameworks/native/compat/ops_builder.h similarity index 98% rename from frameworks/native/ops_builder.h rename to frameworks/native/compat/ops_builder.h index ca2f70c4cd12e946dd78524358e79159dfb876da..d9b2f4ff43587ec828bd6b1bba3b398420e8b1aa 100644 --- a/frameworks/native/ops_builder.h +++ b/frameworks/native/compat/ops_builder.h @@ -21,7 +21,7 @@ #include "nn_tensor.h" #include "common/log.h" -#include "interfaces/kits/c/neural_network_runtime.h" +#include "v1_0/neural_network_runtime_compat.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops_registry.cpp b/frameworks/native/compat/ops_registry.cpp similarity index 100% rename from frameworks/native/ops_registry.cpp rename to frameworks/native/compat/ops_registry.cpp diff --git a/frameworks/native/ops_registry.h b/frameworks/native/compat/ops_registry.h similarity index 96% rename from frameworks/native/ops_registry.h rename to frameworks/native/compat/ops_registry.h index 29171cbf11da14ebb42bb597f94ca26dd0e4a869..404d193c3d13fa23d2fdd7c5b3548b9dc1985343 100644 --- a/frameworks/native/ops_registry.h +++ b/frameworks/native/compat/ops_registry.h @@ -21,7 +21,7 @@ #include #include "ops_builder.h" -#include "interfaces/kits/c/neural_network_runtime.h" +#include "v1_0/neural_network_runtime_compat.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/prepared_model.h b/frameworks/native/compat/prepared_model.h similarity index 79% rename from frameworks/native/prepared_model.h rename to frameworks/native/compat/prepared_model.h index 7e64f08a68ac9232720658b3451d0f9eb4f469ed..e7e5d3510426c400c1bb4f12f55a23bfd70daa7c 100644 --- a/frameworks/native/prepared_model.h +++ b/frameworks/native/compat/prepared_model.h @@ -18,7 +18,8 @@ #include -#include "interfaces/kits/c/neural_network_runtime_type.h" +#include "v1_0/neural_network_runtime_type_compat.h" +#include "v2_0/neural_network_core_type.h" #include "cpp_type.h" namespace OHOS { @@ -35,6 +36,11 @@ public: std::vector>& outputsDims, std::vector& isOutputBufferEnough) = 0; + virtual OH_NN_ReturnCode Run(const std::vector& inputs, + const std::vector& outputs, + std::vector>& outputsDims, + std::vector& isOutputBufferEnough) = 0; + virtual OH_NN_ReturnCode GetInputDimRanges(std::vector>& minInputDims, std::vector>& maxInputDims) { diff --git a/frameworks/native/compat/transform.cpp b/frameworks/native/compat/transform.cpp new file mode 100644 index 0000000000000000000000000000000000000000..12e51b05209f2a7e2fd1c63b07c26bf6854805a4 --- /dev/null +++ b/frameworks/native/compat/transform.cpp @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "transform.h" + +#include "memory_manager.h" +#include "common/log.h" + +namespace OHOS { +namespace NeuralNetworkRuntime { +const uint32_t BIT8_TO_BYTE = 1; +const uint32_t BIT16_TO_BYTE = 2; +const uint32_t BIT32_TO_BYTE = 4; +const uint32_t BIT64_TO_BYTE = 8; + +uint32_t GetTypeSize(OH_NN_DataType type) +{ + switch (type) { + case OH_NN_BOOL: + return sizeof(bool); + case OH_NN_INT8: + case OH_NN_UINT8: + return BIT8_TO_BYTE; + case OH_NN_INT16: + case OH_NN_UINT16: + case OH_NN_FLOAT16: + return BIT16_TO_BYTE; + case OH_NN_INT32: + case OH_NN_UINT32: + case OH_NN_FLOAT32: + return BIT32_TO_BYTE; + case OH_NN_INT64: + case OH_NN_UINT64: + case OH_NN_FLOAT64: + return BIT64_TO_BYTE; + default: + return 0; + } +} + +mindspore::lite::DataType NNToMS::TransformDataType(OH_NN_DataType type) +{ + switch (type) { + case OH_NN_BOOL: + return mindspore::lite::DATA_TYPE_BOOL; + case OH_NN_INT8: + return mindspore::lite::DATA_TYPE_INT8; + case OH_NN_INT16: + return mindspore::lite::DATA_TYPE_INT16; + case OH_NN_INT32: + return mindspore::lite::DATA_TYPE_INT32; + case OH_NN_INT64: + return mindspore::lite::DATA_TYPE_INT64; + case OH_NN_UINT8: + return mindspore::lite::DATA_TYPE_UINT8; + case OH_NN_UINT16: + return mindspore::lite::DATA_TYPE_UINT16; + case OH_NN_UINT32: + return mindspore::lite::DATA_TYPE_UINT32; + case OH_NN_UINT64: + return mindspore::lite::DATA_TYPE_UINT64; + case OH_NN_FLOAT16: + return mindspore::lite::DATA_TYPE_FLOAT16; + case OH_NN_FLOAT32: + return mindspore::lite::DATA_TYPE_FLOAT32; + case OH_NN_FLOAT64: + return mindspore::lite::DATA_TYPE_FLOAT64; + default: + return mindspore::lite::DATA_TYPE_UNKNOWN; + } +} + +mindspore::lite::Format NNToMS::TransformFormat(OH_NN_Format type) +{ + switch (type) { + case OH_NN_FORMAT_NCHW: + return mindspore::lite::FORMAT_NCHW; + case OH_NN_FORMAT_NHWC: + return mindspore::lite::FORMAT_NHWC; + default: + return mindspore::lite::FORMAT_NHWC; + } +} + +mindspore::lite::ActivationType NNToMS::TransfromFusionType(OH_NN_FuseType type) +{ + switch (type) { + case OH_NN_FUSED_NONE: + return mindspore::lite::ACTIVATION_TYPE_NO_ACTIVATION; + case OH_NN_FUSED_RELU: + return mindspore::lite::ACTIVATION_TYPE_RELU; + case OH_NN_FUSED_RELU6: + return mindspore::lite::ACTIVATION_TYPE_RELU6; + default: + return mindspore::lite::ACTIVATION_TYPE_UNKNOWN; + } +} + +mindspore::lite::QuantType NNToMS::TransformQuantType(OHOS::NeuralNetworkRuntime::Ops::OpsQuantType type) +{ + switch (type) { + case OHOS::NeuralNetworkRuntime::Ops::OpsQuantType::QUANT_NONE: + return mindspore::lite::QUANT_TYPE_NONE; + case OHOS::NeuralNetworkRuntime::Ops::OpsQuantType::QUANT_ALL: + return mindspore::lite::QUANT_TYPE_ALL; + default: return mindspore::lite::QUANT_TYPE_NONE; + } +} + +mindspore::lite::PadMode NNToMS::TransformPadModeValue(int8_t padMode) +{ + // The value is an optional value of the int8_t type. The value 0 indicates the same, + // and the value 1 indicates valid. + return (padMode == 0) ? mindspore::lite::PadMode::PAD_MODE_SAME : + mindspore::lite::PadMode::PAD_MODE_VALID; +} + +OH_NN_DataType MSToNN::TransformDataType(mindspore::lite::DataType type) +{ + switch (type) { + case mindspore::lite::DATA_TYPE_BOOL: + return OH_NN_BOOL; + case mindspore::lite::DATA_TYPE_INT8: + return OH_NN_INT8; + case mindspore::lite::DATA_TYPE_INT16: + return OH_NN_INT16; + case mindspore::lite::DATA_TYPE_INT32: + return OH_NN_INT32; + case mindspore::lite::DATA_TYPE_INT64: + return OH_NN_INT64; + case mindspore::lite::DATA_TYPE_UINT8: + return OH_NN_UINT8; + case mindspore::lite::DATA_TYPE_UINT16: + return OH_NN_UINT16; + case mindspore::lite::DATA_TYPE_UINT32: + return OH_NN_UINT32; + case mindspore::lite::DATA_TYPE_UINT64: + return OH_NN_UINT64; + case mindspore::lite::DATA_TYPE_FLOAT16: + return OH_NN_FLOAT16; + case mindspore::lite::DATA_TYPE_FLOAT32: + return OH_NN_FLOAT32; + case mindspore::lite::DATA_TYPE_FLOAT64: + return OH_NN_FLOAT64; + default: + return OH_NN_UNKNOWN; + } +} + +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}); + } + return nnQuantParam; +} + +OH_NN_Format MSToNN::TransformFormat(mindspore::lite::Format msFormat) +{ + if (msFormat == mindspore::lite::FORMAT_NHWC) { + return OH_NN_Format::OH_NN_FORMAT_NHWC; + } else if (msFormat == mindspore::lite::FORMAT_NCHW) { + return OH_NN_Format::OH_NN_FORMAT_NCHW; + } + + return OH_NN_Format::OH_NN_FORMAT_NONE; +} +} // namespace NeuralNetworkRuntime +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/compat/transform.h b/frameworks/native/compat/transform.h new file mode 100644 index 0000000000000000000000000000000000000000..98260bc923aa8540e4373f11b0843bcbddcc5623 --- /dev/null +++ b/frameworks/native/compat/transform.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_RUNTIME_TRANSFORM_H +#define NEURAL_NETWORK_RUNTIME_TRANSFORM_H + +#include "v1_0/neural_network_runtime_type_compat.h" +#include "cpp_type.h" +#include "mindir.h" +#include "mindir_types.h" +#include "ops_builder.h" +#include "transform_nnbackend_to_nncore.h" +#include "transform_nncore_to_nnbackend.h" + +namespace OHOS { +namespace NeuralNetworkRuntime { +template +std::vector ConstructVectorFromArray(const T* data, size_t size) +{ + std::vector array; + if (data != nullptr) { + array.assign(data, data + size); + } + return array; +} + +uint32_t GetTypeSize(OH_NN_DataType type); + + +namespace NNToMS { +mindspore::lite::DataType TransformDataType(OH_NN_DataType type); +mindspore::lite::Format TransformFormat(OH_NN_Format type); +mindspore::lite::ActivationType TransfromFusionType(OH_NN_FuseType type); +mindspore::lite::QuantType TransformQuantType(OHOS::NeuralNetworkRuntime::Ops::OpsQuantType type); +mindspore::lite::PadMode TransformPadModeValue(int8_t padMode); +} // NNToMS + +namespace MSToNN { +OH_NN_DataType TransformDataType(mindspore::lite::DataType type); +std::vector TransformQuantParams(std::vector msQuantParams); +OH_NN_Format TransformFormat(mindspore::lite::Format msFormat); +} // namespace MSToNN +} // namespace NeuralNetworkRuntime +} // namespace OHOS +#endif // NEURAL_NETWORK_RUNTIME_TRANSFORM_H \ No newline at end of file diff --git a/frameworks/native/compat/transform_nnbackend_to_nncore.cpp b/frameworks/native/compat/transform_nnbackend_to_nncore.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2ee09f92c7c73971466ada5427f087589a5deecd --- /dev/null +++ b/frameworks/native/compat/transform_nnbackend_to_nncore.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "transform_nnbackend_to_nncore.h" + +namespace OHOS { +namespace NeuralNetworkBackend { +namespace BackendToCore { +OH_NNCore_ReturnCode ConvertReturnCode(OH_NN_ReturnCode returnCode) +{ + switch (returnCode) { + case OH_NN_SUCCESS: + return OH_NNCORE_SUCCESS; + case OH_NN_FAILED: + return OH_NNCORE_FAILED; + case OH_NN_INVALID_PARAMETER: + return OH_NNCORE_INVALID_PARAMETER; + case OH_NN_MEMORY_ERROR: + return OH_NNCORE_MEMORY_EXCEPTION; + case OH_NN_OPERATION_FORBIDDEN: + return OH_NNCORE_OPERATION_FORBIDDEN; + case OH_NN_NULL_PTR: + return OH_NNCORE_NULL_PTR; + case OH_NN_INVALID_FILE: + return OH_NNCORE_INVALID_FILE; + case OH_NN_UNAVALIDABLE_DEVICE: + return OH_NNCORE_UNAVAILABLE_BACKEND; + case OH_NN_INVALID_PATH: + return OH_NNCORE_INVALID_PATH; + default: + OH_NNCORE_FAILED; + } +} +OH_NNCore_DataType ConvertDataType(OH_NN_DataType dataType) +{ + switch (dataType) { + case OH_NN_FLOAT32: + return OH_NNCORE_FLOAT32; + case OH_NN_FLOAT16: + return OH_NNCORE_FLOAT16; + case OH_NN_INT8: + return OH_NNCORE_INT8; + case OH_NN_UINT8: + return OH_NNCORE_UINT8; + case OH_NN_INT16: + return OH_NNCORE_INT16; + case OH_NN_UINT16: + return OH_NNCORE_UINT16; + case OH_NN_INT32: + return OH_NNCORE_INT32; + case OH_NN_UINT32: + return OH_NNCORE_UINT32; + case OH_NN_INT64: + return OH_NNCORE_INT64; + case OH_NN_UINT64: + return OH_NNCORE_UINT64; + case OH_NN_BOOL: + return OH_NNCORE_BOOL; + case OH_NN_FLOAT64: + return OH_NNCORE_FLOAT64; + case OH_NN_UNKNOWN: + default: + return OH_NNCORE_OTHER_TYPES; + } +} + +OH_NNCore_Format ConvertFormat(OH_NN_Format format) +{ + switch (format) { + case OH_NN_FORMAT_NCHW: + return OH_NNCORE_FORMAT_NCHW; + case OH_NN_FORMAT_NHWC: + return OH_NNCORE_FORMAT_NHWC; + case OH_NN_FORMAT_NONE: + default: + return OH_NNCORE_FORMAT_NONE; + } +} +} // namespace BackendToCore +} // namespace NeuralNetworkBackend +} // namespace OHOS diff --git a/frameworks/native/compat/transform_nnbackend_to_nncore.h b/frameworks/native/compat/transform_nnbackend_to_nncore.h new file mode 100644 index 0000000000000000000000000000000000000000..2a99a65e7aebf54207f0ab09d3d1e65891ec0ccd --- /dev/null +++ b/frameworks/native/compat/transform_nnbackend_to_nncore.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_BACKEND_TRANSFORM_NNBACKEND_TONNCORE_H +#define NEURAL_NETWORK_BACKEND_TRANSFORM_NNBACKEND_TONNCORE_H + +#include "neural_network_core.h" +#include "neural_network_runtime_type_compat.h" + +namespace OHOS { +namespace NeuralNetworkBackend { +namespace BackendToCore { +OH_NNCore_ReturnCode ConvertReturnCode(OH_NN_ReturnCode returnCode); +OH_NNCore_DataType ConvertDataType(OH_NN_DataType dataType); +OH_NNCore_Format ConvertFormat(OH_NN_Format format); +} // namespace BackendToCore +} // namespace NeuralNetworkBackend +} // namespace OHOS +#endif diff --git a/frameworks/native/compat/transform_nncore_to_nnbackend.cpp b/frameworks/native/compat/transform_nncore_to_nnbackend.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8f05f88275241807a7561a78bc2e5123ffe1bba6 --- /dev/null +++ b/frameworks/native/compat/transform_nncore_to_nnbackend.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "transform_nncore_to_nnbackend.h" + +namespace OHOS { +namespace NeuralNetworkBackend { +namespace CoreToBackend { +OH_NN_DataType ConvertDataType(OH_NNCore_DataType nnCoreDataType) +{ + switch (nnCoreDataType) { + case OH_NNCORE_BOOL: + return OH_NN_BOOL; + case OH_NNCORE_INT8: + return OH_NN_INT8; + case OH_NNCORE_INT16: + return OH_NN_INT16; + case OH_NNCORE_INT32: + return OH_NN_INT32; + case OH_NNCORE_INT64: + return OH_NN_INT64; + case OH_NNCORE_UINT8: + return OH_NN_UINT8; + case OH_NNCORE_UINT16: + return OH_NN_UINT16; + case OH_NNCORE_UINT32: + return OH_NN_UINT32; + case OH_NNCORE_UINT64: + return OH_NN_UINT64; + case OH_NNCORE_FLOAT16: + return OH_NN_FLOAT16; + case OH_NNCORE_FLOAT32: + return OH_NN_FLOAT32; + case OH_NNCORE_FLOAT64: + return OH_NN_FLOAT64; + case OH_NNCORE_DOUBLE: + case OH_NNCORE_OTHER_TYPES: + return OH_NN_UNKNOWN; + default: + return OH_NN_UNKNOWN; + } +} +} // namespace CoreToBackend +} // namespace NeuralNetworkBackend +} // namespace OHOS diff --git a/frameworks/native/compat/transform_nncore_to_nnbackend.h b/frameworks/native/compat/transform_nncore_to_nnbackend.h new file mode 100644 index 0000000000000000000000000000000000000000..a3e5272c53986d224aa3551d494b27f7bd61e469 --- /dev/null +++ b/frameworks/native/compat/transform_nncore_to_nnbackend.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_BACKEND_TRANSFORM_NNCORE_TO_NNBACKEND_H +#define NEURAL_NETWORK_BACKEND_TRANSFORM_NNCORE_TO_NNBACKEND_H + +#include "neural_network_core.h" +#include "neural_network_runtime_type_compat.h" + +namespace OHOS { +namespace NeuralNetworkBackend { +namespace CoreToBackend { +OH_NN_DataType ConvertDataType(OH_NNCore_DataType nnCoreDataType); +} // namespace CoreToBackend +} // namespace NeuralNetworkBackend +} // namespace OHOS +#endif diff --git a/frameworks/native/compat/validation.cpp b/frameworks/native/compat/validation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d451601d122036d916cf0fac1dd5eb7f2a240318 --- /dev/null +++ b/frameworks/native/compat/validation.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mindir_types.h" + +#include "validation.h" + +namespace OHOS { +namespace NeuralNetworkRuntime { +namespace Validation { +bool ValidateTensorDataType(OH_NN_DataType dataType) +{ + if (dataType >= OH_NN_UNKNOWN && dataType <= OH_NN_FLOAT64) { + return true; + } + return false; +} + +bool ValidateTensorFormat(OH_NN_Format format) +{ + if ((format >= OH_NN_FORMAT_NONE) && (format <= OH_NN_FORMAT_NHWC)) { + return true; + } + return false; +} + +bool ValidatePerformanceMode(OH_NN_PerformanceMode performanceMode) +{ + if ((performanceMode >= OH_NN_PERFORMANCE_NONE) && (performanceMode <= OH_NN_PERFORMANCE_EXTREME)) { + return true; + } + return false; +} + +bool ValidatePriority(OH_NN_Priority priority) +{ + if ((priority >= OH_NN_PRIORITY_NONE) && (priority <= OH_NN_PRIORITY_HIGH)) { + return true; + } + return false; +} + +bool ValidateFuseType(OH_NN_FuseType fuseType) +{ + if ((fuseType >= OH_NN_FUSED_NONE) && (fuseType <= OH_NN_FUSED_RELU6)) { + return true; + } + return false; +} + +bool ValidatePadMode(int8_t padMode) +{ + if ((padMode >= mindspore::lite::PAD_MODE_PAD) && (padMode <= mindspore::lite::PAD_MODE_VALID)) { + return true; + } + return false; +} + +bool ValidateTensorType(OH_NN_TensorType nnTensorType) +{ + if ((nnTensorType >= OH_NN_TENSOR) && (nnTensorType <= OH_NN_UNSQUEEZE_AXIS)) { + return true; + } + return false; +} +} // namespace Validation +} // namespace NeuralNetworkRuntime +} // namespace OHOS diff --git a/frameworks/native/compat/validation.h b/frameworks/native/compat/validation.h new file mode 100644 index 0000000000000000000000000000000000000000..6487fbd27bd14095f79d700e1924dabf845aa894 --- /dev/null +++ b/frameworks/native/compat/validation.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_RUNTIME_VALIDATION_H +#define NEURAL_NETWORK_RUNTIME_VALIDATION_H + +#include "common/log.h" +#include "v1_0/neural_network_runtime_compat.h" + +namespace OHOS { +namespace NeuralNetworkRuntime { +namespace Validation { +template +OH_NN_ReturnCode ValidateArray(const T* data, size_t size) +{ + if ((data != nullptr) != (size > 0)) { + LOGE("ValidateArray failed, data should passed a valid pointer when size is larger than 0, " + "otherwise, data should be nullptr when size is 0."); + return OH_NN_INVALID_PARAMETER; + } + return OH_NN_SUCCESS; +} + +bool ValidateTensorType(OH_NN_TensorType nnTensorType); +bool ValidateTensorDataType(OH_NN_DataType dataType); +bool ValidateTensorFormat(OH_NN_Format format); +bool ValidatePerformanceMode(OH_NN_PerformanceMode performanceMode); +bool ValidatePriority(OH_NN_Priority priority); +bool ValidateFuseType(OH_NN_FuseType fuseType); +bool ValidatePadMode(int8_t padMode); +} // namespace Validation +} // NeuralNetworkRuntime +} // namespace OHOS + +#endif // NEURAL_NETWORK_RUNTIME_VALIDATION_H diff --git a/frameworks/native/compiled.h b/frameworks/native/compiled.h new file mode 100644 index 0000000000000000000000000000000000000000..a08ad2f1155a23192480a721e5d78f2ca7c0473b --- /dev/null +++ b/frameworks/native/compiled.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_CORE_COMPILED_H +#define NEURAL_NETWORK_CORE_COMPILED_H + +#include + +#include "options.h" +#include "v2_0/neural_network_core_type.h" + +namespace OHOS { +namespace NeuralNetworkCore { +class Compiled { +public: + Compiled() = default; + virtual ~Compiled() = default; + + virtual OH_NNCore_ReturnCode Save(const std::string& path) const = 0; + virtual OH_NNCore_ReturnCode Restore(const std::string& path, const Options* options) = 0; + virtual OH_NNCore_ReturnCode Save(const void* buffer, size_t length, size_t* modelSize) const = 0; + virtual OH_NNCore_ReturnCode Restore(const void* buffer, size_t modelSize, const Options* options) = 0; + + virtual OH_NNCore_ReturnCode GetInputCount(size_t* count) const = 0; + virtual OH_NNCore_ReturnCode GetInputDesc(size_t index, OH_NNCore_TensorDesc** tensorDesc) const= 0; + virtual OH_NNCore_ReturnCode GetOutputCount(size_t* count) const = 0; + virtual OH_NNCore_ReturnCode GetOutputDesc(size_t index, OH_NNCore_TensorDesc** tensorDesc) const = 0; + + virtual OH_NNCore_ReturnCode SetCompiledOptions(const OH_NNCore_Options* options) = 0; + + virtual OH_NNCore_ReturnCode CreateExecutor(OH_NNCore_Executor** executor) const = 0; + virtual OH_NNCore_ReturnCode GetBackendName(std::string& backendName) const = 0; +}; +} // namespace NeuralNetworkCore +} // namespace OHOS +#endif // NEURAL_NETWORK_CORE_COMPILED_H \ No newline at end of file diff --git a/frameworks/native/compiler.h b/frameworks/native/compiler.h new file mode 100644 index 0000000000000000000000000000000000000000..a51a020a3b53d001d90c6efeba89a67a84121caf --- /dev/null +++ b/frameworks/native/compiler.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_CORE_COMPILER_H +#define NEURAL_NETWORK_CORE_COMPILER_H + +#include "compiled.h" +#include "v2_0/neural_network_core_type.h" + +namespace OHOS { +namespace NeuralNetworkCore { +class Compiler { +public: + Compiler() = default; + virtual ~Compiler() = default; + + virtual OH_NNCore_ReturnCode SetOptions(const OH_NNCore_Options* compilationOptions) = 0; + virtual OH_NNCore_ReturnCode Build(const void* model, Compiled** compiled) = 0; + virtual OH_NNCore_ReturnCode Build(const std::string& filePath, Compiled** compiled) = 0; + virtual OH_NNCore_ReturnCode Build(const void* modelData, size_t modelSize, Compiled** compiled) = 0; +}; +} // namespace NeuralNetworkCore +} // namespace OHOS +#endif // NEURAL_NETWORK_CORE_COMPILER_H diff --git a/frameworks/native/demo.cpp b/frameworks/native/demo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1590e754135f9493df03269977ac3ba857ce3744 --- /dev/null +++ b/frameworks/native/demo.cpp @@ -0,0 +1,335 @@ +#include "v2_0/neural_network_core.h" +#include "v2_0/neural_network_runtime.h" +#include + +#include +#include "hilog/log.h" + +#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_NNCore_ReturnCode SetInputData(OH_NNCore_Tensor* inputTensor[], size_t inputSize) +{ + OH_NNCore_DataType dataType(OH_NNCORE_FLOAT32); + OH_NNCore_ReturnCode ret{OH_NNCORE_FAILED}; + size_t elementNum = 0; + for (size_t i = 0; i < inputSize; ++i) { + auto data = OH_NNCore_GetDataBuffer(inputTensor[i]); + CHECKEQ(data, nullptr, OH_NNCORE_FAILED, "Failed to get data buffer"); + auto desc = OH_NNCore_GetTensorDesc(inputTensor[i]); + CHECKEQ(desc, nullptr, OH_NNCORE_FAILED, "Failed to get desc"); + ret = OH_NNCore_GetTensorDescDataType(desc, &dataType); + CHECKNEQ(ret, OH_NNCORE_SUCCESS, OH_NNCORE_FAILED, "Failed to get data type"); + ret = OH_NNCore_GetTensorDescElementNum(desc, &elementNum); + CHECKNEQ(ret, OH_NNCORE_SUCCESS, OH_NNCORE_FAILED, "Failed to get element num"); + switch(dataType) { + case OH_NNCORE_FLOAT32: { + float* floatValue = reinterpret_cast(data); + for (size_t j = 0; j < elementNum; ++j) { + floatValue[j] = static_cast(j); + } + break; + } + case OH_NNCORE_INT32: { + int* intValue = reinterpret_cast(data); + for (size_t j = 0; j < elementNum; ++j) { + intValue[j] = static_cast(j); + } + break; + } + default: + return OH_NNCORE_FAILED; + } + } + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode Print(OH_NNCore_Tensor* outputTensor[], size_t outputSize) +{ + OH_NNCore_DataType dataType(OH_NNCORE_FLOAT32); + OH_NNCore_ReturnCode ret{OH_NNCORE_FAILED}; + size_t elementNum = 0; + for (size_t i = 0; i < outputSize; ++i) { + auto data = OH_NNCore_GetDataBuffer(outputTensor[i]); + CHECKEQ(data, nullptr, OH_NNCORE_FAILED, "Failed to get data buffer"); + auto desc = OH_NNCore_GetTensorDesc(outputTensor[i]); + CHECKEQ(desc, nullptr, OH_NNCORE_FAILED, "Failed to get desc"); + ret = OH_NNCore_GetTensorDescDataType(desc, &dataType); + CHECKNEQ(ret, OH_NNCORE_SUCCESS, OH_NNCORE_FAILED, "Failed to get data type"); + ret = OH_NNCore_GetTensorDescElementNum(desc, &elementNum); + CHECKNEQ(ret, OH_NNCORE_SUCCESS, OH_NNCORE_FAILED, "Failed to get element num"); + printf("elementnum:%zu: ", elementNum); + switch(dataType) { + case OH_NNCORE_FLOAT32: { + float* floatValue = reinterpret_cast(data); + for (size_t j = 0; j < std::min((size_t)10, elementNum); ++j) { + printf("%f ", floatValue[j]); + } + break; + } + case OH_NNCORE_INT32: { + int* intValue = reinterpret_cast(data); + for (size_t j = 0; j < std::min((size_t)10, elementNum); ++j) { + printf("%d ", intValue[j]); + } + break; + } + default: + return OH_NNCORE_FAILED; + } + printf("\n"); + } + printf("\n"); + + return OH_NNCORE_SUCCESS; +} + +int main(int argc, char** argv) { + // 查询当前已经对接的backendnnrt + // 1. 先查询backend总数 + size_t backendNum = 0; + OH_NNCore_ReturnCode returnCode = OH_NNCore_GetBackendNum(&backendNum); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_GetBackendNum failed."); + // 2. 遍历backend + std::string backendName; + for(size_t i = 0; i < backendNum; ++i) { + const char* backendNameTmp = nullptr; + returnCode = OH_NNCore_GetBackendName(i, &backendNameTmp); + backendName = backendNameTmp; + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_GetBackendName failed."); + } + printf("backendName:%s\n", backendName.c_str()); + + // 创建模型实例,进行模型构造 + OH_NNBackend_Model* model = OH_NNBackend_CreateModel(); + CHECKEQ(model, nullptr, -1, "Create model failed."); + + + // 添加Add算子的第一个输入Tensor,类型为float32,张量形状为[1, 2, 2, 3] + OH_NNCore_TensorDesc* tensorDesc = OH_NNCore_CreateTensorDesc(); + CHECKEQ(tensorDesc, nullptr, -1, "Create TensorDesc failed."); + + int32_t inputDims[4] = {1, 2, 2, 3}; + returnCode = OH_NNCore_SetTensorDescShape(tensorDesc, inputDims, 4); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc shape failed."); + + returnCode = OH_NNCore_SetTensorDescDataType(tensorDesc, OH_NNCORE_FLOAT32); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc data type failed."); + + returnCode = OH_NNCore_SetTensorDescFormat(tensorDesc, OH_NNCORE_FORMAT_NONE); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc format failed."); + + returnCode = OH_NNBackend_AddTensorToModel(model, tensorDesc); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Add first TensorDesc to model failed."); + + returnCode = OH_NNBackend_SetModelTensorType(model, 0, OH_NNBACKEND_TENSOR); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set model tensor type failed."); + + + // 添加Add算子的第二个输入Tensor,类型为float32,张量形状为[1, 2, 2, 3] + tensorDesc = OH_NNCore_CreateTensorDesc(); + CHECKEQ(tensorDesc, nullptr, -1, "Create TensorDesc failed."); + + returnCode = OH_NNCore_SetTensorDescShape(tensorDesc, inputDims, 4); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc shape failed."); + + returnCode = OH_NNCore_SetTensorDescDataType(tensorDesc, OH_NNCORE_FLOAT32); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc data type failed."); + + returnCode = OH_NNCore_SetTensorDescFormat(tensorDesc, OH_NNCORE_FORMAT_NONE); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc format failed."); + + returnCode = OH_NNBackend_AddTensorToModel(model, tensorDesc); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Add second TensorDesc to model failed."); + + returnCode = OH_NNBackend_SetModelTensorType(model, 1, OH_NNBACKEND_TENSOR); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set model tensor type failed."); + + + // 添加Add算子的参数Tensor,该参数Tensor用于指定激活函数的类型,Tensor的数据类型为int8。 + tensorDesc = OH_NNCore_CreateTensorDesc(); + CHECKEQ(tensorDesc, nullptr, -1, "Create TensorDesc failed."); + + int32_t activationDims = 1; + returnCode = OH_NNCore_SetTensorDescShape(tensorDesc, &activationDims, 1); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc shape failed."); + + returnCode = OH_NNCore_SetTensorDescDataType(tensorDesc, OH_NNCORE_INT8); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc data type failed."); + + returnCode = OH_NNCore_SetTensorDescFormat(tensorDesc, OH_NNCORE_FORMAT_NONE); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc format failed."); + + returnCode = OH_NNBackend_AddTensorToModel(model, tensorDesc); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Add second TensorDesc to model failed."); + + returnCode = OH_NNBackend_SetModelTensorType(model, 2, OH_NNBACKEND_ADD_ACTIVATIONTYPE); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set model tensor type failed."); + + // 将激活函数类型设置为OH_NNBACKEND_FUSED_NONE,表示该算子不添加激活函数。 + int8_t activationValue = OH_NNBACKEND_FUSED_NONE; + returnCode = OH_NNBackend_SetModelTensorData(model, 2, &activationValue, sizeof(int8_t)); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set model tensor data failed."); + + + // 设置Add算子的输出,类型为float32,张量形状为[1, 2, 2, 3] + tensorDesc = OH_NNCore_CreateTensorDesc(); + CHECKEQ(tensorDesc, nullptr, -1, "Create TensorDesc failed."); + + returnCode = OH_NNCore_SetTensorDescShape(tensorDesc, inputDims, 4); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc shape failed."); + + returnCode = OH_NNCore_SetTensorDescDataType(tensorDesc, OH_NNCORE_FLOAT32); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc data type failed."); + + returnCode = OH_NNCore_SetTensorDescFormat(tensorDesc, OH_NNCORE_FORMAT_NONE); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set TensorDesc format failed."); + + returnCode = OH_NNBackend_AddTensorToModel(model, tensorDesc); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Add forth TensorDesc to model failed."); + + returnCode = OH_NNBackend_SetModelTensorType(model, 3, OH_NNBACKEND_TENSOR); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Set model tensor type failed."); + + // 指定Add算子的输入、参数和输出索引 + uint32_t inputIndicesValues[2] = {0, 1}; + uint32_t paramIndicesValues = 2; + uint32_t outputIndicesValues = 3; + OH_NNBackend_Array paramIndices = {¶mIndicesValues, 1 * 4, OH_NNCORE_UINT32}; + OH_NNBackend_Array inputIndices = {inputIndicesValues, 2 * 4, OH_NNCORE_UINT32}; + OH_NNBackend_Array outputIndices = {&outputIndicesValues, 1 * 4, OH_NNCORE_UINT32}; + + // 向模型实例添加Add算子 + returnCode = OH_NNBackend_AddOperationToModel(model, OH_NNBACKEND_OPS_ADD, ¶mIndices, &inputIndices, &outputIndices); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Add operation to model failed."); + + // 设置模型实例的输入、输出索引 + returnCode = OH_NNBackend_SpecifyModelInputsAndOutputs(model, &inputIndices, &outputIndices); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Specify model inputs and outputs failed."); + + // 完成模型实例的构建 + returnCode = OH_NNBackend_BuildModel(model); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "Build model failed."); + + // 创建并设置options + OH_NNCore_Options* options = OH_NNCore_CreateOptions(backendName.c_str()); + CHECKEQ(options, nullptr, -1, "OH_NNCore_CreateOptions failed."); + returnCode = OH_NNCore_SetPriority(options, OH_NNCORE_PRIORITY_HIGH); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_SetPriority failed."); + returnCode = OH_NNCore_SetPerformanceMode(options, OH_NNCORE_PERFORMANCE_EXTREME); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_SetPerformanceMode failed."); + returnCode = OH_NNCore_SetEnableFloat16(options, true); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_SetEnableFloat16 failed."); + returnCode = OH_NNBackend_SetCacheVersion(options, 1); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNBackend_SetCacheVersion failed."); + + // 创建compilation,将构图的model或MSLite传下来的model传入 + OH_NNCore_Compilation* compilation = OH_NNCore_ConstructCompilationWithNNModel(model); + CHECKEQ(compilation, nullptr, -1, "OH_NNCore_ConstructCompilationWithNNModel failed."); + // 编译生成compiled对象后销毁compilation + OH_NNCore_Compiled* compiled = OH_NNCore_BuildCompilation(compilation, backendName.c_str(), options); + CHECKEQ(compiled, nullptr, -1, "OH_NNCore_BuildCompilation failed."); + returnCode = OH_NNCore_DestroyCompilation(&compilation); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_DestroyCompilation failed."); + + // 保存cache + const char* filePath = "./cache"; + returnCode = OH_NNCore_SaveCompiledToFile(compiled, filePath); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_SaveCompiledToFile failed."); + // 从compiled获取输入输出信息 + size_t inputCount = 0; + returnCode = OH_NNCore_GetCompiledInputNum(compiled, &inputCount); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_GetCompiledInputCount failed."); + std::vector inputTensorDescs; + OH_NNCore_TensorDesc* tensorDescTmp = nullptr; + for (size_t i = 0; i < inputCount; ++i) { + tensorDescTmp = nullptr; + returnCode = OH_NNCore_GetCompiledInputDesc(compiled, i, &tensorDescTmp); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_GetCompiledInputDesc failed."); + inputTensorDescs.emplace_back(tensorDescTmp); + // size_t bs = 0; + // returnCode = OH_NNCore_GetTensorDescByteSize(tensorDescTmp, &bs); + // CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_GetTensorDescByteSize failed.\n"); + // printf("tensorDescTmp:%zu\n", bs); + } + size_t outputCount = 0; + returnCode = OH_NNCore_GetCompiledOutputNum(compiled, &outputCount); + std::vector outputTensorDescs; + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_GetCompiledOutputCount failed."); + for (size_t i = 0; i < outputCount; ++i) { + tensorDescTmp = nullptr; + returnCode = OH_NNCore_GetCompiledOutputDesc(compiled, i, &tensorDescTmp); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_GetCompiledOutputDesc failed."); + outputTensorDescs.emplace_back(tensorDescTmp); + } + + // 从compiled中创建executor + OH_NNCore_Executor* executor = OH_NNCore_ConstructExecutor(compiled); + CHECKEQ(executor, nullptr, -1, "OH_NNCore_ConstructExecutor failed."); + // // 销毁compiled + // returnCode = OH_NNCore_DestroyCompiled(&compiled); + // CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_DestroyCompiled failed."); + // 创建输入输出Tensor + OH_NNCore_Tensor* inputTensors[inputCount]; + OH_NNCore_Tensor* tensor = nullptr; + for (size_t i = 0; i < inputCount; ++i) { + tensor = nullptr; + tensor = OH_NNCore_CreateTensor(backendName.c_str(), inputTensorDescs[i]); + CHECKEQ(tensor, nullptr, -1, "OH_NNCore_CreateTensor failed."); + inputTensors[i] = tensor; + } + OH_NNCore_Tensor* outputTensors[outputCount]; + for (size_t i = 0; i < outputCount; ++i) { + tensor = nullptr; + tensor = OH_NNCore_CreateTensor(backendName.c_str(), outputTensorDescs[i]); + CHECKEQ(tensor, nullptr, -1, "OH_NNCore_CreateTensor failed."); + outputTensors[i] = tensor; + } + // 设置输入元素值 + returnCode = SetInputData(inputTensors, inputCount); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "SetInputData failed."); + // 执行run + returnCode = OH_NNCore_ExecutorRunSync(executor, inputTensors, inputCount, outputTensors, outputCount); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_ExecutorRunSync failed."); + // 打印输出 + printf("inputs:\n"); + Print(inputTensors, inputCount); + printf("\n"); + printf("outputs:\n"); + Print(outputTensors, outputCount); + // 清理输入输出Tensor + for (size_t i = 0; i < inputCount; ++i) { + returnCode = OH_NNCore_DestroyTensor(&inputTensors[i]); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_DestroyTensor failed."); + } + for (size_t i = 0; i < outputCount; ++i) { + returnCode = OH_NNCore_DestroyTensor(&outputTensors[i]); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_DestroyTensor failed."); + } + // 销毁Executor + returnCode = OH_NNCore_DestroyExecutor(&executor); + CHECKNEQ(returnCode, OH_NNCORE_SUCCESS, -1, "OH_NNCore_DestroyExecutor failed."); + + return 0; +} \ No newline at end of file diff --git a/frameworks/native/executor.h b/frameworks/native/executor.h index c7b2061e911800cef2efcf80bbec771e9b50b6dd..f6046514bcd584ed8a4c35746fac3c9d24eb8342 100644 --- a/frameworks/native/executor.h +++ b/frameworks/native/executor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,61 +13,39 @@ * limitations under the License. */ -#ifndef NEURAL_NETWORK_RUNTIME_EXECUTOR_H -#define NEURAL_NETWORK_RUNTIME_EXECUTOR_H +#ifndef NEURAL_NETWORK_CORE_EXECUTOR_H +#define NEURAL_NETWORK_CORE_EXECUTOR_H -#include "compilation.h" -#include "execution_plan.h" -#include "nn_tensor.h" -#include "interfaces/kits/c/neural_network_runtime.h" -#include "device.h" +#include +#include + +#include "compiler.h" +#include "compiled.h" +#include "tensor_desc.h" +#include "v2_0/neural_network_core_type.h" namespace OHOS { -namespace NeuralNetworkRuntime { +namespace NeuralNetworkCore { class Executor { public: - explicit Executor(const Compilation* compilation); - ~Executor(); - - OH_NN_ReturnCode SetInput(uint32_t index, const OH_NN_Tensor& nnTensor, const void* buffer, size_t length); - OH_NN_ReturnCode SetInputFromMemory(uint32_t index, const OH_NN_Tensor& nnTensor, const OH_NN_Memory& memory); - OH_NN_ReturnCode SetOutput(uint32_t index, void* buffer, size_t length); - OH_NN_ReturnCode SetOutputFromMemory(uint32_t index, const OH_NN_Memory& memory); - OH_NN_ReturnCode GetOutputShape(uint32_t index, int32_t** dimensions, uint32_t& dimensionCount); - - OH_NN_ReturnCode CreateInputMemory(uint32_t index, size_t length, OH_NN_Memory** memory); - OH_NN_ReturnCode CreateOutputMemory(uint32_t index, size_t length, OH_NN_Memory** memory); - OH_NN_ReturnCode DestroyInputMemory(uint32_t index, OH_NN_Memory** memory); - OH_NN_ReturnCode DestroyOutputMemory(uint32_t index, OH_NN_Memory** memory); - - OH_NN_ReturnCode Run(); - -private: - OH_NN_ReturnCode BuildInputTensor(uint32_t index, const OH_NN_Tensor& nnTensor, - std::shared_ptr inputTensor) const; - OH_NN_ReturnCode SetInputTensorWithCurrentBuffer(uint32_t index, std::shared_ptr inputTensor, - const void* buffer, size_t dataLength, size_t curBufferLength); - void SetInputTensorWithNewBuffer(uint32_t index, std::shared_ptr inputTensor, - const void* inputBuffer, size_t length, bool isInnerMem); - OH_NN_ReturnCode CheckInputDimRanges(uint32_t index, const OH_NN_Tensor& nnTensor) const; - -private: - struct ExeTensor { - std::shared_ptr tensor; - void* userBuffer; - size_t userBufferLength; - bool isInnerMem; - }; - bool m_isRun {false}; - std::vector> m_modelInputs; - std::vector> m_modelOutputs; - std::shared_ptr m_executionPlan {nullptr}; - std::unordered_map> m_outputDimensions; - std::unordered_map m_inputTensors; - std::unordered_map m_outputTensors; - std::unordered_map> m_inputCreatedMem; - std::unordered_map> m_outputCreatedMem; + Executor() = default; + virtual ~Executor() = default; + + virtual OH_NNCore_ReturnCode SetOnRunDone(OH_NNCore_OnRunDone onRunDone) = 0; + virtual OH_NNCore_ReturnCode SetOnServiceDied(OH_NNCore_OnServiceDied onServiceDied) = 0; + virtual OH_NNCore_ReturnCode SetOptions(const OH_NNCore_Options* options) = 0; + virtual OH_NNCore_ReturnCode RunSync(OH_NNCore_Tensor* inputTensors[], + size_t inputSize, + OH_NNCore_Tensor* outputTensors[], + size_t outputSize) = 0; + virtual OH_NNCore_ReturnCode RunAsync(OH_NNCore_Tensor* inputTensors[], + size_t inputSize, + OH_NNCore_Tensor* outputTensors[], + size_t outputSize, + int32_t timeout, + void* userData) = 0; + virtual OH_NNCore_ReturnCode GetBackendName(std::string& backendName) = 0; }; -} // namespace NeuralNetworkRuntime -} // namespace OHOS -#endif \ No newline at end of file +} // namespace NeuralNetworkCore +} // namespace OHOS +#endif // NEURAL_NETWORK_CORE_EXECUTOR_H diff --git a/frameworks/native/neural_network_core.cpp b/frameworks/native/neural_network_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8c4d11cba6e0a0dc1377376c2f4c56265cb1c932 --- /dev/null +++ b/frameworks/native/neural_network_core.cpp @@ -0,0 +1,1102 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "v2_0/neural_network_core.h" +#include "backend_manager.h" +#include "compiled.h" +#include "options.h" +#include "common/log.h" +#include "tensor.h" + +using namespace OHOS::NeuralNetworkCore; +#define NNRT_API __attribute__((visibility("default"))) + +struct OH_NNCore_Compilation { + void* model = nullptr; + char* offlineModelPath = nullptr; + std::pair modelCache; +}; + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_GetBackendNum(size_t* backendNum) +{ + BackendManager& manager = BackendManager::GetInstance(); + + OH_NNCore_ReturnCode ret = manager.GetBackendNum(backendNum); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("OH_NNCore_GetBackendNum failed, Get backend num failed."); + return OH_NNCORE_FAILED; + } + + return OH_NNCORE_SUCCESS; +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_GetBackendName(size_t index, const char** backendName) +{ + if (backendName == nullptr) { + LOGE("OH_NNCore_GetBackendName failed, passed nullptr to backendName"); + return OH_NNCORE_INVALID_PARAMETER; + } + + BackendManager& manager = BackendManager::GetInstance(); + + OH_NNCore_ReturnCode ret = manager.GetBackendName(index, backendName); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("OH_NNCore_GetBackendName failed, fail to get backend name."); + return OH_NNCORE_FAILED; + } + + return OH_NNCORE_SUCCESS; +} + +NNRT_API OH_NNCore_Compilation* OH_NNCore_ConstructCompilationWithNNModel(const void* model) +{ + OH_NNCore_Compilation* compilation = new (std::nothrow) OH_NNCore_Compilation(); + if (compilation == nullptr) { + LOGE("OH_NNCore_ConstructCompilationWithNNModel failed, fail to create compilation from NNModel."); + return nullptr; + } + compilation->model = const_cast(model); + return compilation; +} + +NNRT_API OH_NNCore_Compilation* OH_NNCore_ConstructCompilationWithOfflineModel(const char* filePath) +{ + OH_NNCore_Compilation* compilation = new (std::nothrow) OH_NNCore_Compilation(); + if (compilation == nullptr) { + LOGE("OH_NNCore_ConstructCompilationWithOfflineModel failed, fail to create compilation from OfflineModel."); + return nullptr; + } + compilation->offlineModelPath = const_cast(filePath); + return compilation; +} + +NNRT_API OH_NNCore_Compilation* OH_NNCore_ConstructCompilationWithOfflineBuffer(const void* modelData, const size_t modelSize) +{ + OH_NNCore_Compilation* compilation = new (std::nothrow) OH_NNCore_Compilation(); + if (compilation == nullptr) { + LOGE("OH_NNCore_ConstructCompilationWithOfflineModel failed, fail to create compilation from OfflineBuffer."); + return nullptr; + } + compilation->modelCache = std::make_pair(const_cast(modelData), modelSize); + return compilation; +} + +NNRT_API OH_NNCore_Compiled* OH_NNCore_BuildCompilation( + OH_NNCore_Compilation* compilation, const char* backendName, OH_NNCore_Options* options) +{ + if ((compilation->model == nullptr) && (compilation->offlineModelPath == nullptr) && + ((compilation->modelCache.first == nullptr) || (compilation->modelCache.second == size_t(0)))) { + LOGE("OH_NNCore_BuildCompilation failed, find no model to build compilation."); + return nullptr; + } + + if (((compilation->model != nullptr) && (compilation->offlineModelPath != nullptr)) || + ((compilation->model != nullptr) && + ((compilation->modelCache.first != nullptr) || (compilation->modelCache.second != size_t(0)))) || + ((compilation->offlineModelPath != nullptr) && + ((compilation->modelCache.first != nullptr) || (compilation->modelCache.second != size_t(0))))) { + LOGE("OH_NNCore_BuildCompilation failed, find multi model to build compilation."); + return nullptr; + } + + BackendManager& manager = BackendManager::GetInstance(); + const std::string backendNameImpl = (backendName == nullptr ? "" : backendName); + std::shared_ptr backend = manager.GetBackend(backendNameImpl); + if(backend == nullptr) { + LOGE("OH_NNCore_BuildCompilation failed, fail to get backend."); + return nullptr; + } + + Compiler* compiler = backend->CreateCompiler(); + if (compiler == nullptr) { + LOGE("OH_NNCore_BuildCompilation failed, fail to create compiler."); + return nullptr; + } + + OH_NNCore_ReturnCode ret = compiler->SetOptions(options); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("OH_NNCore_BuildCompilation failed, fail to set options."); + return nullptr; + } + + Compiled* compiled = nullptr; + if (compilation->model != nullptr) { + ret = compiler->Build(compilation->model, &compiled); + } else if (compilation->offlineModelPath != nullptr) { + ret = compiler->Build(compilation->offlineModelPath, &compiled); + } else if ((compilation->modelCache.first != nullptr) && (compilation->modelCache.second != size_t(0))) { + LOGE("OH_NNCore_BuildCompilation failed, find no model to build compilation."); + return nullptr; + } + + if (ret != OH_NNCORE_SUCCESS) { + LOGE("OH_NNCore_BuildCompilation failed, fail to build compilation."); + return nullptr; + } + + ret = backend->DestroyCompiler(compiler); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("OH_NNCore_BuildCompilation failed, fail to destory compier after build."); + backend->DestroyCompiled(compiled); + return nullptr; + } + + return reinterpret_cast(compiled); +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_DestroyCompilation(OH_NNCore_Compilation** compilation) +{ + if (compilation == nullptr) { + LOGE("OH_NNCore_DestroyCompilation failed, the compilation is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + if ((*compilation) == nullptr) { + LOGE("OH_NNCore_DestroyCompilation failed, the *compilation is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + delete (*compilation); + *compilation = nullptr; + return OH_NNCORE_SUCCESS; +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_SaveCompiledToFile(const OH_NNCore_Compiled* compiled, const char* filePath) +{ + if (compiled == nullptr) { + LOGE("OH_NNCore_CompiledSaveToFile failed, compiled is nullptr."); + return OH_NNCORE_NULL_PTR; + } + + if (filePath == nullptr) { + LOGE("OH_NNCore_CompiledSaveToFile failed, filePath is nullptr."); + return OH_NNCORE_NULL_PTR; + } + + const Compiled* compiledImpr = reinterpret_cast(compiled); + if (compiledImpr == nullptr) { + LOGE("OH_NNCore_CompiledSaveToFile failed, cast to Compiled instance failed."); + return OH_NNCORE_NULL_PTR; + } + + std::string path = filePath; + OH_NNCore_ReturnCode returnCode = compiledImpr->Save(path); + return returnCode; +} + + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_RestoreCompiledFromFile( + const char* filePath, const char* backendName, const OH_NNCore_Options* options, OH_NNCore_Compiled** compiled) +{ + if (filePath == nullptr) { + LOGE("OH_NNCore_CompiledFromFile failed, filePath is nullptr."); + return OH_NNCORE_NULL_PTR; + } + + if (backendName == nullptr) { + LOGE("OH_NNCore_CompiledFromFile failed, backendName is nullptr."); + return OH_NNCORE_NULL_PTR; + } + + BackendManager& backendManager = BackendManager::GetInstance(); + std::shared_ptr backend = backendManager.GetBackend(backendName); + if (backend == nullptr) { + LOGE("OH_NNCore_CompiledFromFile failed, passed invalid backend name %{public}s.", backendName); + return OH_NNCORE_INVALID_PARAMETER; + } + + Compiled* innerCompiled = backend->CreateCompiled(filePath, options); + if (innerCompiled == nullptr) { + LOGE("OH_NNCore_RestoreCompiledFromFile failed, failed to create compiled."); + return OH_NNCORE_INVALID_PARAMETER; + } + + *compiled = reinterpret_cast(innerCompiled); + return OH_NNCORE_SUCCESS; +} + + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_SaveCompiledToBuffer( + const OH_NNCore_Compiled* compiled, const void* buffer, size_t length, size_t* modelSize) +{ + if (compiled == nullptr) { + LOGE("OH_NNCore_CompiledSaveToBuffer failed, compiled is nullptr."); + return OH_NNCORE_NULL_PTR; + } + + if (buffer == nullptr) { + LOGE("OH_NNCore_CompiledSaveToBuffer failed, buffer is nullptr."); + return OH_NNCORE_NULL_PTR; + } + + if (length == 0) { + LOGE("OH_NNCore_CompiledSaveToBuffer failed, pass length equals to 0."); + return OH_NNCORE_INVALID_PARAMETER; + } + + if (modelSize == nullptr) { + LOGE("OH_NNCore_CompiledSaveToBuffer failed, modelSize is nullptr."); + return OH_NNCORE_NULL_PTR; + } + + const Compiled* compiledImpr = reinterpret_cast(compiled); + if (compiledImpr == nullptr) { + LOGE("OH_NNCore_CompiledSaveToBuffer failed, cast to Compiled instance failed."); + return OH_NNCORE_NULL_PTR; + } + + OH_NNCore_ReturnCode returnCode = compiledImpr->Save(buffer, length, modelSize); + return returnCode; +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_RestoreCompiledFromBuffer(const void* buffer, + size_t modelSize, + const char* backendName, + const OH_NNCore_Options* options, + OH_NNCore_Compiled** compiled) +{ + if (buffer == nullptr) { + LOGE("OH_NNCore_CompiledRestoreFromBuffer failed, buffer is nullptr."); + return OH_NNCORE_NULL_PTR; + } + + if (backendName == nullptr) { + LOGE("OH_NNCore_CompiledRestoreFromBuffer failed, backendName is nullptr."); + return OH_NNCORE_NULL_PTR; + } + + BackendManager& backendManager = BackendManager::GetInstance(); + std::shared_ptr backend = backendManager.GetBackend(backendName); + if (backend == nullptr) { + LOGE("OH_NNCore_CompiledRestoreFromBuffer failed, passed invalid backend name %{public}s.", backendName); + return OH_NNCORE_INVALID_PARAMETER; + } + + Compiled* innerCompiled = backend->CreateCompiled(buffer, modelSize, options); + if (innerCompiled == nullptr) { + LOGE("OH_NNCore_RestoreCompiledFromBuffer failed, failed to create compiled."); + return OH_NNCORE_INVALID_PARAMETER; + } + *compiled = reinterpret_cast(innerCompiled); + return OH_NNCORE_SUCCESS; +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_GetCompiledInputNum(const OH_NNCore_Compiled* compiled, size_t* inputNum) +{ + if (compiled == nullptr) { + LOGE("OH_NNCore_GetCompiledInputNum failed, compiled is nullptr."); + return OH_NNCORE_NULL_PTR; + } + + const Compiled* compiledImpr = reinterpret_cast(compiled); + if (compiledImpr == nullptr) { + LOGE("OH_NNCore_GetCompiledInputNum failed, cast to Compiled instance failed."); + return OH_NNCORE_NULL_PTR; + } + + OH_NNCore_ReturnCode returnCode = compiledImpr->GetInputCount(inputNum); + return returnCode; +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_CreateCompiledInputDesc(const OH_NNCore_Compiled* compiled, + size_t index, + OH_NNCore_TensorDesc** tensorDesc) +{ + if (compiled == nullptr) { + LOGE("OH_NNCore_CompiledGetInputDesc failed, compiled is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + if (tensorDesc == nullptr) { + LOGE("OH_NNCore_CompiledGetInputDesc failed, tensorDesc is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + if (*tensorDesc != nullptr) { + LOGE("OH_NNCore_CompiledGetInputDesc failed, *tensorDesc should be nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + const Compiled* compiledImpr = reinterpret_cast(compiled); + if (compiledImpr == nullptr) { + LOGE("OH_NNCore_CompiledGetInputDesc failed, cast to Compiled instance failed."); + return OH_NNCORE_NULL_PTR; + } + + OH_NNCore_ReturnCode returnCode = compiledImpr->GetInputDesc(index, tensorDesc); + return returnCode; +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_GetCompiledOutputNum(const OH_NNCore_Compiled* compiled, size_t* outputNum) +{ + if (compiled == nullptr) { + LOGE("OH_NNCore_GetCompiledOutputNum failed, compiled is nullptr."); + return OH_NNCORE_NULL_PTR; + } + + const Compiled* compiledImpr = reinterpret_cast(compiled); + if (compiledImpr == nullptr) { + LOGE("OH_NNCore_GetCompiledOutputNum failed, cast to Compiled instance failed."); + return OH_NNCORE_NULL_PTR; + } + + OH_NNCore_ReturnCode returnCode = compiledImpr->GetOutputCount(outputNum); + return returnCode; +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_CreateCompiledOutputDesc(const OH_NNCore_Compiled* compiled, + size_t index, + OH_NNCore_TensorDesc** tensorDesc) +{ + if (compiled == nullptr) { + LOGE("OH_NNCore_CompiledGetOutputDesc failed, compiled is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + if (tensorDesc == nullptr) { + LOGE("OH_NNCore_CompiledGetOutputDesc failed, tensorDesc is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + if (*tensorDesc != nullptr) { + LOGE("OH_NNCore_CompiledGetOutputDesc failed, *tensorDesc should be nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + const Compiled* compiledImpr = reinterpret_cast(compiled); + if (compiledImpr == nullptr) { + LOGE("OH_NNCore_CompiledGetOutputDesc failed, cast to Compiled instance failed."); + return OH_NNCORE_NULL_PTR; + } + + OH_NNCore_ReturnCode returnCode = compiledImpr->GetOutputDesc(index, tensorDesc); + return returnCode; +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_DestroyCompiled(OH_NNCore_Compiled** compiled) +{ + if (compiled == nullptr) { + LOGE("OH_NNCore_CompiledDestroy failed, compiled is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + if (*compiled == nullptr) { + LOGE("OH_NNCore_CompiledDestroy failed, *compiled is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + Compiled* compiledImpr = reinterpret_cast(*compiled); + if (compiledImpr == nullptr) { + LOGE("OH_NNCore_CompiledDestroy failed, cast to Compiled instance failed."); + return OH_NNCORE_NULL_PTR; + } + + std::string backendName; + OH_NNCore_ReturnCode returnCode = compiledImpr->GetBackendName(backendName); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("OH_NNCore_DestroyCompiled failed, passed invalid backend name %{public}s", backendName.c_str()); + return returnCode; + } + + BackendManager& backendManager = BackendManager::GetInstance(); + std::shared_ptr backend = backendManager.GetBackend(backendName); + if (backend == nullptr) { + LOGE("OH_NNCore_CompiledDestroy failed, passed invalid backend name %{public}s.", backendName.c_str()); + return OH_NNCORE_INVALID_PARAMETER; + } + + returnCode = backend->DestroyCompiled(compiledImpr); + *compiled = nullptr; + compiledImpr = nullptr; + return returnCode; +} + +NNRT_API OH_NNCore_TensorDesc* OH_NNCore_CreateTensorDesc() +{ + TensorDesc* tensorDescImpl = new (std::nothrow) TensorDesc(); + if (tensorDescImpl == nullptr) { + LOGE("OH_NNCore_CreateTensorDesc failed, failed to create tensor desc."); + return nullptr; + } + + OH_NNCore_TensorDesc* tensorDesc = reinterpret_cast(tensorDescImpl); + return tensorDesc; +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_DestroyTensorDesc(OH_NNCore_TensorDesc** tensorDesc) +{ + if (tensorDesc == nullptr) { + LOGE("OH_NNCore_DestroyTensorDesc failed, tensorDesc is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (*tensorDesc == nullptr) { + LOGE("OH_NNCore_DestroyTensorDesc failed, *tensorDesc is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + TensorDesc* tensorDescImpl = reinterpret_cast(*tensorDesc); + delete tensorDescImpl; + *tensorDesc = nullptr; + return OH_NNCORE_SUCCESS; +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_SetTensorDescName(OH_NNCore_TensorDesc* tensorDesc, const char* name) +{ + if (tensorDesc == nullptr) { + LOGE("OH_NNCore_SetTensorDescName failed, tensorDesc is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (name == nullptr) { + LOGE("OH_NNCore_SetTensorDescName failed, name is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + TensorDesc* tensorDescImpl = reinterpret_cast(tensorDesc); + return tensorDescImpl->SetName(name); +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_GetTensorDescName(const OH_NNCore_TensorDesc* tensorDesc, const char** name) +{ + if (tensorDesc == nullptr) { + LOGE("OH_NNCore_GetTensorDescName failed, tensorDesc is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (name == nullptr) { + LOGE("OH_NNCore_GetTensorDescName failed, name is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (*name != nullptr) { + LOGE("OH_NNCore_GetTensorDescName failed, *name is not nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + const TensorDesc* tensorDescImpl = reinterpret_cast(tensorDesc); + return tensorDescImpl->GetName(name); +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_SetTensorDescDataType(OH_NNCore_TensorDesc* tensorDesc, OH_NNCore_DataType dataType) +{ + if (tensorDesc == nullptr) { + LOGE("OH_NNCore_SetTensorDescDataType failed, tensorDesc is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + TensorDesc* tensorDescImpl = reinterpret_cast(tensorDesc); + return tensorDescImpl->SetDataType(dataType); +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_GetTensorDescDataType( + const OH_NNCore_TensorDesc* tensorDesc, OH_NNCore_DataType* dataType) +{ + if (tensorDesc == nullptr) { + LOGE("OH_NNCore_GetTensorDescDataType failed, tensorDesc is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (dataType == nullptr) { + LOGE("OH_NNCore_GetTensorDescDataType failed, dataType is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + const TensorDesc* tensorDescImpl = reinterpret_cast(tensorDesc); + return tensorDescImpl->GetDataType(dataType); +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_SetTensorDescShape( + OH_NNCore_TensorDesc* tensorDesc, const int32_t* shape, size_t shapeNum) +{ + if (tensorDesc == nullptr) { + LOGE("OH_NNCore_SetTensorDescShape failed, tensorDesc is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (shape == nullptr) { + LOGE("OH_NNCore_SetTensorDescShape failed, shape is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (shapeNum == 0) { + LOGE("OH_NNCore_SetTensorDescShape failed, shapeNum is 0."); + return OH_NNCORE_INVALID_PARAMETER; + } + TensorDesc* tensorDescImpl = reinterpret_cast(tensorDesc); + return tensorDescImpl->SetShape(shape, shapeNum); +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_GetTensorDescShape( + const OH_NNCore_TensorDesc* tensorDesc, int32_t** shape, size_t* shapeNum) +{ + if (tensorDesc == nullptr) { + LOGE("OH_NNCore_GetTensorDescShape failed, tensorDesc is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (shape == nullptr) { + LOGE("OH_NNCore_GetTensorDescShape failed, shape is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (*shape != nullptr) { + LOGE("OH_NNCore_GetTensorDescShape failed, *shape is not nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (shapeNum == nullptr) { + LOGE("OH_NNCore_GetTensorDescShape failed, shapeNum is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + const TensorDesc* tensorDescImpl = reinterpret_cast(tensorDesc); + return tensorDescImpl->GetShape(shape, shapeNum); +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_SetTensorDescFormat(OH_NNCore_TensorDesc* tensorDesc, OH_NNCore_Format format) +{ + if (tensorDesc == nullptr) { + LOGE("OH_NNCore_SetTensorDescFormat failed, tensorDesc is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + TensorDesc* tensorDescImpl = reinterpret_cast(tensorDesc); + return tensorDescImpl->SetFormat(format); +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_GetTensorDescFormat(const OH_NNCore_TensorDesc* tensorDesc, OH_NNCore_Format* format) +{ + if (tensorDesc == nullptr) { + LOGE("OH_NNCore_GetTensorDescFormat failed, tensorDesc is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (format == nullptr) { + LOGE("OH_NNCore_GetTensorDescFormat failed, format is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + const TensorDesc* tensorDescImpl = reinterpret_cast(tensorDesc); + return tensorDescImpl->GetFormat(format); +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_GetTensorDescElementNum(const OH_NNCore_TensorDesc* tensorDesc, size_t* elementNum) +{ + if (tensorDesc == nullptr) { + LOGE("OH_NNCore_GetTensorDescElementNum failed, tensorDesc is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (elementNum == nullptr) { + LOGE("OH_NNCore_GetTensorDescElementNum failed, elementNum is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + const TensorDesc* tensorDescImpl = reinterpret_cast(tensorDesc); + return tensorDescImpl->GetElementNum(elementNum); +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_GetTensorDescByteSize(const OH_NNCore_TensorDesc* tensorDesc, size_t* byteSize) +{ + if (tensorDesc == nullptr) { + LOGE("OH_NNCore_GetTensorDescByteSize failed, tensorDesc is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (byteSize == nullptr) { + LOGE("OH_NNCore_GetTensorDescByteSize failed, byteSize is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + const TensorDesc* tensorDescImpl = reinterpret_cast(tensorDesc); + return tensorDescImpl->GetByteSize(byteSize); +} + +NNRT_API OH_NNCore_Tensor* OH_NNCore_CreateTensor(const char* backendName, OH_NNCore_TensorDesc* desc) +{ + if (backendName == nullptr) { + LOGE("OH_NNCore_CreateTensor failed, backendName is nullptr."); + return nullptr; + } + if (desc == nullptr) { + LOGE("OH_NNCore_CreateTensor failed, desc is nullptr."); + return nullptr; + } + + BackendManager& backendManager = BackendManager::GetInstance(); + std::shared_ptr backend = backendManager.GetBackend(backendName); + if (backend == nullptr) { + LOGE("OH_NNCore_CreateTensor failed, passed invalid backend name %{public}s.", backendName); + return nullptr; + } + + TensorDesc* descImpl = reinterpret_cast(desc); + Tensor* tensorImpl = backend->CreateTensor(backendName, descImpl); + if (tensorImpl == nullptr) { + LOGE("OH_NNCore_CreateTensor failed, failed to create tensor."); + return nullptr; + } + + OH_NNCore_ReturnCode ret = tensorImpl->CreateData(); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("OH_NNCore_CreateTensor failed, failed to create tensor."); + backend->DestroyTensor(tensorImpl); + return nullptr; + } + + OH_NNCore_Tensor* tensor = reinterpret_cast(tensorImpl); + return tensor; +} + +NNRT_API OH_NNCore_Tensor* OH_NNCore_CreateTensorWithSize(const char* backendName, + OH_NNCore_TensorDesc* desc, size_t size) +{ + if (backendName == nullptr) { + LOGE("OH_NNCore_CreateTensorWithSize failed, backendName is nullptr."); + return nullptr; + } + if (desc == nullptr) { + LOGE("OH_NNCore_CreateTensorWithSize failed, desc is nullptr."); + return nullptr; + } + + BackendManager& backendManager = BackendManager::GetInstance(); + std::shared_ptr backend = backendManager.GetBackend(backendName); + if (backend == nullptr) { + LOGE("OH_NNCore_CreateTensorWithSize failed, passed invalid backend name %{public}s.", backendName); + return nullptr; + } + + TensorDesc* descImpl = reinterpret_cast(desc); + Tensor* tensorImpl = backend->CreateTensor(backendName, descImpl); + if (tensorImpl == nullptr) { + LOGE("OH_NNCore_CreateTensorWithSize failed, failed to create tensor."); + return nullptr; + } + + OH_NNCore_ReturnCode ret = tensorImpl->CreateData(size); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("OH_NNCore_CreateTensorWithSize failed, failed to create tensor."); + backend->DestroyTensor(tensorImpl); + return nullptr; + } + + OH_NNCore_Tensor* tensor = reinterpret_cast(tensorImpl); + return tensor; +} + +NNRT_API OH_NNCore_Tensor* OH_NNCore_CreateTensorWithFd(const char* backendName, + OH_NNCore_TensorDesc* desc, int fd, size_t size, size_t offset) +{ + if (backendName == nullptr) { + LOGE("OH_NNCore_CreateTensorWithFd failed, backendName is nullptr."); + return nullptr; + } + if (desc == nullptr) { + LOGE("OH_NNCore_CreateTensorWithFd failed, desc is nullptr."); + return nullptr; + } + if (fd < 0) { + LOGE("OH_NNCore_CreateTensorWithFd failed, fd is less than zero."); + return nullptr; + } + + BackendManager& backendManager = BackendManager::GetInstance(); + std::shared_ptr backend = backendManager.GetBackend(backendName); + if (backend == nullptr) { + LOGE("OH_NNCore_CreateTensorWithFd failed, passed invalid backend name %{public}s.", backendName); + return nullptr; + } + + TensorDesc* descImpl = reinterpret_cast(desc); + Tensor* tensorImpl = backend->CreateTensor(backendName, descImpl); + if (tensorImpl == nullptr) { + LOGE("OH_NNCore_CreateTensorWithFd failed, failed to create tensor."); + return nullptr; + } + + OH_NNCore_ReturnCode ret = tensorImpl->CreateData(fd, size, offset); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("OH_NNCore_CreateTensorWithFd failed, failed to create tensor."); + backend->DestroyTensor(tensorImpl); + return nullptr; + } + + OH_NNCore_Tensor* tensor = reinterpret_cast(tensorImpl); + return tensor; +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_DestroyTensor(OH_NNCore_Tensor** tensor) +{ + if (tensor == nullptr) { + LOGE("OH_NNCore_DestroyTensor failed, tensor is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (*tensor == nullptr) { + LOGE("OH_NNCore_DestroyTensor failed, *tensor is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + Tensor* tensorImpl = reinterpret_cast(*tensor); + std::string backendName; + auto ret = tensorImpl->GetBackendName(backendName); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("OH_NNCore_DestroyTensor failed, failed to get backend name."); + return ret; + } + + BackendManager& backendManager = BackendManager::GetInstance(); + std::shared_ptr backend = backendManager.GetBackend(backendName); + if (backend == nullptr) { + LOGE("OH_NNCore_DestroyTensor failed, passed invalid backend name %{public}s.", backendName.c_str()); + return OH_NNCORE_NULL_PTR; + } + + ret = backend->DestroyTensor(tensorImpl); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("OH_NNCore_DestroyTensor failed, failed to destroy tensor."); + return ret; + } + *tensor = nullptr; + return OH_NNCORE_SUCCESS; +} + +NNRT_API OH_NNCore_TensorDesc* OH_NNCore_GetTensorDesc(const OH_NNCore_Tensor* tensor) +{ + if (tensor == nullptr) { + LOGE("OH_NNCore_GetTensorDesc failed, tensor is nullptr."); + return nullptr; + } + + const Tensor* tensorImpl = reinterpret_cast(tensor); + auto tensorDescImpl = tensorImpl->GetTensorDesc(); + if (tensorDescImpl == nullptr) { + LOGE("OH_NNCore_GetTensorDesc failed, tensor desc is nullptr."); + return nullptr; + } + + OH_NNCore_TensorDesc* tensorDesc = reinterpret_cast(tensorDescImpl); + return tensorDesc; +} + +NNRT_API void* OH_NNCore_GetDataBuffer(const OH_NNCore_Tensor* tensor) +{ + if (tensor == nullptr) { + LOGE("OH_NNCore_GetData failed, tensor is nullptr."); + return nullptr; + } + + const Tensor* tensorImpl = reinterpret_cast(tensor); + auto data = tensorImpl->GetData(); + if (data == nullptr) { + LOGE("OH_NNCore_GetData failed, data is nullptr."); + return nullptr; + } + + return data; +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_GetSize(const OH_NNCore_Tensor* tensor, size_t* size) +{ + if (tensor == nullptr) { + LOGE("OH_NNCore_GetSize failed, tensor is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (size == nullptr) { + LOGE("OH_NNCore_GetSize failed, size is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + const Tensor* tensorImpl = reinterpret_cast(tensor); + *size = tensorImpl->GetSize(); + return OH_NNCORE_SUCCESS; +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_GetFd(const OH_NNCore_Tensor* tensor, int* fd) +{ + if (tensor == nullptr) { + LOGE("OH_NNCore_GetFd failed, tensor is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (fd == nullptr) { + LOGE("OH_NNCore_GetFd failed, fd is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + const Tensor* tensorImpl = reinterpret_cast(tensor); + *fd = tensorImpl->GetFd(); + return OH_NNCORE_SUCCESS; +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_GetOffset(const OH_NNCore_Tensor* tensor, size_t* offset) +{ + if (tensor == nullptr) { + LOGE("OH_NNCore_GetOffset failed, tensor is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (offset == nullptr) { + LOGE("OH_NNCore_GetOffset failed, offset is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + const Tensor* tensorImpl = reinterpret_cast(tensor); + *offset = tensorImpl->GetOffset(); + return OH_NNCORE_SUCCESS; +} + +// Executor APIs +NNRT_API OH_NNCore_Executor* OH_NNCore_ConstructExecutor(const OH_NNCore_Compiled* compiled) +{ + if (compiled == nullptr) { + LOGE("OH_NNCore_ConstructExecutor failed, compiled is nullptr."); + return nullptr; + } + + const Compiled* compiledImpl = reinterpret_cast(compiled); + OH_NNCore_Executor* executor = nullptr; + OH_NNCore_ReturnCode returnCode = compiledImpl->CreateExecutor(&executor); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("OH_NNCore_ConstructExecutor failed, failed to create executor."); + return nullptr; + } + return executor; +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_DestroyExecutor(OH_NNCore_Executor** executor) +{ + if (executor == nullptr) { + LOGE("OH_NNCore_DestroyExecutor failed, executor is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (*executor == nullptr) { + LOGE("OH_NNCore_DestroyExecutor failed, *executor is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + Executor* executorImpl = reinterpret_cast(*executor); + std::string backendName; + OH_NNCore_ReturnCode returnCode = executorImpl->GetBackendName(backendName); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("OH_NNCore_DestroyExecutor failed, failed to get backend name from tensorDesc."); + return returnCode; + } + + BackendManager& backendManager = BackendManager::GetInstance(); + std::shared_ptr backend = backendManager.GetBackend(backendName); + if (backend == nullptr) { + LOGE("OH_NNCore_DestroyExecutor failed, failed to get backend of %{public}s.", backendName.c_str()); + return OH_NNCORE_NULL_PTR; + } + returnCode = backend->DestroyExecutor(executorImpl); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("OH_NNCore_DestroyExecutor failed, failed to destroy executor."); + return returnCode; + } + *executor = nullptr; + return OH_NNCORE_SUCCESS; +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_SetExecutorOnRunDone(OH_NNCore_Executor* executor, OH_NNCore_OnRunDone onRunDone) +{ + if (executor == nullptr) { + LOGE("OH_NNCore_SetExecutorOnRunDone failed, executor is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (onRunDone == nullptr) { + LOGE("OH_NNCore_SetExecutorOnRunDone failed, onRunDone is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + Executor* executorImpl = reinterpret_cast(executor); + return executorImpl->SetOnRunDone(onRunDone); +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_SetExecutorOnServiceDied( + OH_NNCore_Executor* executor, OH_NNCore_OnServiceDied onServiceDied) +{ + if (executor == nullptr) { + LOGE("OH_NNCore_SetExecutorOnServiceDied failed, executor is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (onServiceDied == nullptr) { + LOGE("OH_NNCore_SetExecutorOnServiceDied failed, onServiceDied is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + Executor* executorImpl = reinterpret_cast(executor); + return executorImpl->SetOnServiceDied(onServiceDied); +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_ExecutorRunSync(OH_NNCore_Executor* executor, OH_NNCore_Tensor* inputTensor[], + size_t inputNum, OH_NNCore_Tensor* outputTensor[], size_t outputNum) +{ + if (executor == nullptr) { + LOGE("OH_NNCore_ExecutorRunSync failed, executor is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (inputTensor == nullptr) { + LOGE("OH_NNCore_ExecutorRunSync failed, inputTensor is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (inputNum == 0) { + LOGE("OH_NNCore_ExecutorRunSync failed, inputNum is 0."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (outputTensor == nullptr) { + LOGE("OH_NNCore_ExecutorRunSync failed, outputTensor is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (outputNum == 0) { + LOGE("OH_NNCore_ExecutorRunSync failed, outputNum is 0."); + return OH_NNCORE_INVALID_PARAMETER; + } + + Executor* executorImpl = reinterpret_cast(executor); + return executorImpl->RunSync(inputTensor, inputNum, outputTensor, outputNum); +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_ExecutorRunAsync(OH_NNCore_Executor* executor, OH_NNCore_Tensor* inputTensor[], + size_t inputNum, OH_NNCore_Tensor* outputTensor[], size_t outputNum, int32_t timeout, void* userData) +{ + if (executor == nullptr) { + LOGE("OH_NNCore_ExecutorRunAsync failed, executor is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (inputTensor == nullptr) { + LOGE("OH_NNCore_ExecutorRunAsync failed, inputTensor is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (inputNum == 0) { + LOGE("OH_NNCore_ExecutorRunAsync failed, inputNum is 0."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (outputTensor == nullptr) { + LOGE("OH_NNCore_ExecutorRunAsync failed, outputTensor is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (outputNum == 0) { + LOGE("OH_NNCore_ExecutorRunAsync failed, outputNum is 0."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (userData == 0) { + LOGE("OH_NNCore_ExecutorRunAsync failed, userData is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + Executor* executorImpl = reinterpret_cast(executor); + return executorImpl->RunAsync(inputTensor, inputNum, outputTensor, outputNum, timeout, userData); +} + +NNRT_API OH_NNCore_Options* OH_NNCore_CreateOptions(const char* backendName) +{ + if (backendName == nullptr) { + LOGE("OH_NNCore_CreateOptions failed, backendName is nullptr."); + return nullptr; + } + + BackendManager& manager = BackendManager::GetInstance(); + std::shared_ptr backend = manager.GetBackend(backendName); + if (backend == nullptr) { + LOGE("OH_NNCore_CreateOptions failed, fail to get backend."); + return nullptr; + } + + Options* innerOptions = backend->CreateOptions(); + if (innerOptions == nullptr) { + LOGE("OH_NNCore_CreateOptions failed, fail to create options."); + return nullptr; + } + + OH_NNCore_Options* options = reinterpret_cast(innerOptions); + return options; +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_DestroyOptions(OH_NNCore_Options** options) +{ + if (options == nullptr) { + LOGE("OH_NNCore_DestroyOptions failed, options is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (*options == nullptr) { + LOGE("OH_NNCore_DestroyOptions failed, *options is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + Options* optionsImpl = reinterpret_cast(*options); + + std::string backendName; + OH_NNCore_ReturnCode returnCode = optionsImpl->GetBackendName(backendName); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("OH_NNCore_DestroyOptions failed, failed to get backend name from options."); + return returnCode; + } + + BackendManager& backendManager = BackendManager::GetInstance(); + std::shared_ptr backend = backendManager.GetBackend(backendName); + if (backend == nullptr) { + LOGE("OH_NNCore_DestroyOptions failed, failed to get backend of %s.", backendName.c_str()); + return OH_NNCORE_NULL_PTR; + } + + returnCode = backend->DestroyOptions(optionsImpl); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("OH_NNCore_DestroyOptions failed, failed to destroy options."); + return returnCode; + } + + *options = nullptr; + return OH_NNCORE_SUCCESS; +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_SetPriority(OH_NNCore_Options* options, OH_NNCore_Priority priority) +{ + if (options == nullptr) { + LOGE("OH_NNCore_SetPriority failed, input options is nullptr;"); + return OH_NNCORE_INVALID_PARAMETER; + } + + Options* optionsImpl = reinterpret_cast(options); + OH_NNCore_ReturnCode returnCode = optionsImpl->SetPriority(priority); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("OH_NNCore_SetPriority failed, failed to set priority."); + return returnCode; + } + + return OH_NNCORE_SUCCESS; +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_SetPerformanceMode(OH_NNCore_Options* options, OH_NNCore_PerformanceMode performanceMode) +{ + if (options == nullptr) { + LOGE("OH_NNCore_SetPerformanceMode failed, input options is nullptr;"); + return OH_NNCORE_INVALID_PARAMETER; + } + + Options* optionsImpl = reinterpret_cast(options); + OH_NNCore_ReturnCode returnCode = optionsImpl->SetPerformanceMode(performanceMode); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("OH_NNCore_SetPerformanceMode failed, failed to set performance mode."); + return returnCode; + } + + return OH_NNCORE_SUCCESS; +} + +NNRT_API OH_NNCore_ReturnCode OH_NNCore_SetEnableFloat16(OH_NNCore_Options* options, bool enableFloat16) +{ + if (options == nullptr) { + LOGE("OH_NNCore_SetEnableFloat16 failed, input options is nullptr;"); + return OH_NNCORE_INVALID_PARAMETER; + } + + Options* optionsImpl = reinterpret_cast(options); + OH_NNCore_ReturnCode returnCode = optionsImpl->SetEnableFp16(enableFloat16); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("OH_NNCore_SetEnableFloat16 failed, failed to set fp16 enabled."); + return returnCode; + } + + return OH_NNCORE_SUCCESS; +} diff --git a/frameworks/native/neural_network_runtime.cpp b/frameworks/native/neural_network_runtime.cpp index f492754217c0ba477be721f78e6415dbc0f97a43..7ed7c59e3f2bb642d7905c2d45ff312e61b8b5e5 100644 --- a/frameworks/native/neural_network_runtime.cpp +++ b/frameworks/native/neural_network_runtime.cpp @@ -13,721 +13,388 @@ * limitations under the License. */ -#include "interfaces/innerkits/c/neural_network_runtime_inner.h" -#include "interfaces/kits/c/neural_network_runtime.h" +#include "v2_0/neural_network_runtime.h" -#include "compilation.h" -#include "device_manager.h" -#include "executor.h" -#include "inner_model.h" #include "common/log.h" +#include "compat/transform.h" +#include "compat/inner_model.h" +#include "nnexecutor.h" +#include "nntensor.h" +#include "neural_network_runtime.h" +#include "nnoptions.h" +#include "nncompiled.h" +#include "nn_validation.h" +#include "quant_param.h" +#include "validation.h" +using namespace OHOS::NeuralNetworkBackend; +using namespace OHOS::NeuralNetworkCore; -using namespace OHOS::NeuralNetworkRuntime; +using NNOperand = OH_NN_Tensor; -#define NNRT_API __attribute__((visibility("default"))) -NNRT_API OH_NNModel *OH_NNModel_Construct(void) +OH_NNBackend_QuantParam* OH_NNBackend_CreateQuantParam(void) { - InnerModel *innerModel = new(std::nothrow) InnerModel(); - if (innerModel == nullptr) { - LOGE("OH_NNModel_Construct failed, please check whether it has enough memory."); + auto* quantParamImpl = new (std::nothrow) OHOS::NeuralNetworkBackend::QuantParam(); + if (quantParamImpl == nullptr) { + LOGE("OH_NNBackend_CreateQuantParam failed, please check whether it has enough memory."); return nullptr; } - OH_NNModel *nnModel = reinterpret_cast(innerModel); - return nnModel; + return (OH_NNBackend_QuantParam*)(quantParamImpl); } -NNRT_API OH_NN_ReturnCode OH_NNModel_AddTensor(OH_NNModel *model, const OH_NN_Tensor *tensor) +OH_NNCore_ReturnCode OH_NNBackend_DestroyQuantParam(OH_NNBackend_QuantParam** quantParam) { - if (model == nullptr) { - LOGE("OH_NNModel_AddTensor failed, passed nullptr to model."); - return OH_NN_INVALID_PARAMETER; + if (quantParam == nullptr) { + LOGE("OH_NNBackend_DestroyQuantParam failed, passed nullptr to quantParam."); + return OH_NNCORE_INVALID_PARAMETER; } - if (tensor == nullptr) { - LOGE("OH_NNModel_AddTensor failed, passed nullptr to tensor."); - return OH_NN_INVALID_PARAMETER; + if (*quantParam == nullptr) { + LOGW("OH_NNBackend_DestroyQuantParam failed, passed nullptr to *quantParam."); + return OH_NNCORE_INVALID_PARAMETER; } - InnerModel *innerModel = reinterpret_cast(model); - return innerModel->AddTensor(*tensor); -} - -NNRT_API 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) -{ - if (model == nullptr) { - LOGE("OH_NNModel_AddOperation failed, passed nullptr to model."); - return OH_NN_INVALID_PARAMETER; - } - - if (paramIndices == nullptr) { - LOGE("OH_NNModel_AddOperation failed, passed nullptr to paramIndices."); - return OH_NN_INVALID_PARAMETER; - } - - if (inputIndices == nullptr) { - LOGE("OH_NNModel_AddOperation failed, passed nullptr to inputIndices."); - return OH_NN_INVALID_PARAMETER; - } + auto* quantParamImpl = reinterpret_cast(*quantParam); + delete quantParamImpl; + *quantParam = nullptr; - if (outputIndices == nullptr) { - LOGE("OH_NNModel_AddOperation failed, passed nullptr to outputIndices."); - return OH_NN_INVALID_PARAMETER; - } - - InnerModel *innerModel = reinterpret_cast(model); - return innerModel->AddOperation(op, *paramIndices, *inputIndices, *outputIndices); + return OH_NNCORE_SUCCESS; } -NNRT_API OH_NN_ReturnCode OH_NNModel_SetTensorData(OH_NNModel *model, - uint32_t index, - const void *dataBuffer, - size_t length) +OH_NNCore_ReturnCode OH_NNBackend_SetQuantParamScales(OH_NNBackend_QuantParam* quantParam, + const double* scales, + size_t quantNum) { - if (model == nullptr) { - LOGE("OH_NNModel_SetTensorData failed, passed nullptr to model."); - return OH_NN_INVALID_PARAMETER; - } - - if (dataBuffer == nullptr) { - LOGE("OH_NNModel_SetTensorData failed, passed nullptr to dataBuffer, which has no effect."); - return OH_NN_INVALID_PARAMETER; - } - - if (length == 0) { - LOGE("OH_NNModel_SetTensorData failed, passed dataBuffer with length 0, which has no effect."); - return OH_NN_INVALID_PARAMETER; + if (quantParam == nullptr) { + LOGE("OH_NNBackend_SetQuantParamScales failed, passed nullptr to quantParam."); + return OH_NNCORE_INVALID_PARAMETER; } - InnerModel *innerModel = reinterpret_cast(model); - return innerModel->SetTensorValue(index, dataBuffer, length); -} - -NNRT_API OH_NN_ReturnCode OH_NNModel_SpecifyInputsAndOutputs(OH_NNModel *model, - const OH_NN_UInt32Array *inputIndices, - const OH_NN_UInt32Array *outputIndices) -{ - if (model == nullptr) { - LOGE("OH_NNModel_SpecifyInputsAndOutputs failed, passed nullptr to model."); - return OH_NN_INVALID_PARAMETER; + if (scales == nullptr) { + LOGE("OH_NNBackend_SetQuantParamScales failed, passed nullptr to scales."); + return OH_NNCORE_INVALID_PARAMETER; } - if (inputIndices == nullptr) { - LOGE("OH_NNModel_SpecifyInputsAndOutputs failed, passed nullptr to inputIndices."); - return OH_NN_INVALID_PARAMETER; + if (quantNum == 0) { + LOGE("OH_NNBackend_SetQuantParamScales failed, passed 0 to quantNum."); + return OH_NNCORE_INVALID_PARAMETER; } - if (outputIndices == nullptr) { - LOGE("OH_NNModel_SpecifyInputsAndOutputs failed, passed nullptr to outputIndices."); - return OH_NN_INVALID_PARAMETER; - } + auto* quantParamImpl = reinterpret_cast(quantParam); + std::vector scaleVector(scales, scales + quantNum); + quantParamImpl->SetScales(scaleVector); - InnerModel *innerModel = reinterpret_cast(model); - return innerModel->SpecifyInputsAndOutputs(*inputIndices, *outputIndices); + return OH_NNCORE_SUCCESS; } -NNRT_API OH_NN_ReturnCode OH_NNModel_Finish(OH_NNModel *model) +OH_NNCore_ReturnCode OH_NNBackend_SetQuantParamZeroPoints(OH_NNBackend_QuantParam* quantParam, + const int32_t* zeroPoints, + size_t quantNum) { - if (model == nullptr) { - LOGE("OH_NNModel_Finish failed, passed nullptr to model."); - return OH_NN_INVALID_PARAMETER; + if (quantParam == nullptr) { + LOGE("OH_NNBackend_SetQuantParamZeroPoints failed, passed nullptr to quantParam."); + return OH_NNCORE_INVALID_PARAMETER; } - InnerModel *innerModel = reinterpret_cast(model); - return innerModel->Build(); -} - -NNRT_API OH_NN_ReturnCode OH_NNModel_BuildFromLiteGraph(OH_NNModel *model, const void *liteGraph) -{ - if (model == nullptr) { - LOGE("OH_NNModel_BuildFromLiteGraph failed, passed nullptr to model."); - return OH_NN_INVALID_PARAMETER; + if (zeroPoints == nullptr) { + LOGE("OH_NNBackend_SetQuantParamZeroPoints failed, passed nullptr to zeroPoints."); + return OH_NNCORE_INVALID_PARAMETER; } - if (liteGraph == nullptr) { - LOGE("OH_NNModel_BuildFromLiteGraph failed, passed nullptr to liteGraph."); - return OH_NN_INVALID_PARAMETER; + if (quantNum == 0) { + LOGE("OH_NNBackend_SetQuantParamZeroPoints failed, passed 0 to quantNum."); + return OH_NNCORE_INVALID_PARAMETER; } - auto *pLiteGraph = static_cast(liteGraph); - InnerModel *innerModel = reinterpret_cast(model); + auto* quantParamImpl = reinterpret_cast(quantParam); + std::vector zeroPointVector(zeroPoints, zeroPoints + quantNum); + quantParamImpl->SetZeroPoints(zeroPointVector); - // Once the innerModel built from the liteGraph successfully, the innerModel - // owns the liteGraph, in which case, the invoker should not delete - // the liteGraph actively. Otherwise, the invoker still has the ownership. - return innerModel->BuildFromLiteGraph(pLiteGraph); + return OH_NNCORE_SUCCESS; } -NNRT_API OH_NN_ReturnCode OH_NNModel_BuildFromMetaGraph(OH_NNModel *model, const void *metaGraph, - const OH_NN_Extension *extensions, size_t extensionSize) +OH_NNCore_ReturnCode OH_NNBackend_SetQuantParamNumBits(OH_NNBackend_QuantParam* quantParam, + const uint32_t* numBits, + size_t quantNum) { - if (model == nullptr) { - LOGE("OH_NNModel_BuildFromMetaGraph failed, passed nullptr to model."); - return OH_NN_INVALID_PARAMETER; + if (quantParam == nullptr) { + LOGE("OH_NNBackend_SetQuantParamNumBits failed, passed nullptr to quantParam."); + return OH_NNCORE_INVALID_PARAMETER; } - if (metaGraph == nullptr) { - LOGE("OH_NNModel_BuildFromMetaGraph failed, passed nullptr to metaGraph."); - return OH_NN_INVALID_PARAMETER; + if (numBits == nullptr) { + LOGE("OH_NNBackend_SetQuantParamNumBits failed, passed nullptr to numBits."); + return OH_NNCORE_INVALID_PARAMETER; } - Buffer buffer; - std::string modelName; - for (size_t i = 0; i < extensionSize; ++i) { - std::string name = extensions[i].name; - if (name == "QuantBuffer") { - buffer.data = extensions[i].value; - buffer.length = extensions[i].valueSize; - } else if (name == "ModelName") { - modelName.assign(extensions[i].value, extensions[i].value + extensions[i].valueSize); - } + if (quantNum == 0) { + LOGE("OH_NNBackend_SetQuantParamNumBits failed, passed 0 to quantNum."); + return OH_NNCORE_INVALID_PARAMETER; } - InnerModel *innerModel = reinterpret_cast(model); - return innerModel->BuildFromMetaGraph(metaGraph, buffer, modelName); -} + auto* quantParamImpl = reinterpret_cast(quantParam); + std::vector numBitVector(numBits, numBits + quantNum); + quantParamImpl->SetNumBits(numBitVector); -NNRT_API OH_NN_ReturnCode OH_NNModel_SetInputsAndOutputsInfo(OH_NNModel *model, const OH_NN_TensorInfo *inputsInfo, - size_t inputSize, const OH_NN_TensorInfo *outputsInfo, size_t outputSize) -{ - if (model == nullptr) { - LOGE("OH_NNModel_SetInputsAndOutputsInfo failed, passed nullptr to model."); - return OH_NN_INVALID_PARAMETER; - } - - if ((inputsInfo == nullptr) || (inputSize == 0)) { - LOGE("OH_NNModel_SetInputsAndOutputsInfo failed, inputsInfo is empty."); - return OH_NN_INVALID_PARAMETER; - } - - if ((outputsInfo == nullptr) || (outputSize == 0)) { - LOGE("OH_NNModel_SetInputsAndOutputsInfo failed, outputsInfo is empty."); - return OH_NN_INVALID_PARAMETER; - } - - InnerModel *innerModel = reinterpret_cast(model); - return innerModel->SetInputsAndOutputsInfo(inputsInfo, inputSize, outputsInfo, outputSize); + return OH_NNCORE_SUCCESS; } -NNRT_API void OH_NNModel_Destroy(OH_NNModel **model) +OH_NNBackend_Model* OH_NNBackend_CreateModel(void) { - if (model == nullptr) { - LOGW("OH_NNModel_Destroy has no effect, passed nullptr to model."); - return; - } - - if (*model == nullptr) { - LOGW("OH_NNModel_Destroy has no effect, passed nullptr to *model."); - return; + auto* innerModel = new (std::nothrow) OHOS::NeuralNetworkRuntime::InnerModel(); + if (innerModel == nullptr) { + LOGE("OH_NNbackend_ConstructModel failed, please check whether it has enough memory."); + return nullptr; } - InnerModel *innerModel = reinterpret_cast(*model); - delete innerModel; - *model = nullptr; + return (OH_NNBackend_Model*)(innerModel); } -NNRT_API OH_NN_ReturnCode OH_NNModel_GetAvailableOperations(OH_NNModel *model, - size_t deviceID, - const bool **isAvailable, - uint32_t *opCount) +OH_NNCore_ReturnCode OH_NNBackend_AddTensorToModel(OH_NNBackend_Model* model, const OH_NNCore_TensorDesc* tensorDesc) { if (model == nullptr) { - LOGE("OH_NNModel_GetAvailableOperations failed, passed nullptr to model."); - return OH_NN_INVALID_PARAMETER; + LOGE("OH_NNBackend_AddTensorToModel failed, passed nullptr to model."); + return OH_NNCORE_INVALID_PARAMETER; } - if (isAvailable == nullptr) { - LOGE("OH_NNModel_GetAvailableOperations failed, passed nullptr to isAvailable."); - return OH_NN_INVALID_PARAMETER; + if (tensorDesc == nullptr) { + LOGE("OH_NNBackend_AddTensorToModel failed, passed nullptr to tensorDesc."); + return OH_NNCORE_INVALID_PARAMETER; } - if (*isAvailable != nullptr) { - LOGE("OH_NNModel_GetAvailableOperations failed, *isAvailable is not nullptr."); - return OH_NN_INVALID_PARAMETER; + auto* innerModel = reinterpret_cast(model); + if (innerModel == nullptr) { + LOGE("OH_NNBackend_AddTensorToModel failed, error happened when converting model."); + return OH_NNCORE_FAILED; } - if (opCount == nullptr) { - LOGE("OH_NNModel_GetAvailableOperations failed, passed nullptr to opCount."); - return OH_NN_INVALID_PARAMETER; + OH_NNCore_ReturnCode returnCode = innerModel->AddTensorDesc(tensorDesc); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("OH_NNBackend_AddTensorToModel failed, error happened when adding tensor to model."); } - InnerModel *innerModel = reinterpret_cast(model); - return innerModel->GetSupportedOperations(deviceID, isAvailable, *opCount); + return returnCode; } -NNRT_API OH_NNCompilation *OH_NNCompilation_Construct(const OH_NNModel *model) +OH_NNCore_ReturnCode OH_NNBackend_SpecifyModelInputsAndOutputs(OH_NNBackend_Model* model, + const OH_NNBackend_Array* inputIndices, + const OH_NNBackend_Array* outputIndices) { if (model == nullptr) { - LOGE("OH_NNCompilation_Construct failed, passed nullptr to model."); - return nullptr; - } - const InnerModel *innerModel = reinterpret_cast(model); - - if (!innerModel->IsBuild()) { - LOGE("OH_NNCompilation_Construct failed, should call OH_NNModel_Finish before creating compilation."); - return nullptr; - } - - Compilation *compilation = new(std::nothrow) Compilation(innerModel); - if (compilation == nullptr) { - LOGE("OH_NNCompilation_Construct failed, please check whether it has enough memory."); - return nullptr; - } - - OH_NNCompilation* nnCompilation = reinterpret_cast(compilation); - return nnCompilation; -} - -NNRT_API OH_NN_ReturnCode OH_NNCompilation_SetDevice(OH_NNCompilation *compilation, size_t deviceID) -{ - if (compilation == nullptr) { - LOGE("OH_NNCompilation_SetDevice failed, passed nullptr to compilation."); - return OH_NN_INVALID_PARAMETER; - } - - Compilation* innerCompilation = reinterpret_cast(compilation); - return innerCompilation->SetDevice(deviceID); -} - -NNRT_API OH_NN_ReturnCode OH_NNCompilation_SetCache(OH_NNCompilation *compilation, - const char *cachePath, - uint32_t version) -{ - if (compilation == nullptr) { - LOGE("OH_NNCompilation_SetCache failed, passed nullptr to compilation."); - return OH_NN_INVALID_PARAMETER; - } - - if (cachePath == nullptr) { - LOGE("OH_NNCompilation_SetCache failed, passed nullptr to cachePath."); - return OH_NN_INVALID_PARAMETER; - } - - Compilation* innerCompilation = reinterpret_cast(compilation); - return innerCompilation->SetCacheDir(cachePath, version); -} - -NNRT_API OH_NN_ReturnCode OH_NNCompilation_SetPerformanceMode(OH_NNCompilation *compilation, - OH_NN_PerformanceMode performanceMode) -{ - if (compilation == nullptr) { - LOGE("OH_NNCompilation_SetPerformanceMode failed, passed nullptr to compilation."); - return OH_NN_INVALID_PARAMETER; - } - - Compilation* innerCompilation = reinterpret_cast(compilation); - return innerCompilation->SetPerformance(performanceMode); -} - -NNRT_API OH_NN_ReturnCode OH_NNCompilation_SetPriority(OH_NNCompilation *compilation, - OH_NN_Priority priority) -{ - if (compilation == nullptr) { - LOGE("OH_NNCompilation_SetPriority failed, passed nullptr to compilation."); - return OH_NN_INVALID_PARAMETER; - } - - Compilation* innerCompilation = reinterpret_cast(compilation); - return innerCompilation->SetPriority(priority); -} - -NNRT_API OH_NN_ReturnCode OH_NNCompilation_EnableFloat16(OH_NNCompilation *compilation, bool enableFloat16) -{ - if (compilation == nullptr) { - LOGE("OH_NNCompilation_EnableFloat16 failed, passed nullptr to compilation."); - return OH_NN_INVALID_PARAMETER; - } - - Compilation* innerCompilation = reinterpret_cast(compilation); - return innerCompilation->SetEnableFp16(enableFloat16); -} - -NNRT_API OH_NN_ReturnCode OH_NNCompilation_Build(OH_NNCompilation *compilation) -{ - if (compilation == nullptr) { - LOGE("OH_NNCompilation_Build failed, passed nullptr to compilation."); - return OH_NN_INVALID_PARAMETER; - } - - Compilation* innerCompilation = reinterpret_cast(compilation); - return innerCompilation->Build(); -} - -NNRT_API void OH_NNCompilation_Destroy(OH_NNCompilation **compilation) -{ - if (compilation == nullptr) { - LOGW("OH_NNCompilation_Destroy has no effect, passed nullptr to compilation."); - return; + LOGE("OH_NNBackend_SpecifyModelInputsAndOutputs failed, passed nullptr to model."); + return OH_NNCORE_INVALID_PARAMETER; } - if (*compilation == nullptr) { - LOGW("OH_NNCompilation_Destroy has no effect, passed nullptr to *compilation."); - return; - } - - Compilation *innerCompilation = reinterpret_cast(*compilation); - delete innerCompilation; - *compilation = nullptr; -} - -NNRT_API OH_NNExecutor *OH_NNExecutor_Construct(OH_NNCompilation *compilation) -{ - if (compilation == nullptr) { - LOGE("OH_NNExecutor_Construct failed, passed nullptr to compilation."); - return nullptr; + if (inputIndices == nullptr) { + LOGE("OH_NNBackend_SpecifyModelInputsAndOutputs failed, passed nullptr to inputIndices."); + return OH_NNCORE_INVALID_PARAMETER; } - Compilation *innerCompilation = reinterpret_cast(compilation); - if (!innerCompilation->IsBuild()) { - LOGE("OH_NNExecutor_Construct failed, should call OH_NNCompilation_Build before creating executor."); - return nullptr; + if (outputIndices == nullptr) { + LOGE("OH_NNBackend_SpecifyModelInputsAndOutputs failed, passed nullptr to outputIndices."); + return OH_NNCORE_INVALID_PARAMETER; } - Executor* executor = new(std::nothrow) Executor(innerCompilation); - if (executor == nullptr) { - LOGE("OH_NNExecutor_Construct failed, please check whether it has enough memory."); - return nullptr; + auto* innerModel = reinterpret_cast(model); + OH_NNCore_ReturnCode returnCode = innerModel->SpecifyInputsAndOutputs(*inputIndices, *outputIndices); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("OH_NNBackend_SpecifyModelInputsAndOutputs failed, error happened when specifying model inputs and outputs."); } - OH_NNExecutor* nnExecutor = reinterpret_cast(executor); - return nnExecutor; + return returnCode; } -NNRT_API OH_NN_ReturnCode OH_NNExecutor_SetInput(OH_NNExecutor *executor, - uint32_t inputIndex, - const OH_NN_Tensor *tensor, - const void *dataBuffer, - size_t length) +OH_NNCore_ReturnCode OH_NNBackend_BuildModel(OH_NNBackend_Model* model) { - if (executor == nullptr) { - LOGE("OH_NNExecutor_SetInput failed, passed nullptr to executor."); - return OH_NN_INVALID_PARAMETER; - } - - if (tensor == nullptr) { - LOGE("OH_NNExecutor_SetInput failed, passed nullptr to tensor."); - return OH_NN_INVALID_PARAMETER; - } - - if (dataBuffer == nullptr) { - LOGE("OH_NNExecutor_SetInput failed, passed nullptr to dataBuffer."); - return OH_NN_INVALID_PARAMETER; - } - - if (length == 0) { - LOGE("OH_NNExecutor_SetInput failed, dataBuffer length is 0."); - return OH_NN_INVALID_PARAMETER; + if (model == nullptr) { + LOGE("OH_NNBackend_BuildModel failed, passed nullptr to model."); + return OH_NNCORE_INVALID_PARAMETER; } - Executor* innerExecutor = reinterpret_cast(executor); - return innerExecutor->SetInput(inputIndex, *tensor, dataBuffer, length); + auto* innerModel = reinterpret_cast(model); + OH_NN_ReturnCode returnCode = innerModel->Build(); + return OHOS::NeuralNetworkBackend::BackendToCore::ConvertReturnCode(returnCode); } -NNRT_API OH_NN_ReturnCode OH_NNExecutor_SetOutput(OH_NNExecutor *executor, - uint32_t outputIndex, - void *dataBuffer, - size_t length) +OH_NNCore_ReturnCode OH_NNBackend_SetModelTensorData(OH_NNBackend_Model* model, + size_t index, + const void* dataBuffer, + size_t length) { - if (executor == nullptr) { - LOGE("OH_NNExecutor_SetOutput failed, passed nullptr to executor."); - return OH_NN_INVALID_PARAMETER; + if (model == nullptr) { + LOGE("OH_NNBackend_SetModelTensorData failed, passed nullptr to model."); + return OH_NNCORE_INVALID_PARAMETER; } if (dataBuffer == nullptr) { - LOGE("OH_NNExecutor_SetOutput failed, passed nullptr to dataBuffer."); - return OH_NN_INVALID_PARAMETER; + LOGE("OH_NNBackend_SetModelTensorData failed, passed nullptr to dataBuffer."); + return OH_NNCORE_INVALID_PARAMETER; } if (length == 0) { - LOGE("OH_NNExecutor_SetOutput failed, dataBuffer length is 0."); - return OH_NN_INVALID_PARAMETER; - } - - Executor* innerExecutor = reinterpret_cast(executor); - return innerExecutor->SetOutput(outputIndex, dataBuffer, length); -} - -NNRT_API OH_NN_ReturnCode OH_NNExecutor_GetOutputShape(OH_NNExecutor *executor, - uint32_t outputIndex, - int32_t **shape, - uint32_t *shapeLength) -{ - if (executor == nullptr) { - LOGE("OH_NNExecutor_GetOutputShape failed, passed nullptr to executor."); - return OH_NN_INVALID_PARAMETER; - } - - if (shape == nullptr) { - LOGE("OH_NNExecutor_GetOutputShape failed, passed nullptr to shape."); - return OH_NN_INVALID_PARAMETER; - } - - if (*shape != nullptr) { - LOGE("OH_NNExecutor_GetOutputShape failed, *shape is not nullptr."); - return OH_NN_INVALID_PARAMETER; + LOGE("OH_NNBackend_SetModelTensorData failed, passed 0 to length."); + return OH_NNCORE_INVALID_PARAMETER; } - if (shapeLength == nullptr) { - LOGE("OH_NNExecutor_GetOutputShape failed, passed nullptr to shapeLength."); - return OH_NN_INVALID_PARAMETER; + auto* innerModel = reinterpret_cast(model); + OH_NN_ReturnCode returnCode = innerModel->SetTensorValue(index, dataBuffer, length); + if (returnCode != OH_NN_SUCCESS) { + LOGE("OH_NNBackend_SetModelTensorData failed, error happened when setting tensor data."); } - Executor* innerExecutor = reinterpret_cast(executor); - return innerExecutor->GetOutputShape(outputIndex, shape, *shapeLength); + return OHOS::NeuralNetworkBackend::BackendToCore::ConvertReturnCode(returnCode); } -NNRT_API OH_NN_ReturnCode OH_NNExecutor_Run(OH_NNExecutor *executor) +OH_NNCore_ReturnCode OH_NNBackend_SetModelTensorQuantParam(OH_NNBackend_Model* model, + size_t index, + OH_NNBackend_QuantParam* param) { - if (executor == nullptr) { - LOGE("OH_NNExecutor_Run failed, passed nullptr to executor."); - return OH_NN_INVALID_PARAMETER; - } - - Executor *innerExecutor = reinterpret_cast(executor); - return innerExecutor->Run(); -} - -NNRT_API OH_NN_Memory *OH_NNExecutor_AllocateInputMemory(OH_NNExecutor *executor, uint32_t inputIndex, size_t length) -{ - if (executor == nullptr) { - LOGE("OH_NNExecutor_AllocateInputMemory failed, passed nullptr to executor."); - return nullptr; + if (model == nullptr) { + LOGE("OH_NNBackend_SetModelTensorQuantParam failed, passed nullptr to model."); + return OH_NNCORE_INVALID_PARAMETER; } - if (length == 0) { - LOGW("OH_NNExecutor_AllocateInputMemory has no effect, passed length equals 0."); - return nullptr; + if (param == nullptr) { + LOGE("OH_NNBackend_SetModelTensorQuantParam failed, passed nullptr to param."); + return OH_NNCORE_INVALID_PARAMETER; } - OH_NN_Memory *nnMemory = nullptr; - Executor *innerExecutor = reinterpret_cast(executor); - OH_NN_ReturnCode ret = innerExecutor->CreateInputMemory(inputIndex, length, &nnMemory); - if (ret != OH_NN_SUCCESS) { - LOGE("OH_NNExecutor_AllocateInputMemory failed, error happened when creating input memory in executor."); - return nullptr; + auto* innerModel = reinterpret_cast(model); + OH_NNCore_ReturnCode returnCode = innerModel->SetTensorQuantParam((uint32_t)(index), param); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("OH_NNBackend_SetModelTensorQuantParam failed, error happened when setting tensor quant param."); } - return nnMemory; + return returnCode; } -NNRT_API OH_NN_Memory *OH_NNExecutor_AllocateOutputMemory(OH_NNExecutor *executor, uint32_t outputIndex, size_t length) +OH_NNCore_ReturnCode OH_NNBackend_SetModelTensorType(OH_NNBackend_Model* model, + size_t index, + OH_NNBackend_TensorType type) { - if (executor == nullptr) { - LOGE("OH_NNExecutor_AllocateOutputMemory failed, passed nullptr to executor."); - return nullptr; + if (model == nullptr) { + LOGE("OH_NNBackend_SetModelTensorType failed, passed nullptr to model."); + return OH_NNCORE_INVALID_PARAMETER; } - if (length == 0) { - LOGW("OH_NNExecutor_AllocateOutputMemory has no effect, passed length equals 0."); - return nullptr; + if (!OHOS::NeuralNetworkBackend::Validation::ValidateTensorType(type)) { + LOGE("OH_NNBackend_SetModelTensorType failed, invalid tensor type."); + return OH_NNCORE_INVALID_PARAMETER; } - OH_NN_Memory *nnMemory = nullptr; - Executor *innerExecutor = reinterpret_cast(executor); - OH_NN_ReturnCode ret = innerExecutor->CreateOutputMemory(outputIndex, length, &nnMemory); - if (ret != OH_NN_SUCCESS) { - LOGE("OH_NNExecutor_AllocateOutputMemory failed, error happened when creating output memory in executor."); - return nullptr; + auto* innerModel = reinterpret_cast(model); + OH_NNCore_ReturnCode returnCode = innerModel->SetTensorType((uint32_t)(index), type); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("OH_NNBackend_SetModelTensorType failed, error happened when setting tensor type."); } - return nnMemory; + return returnCode; } -NNRT_API void OH_NNExecutor_DestroyInputMemory(OH_NNExecutor *executor, uint32_t inputIndex, OH_NN_Memory **memory) +OH_NNCore_ReturnCode OH_NNBackend_AddOperationToModel(OH_NNBackend_Model* model, + OH_NNBackend_OperationType operationType, + const OH_NNBackend_Array* paramIndices, + const OH_NNBackend_Array* inputIndices, + const OH_NNBackend_Array* outputIndices) { - if (executor == nullptr) { - LOGE("OH_NNExecutor_DestroyInputMemory failed, passed nullptr to executor."); - return; - } - - if (memory == nullptr) { - LOGW("OH_NNExecutor_DestroyInputMemory has no effect, passed nullptr to memory."); - return; - } - - if (*memory == nullptr) { - LOGW("OH_NNExecutor_DestroyInputMemory has no effect, passed nullptr to *memory."); - return; - } - - Executor *innerExecutor = reinterpret_cast(executor); - OH_NN_ReturnCode ret = innerExecutor->DestroyInputMemory(inputIndex, memory); - if (ret != OH_NN_SUCCESS) { - LOGE("OH_NNExecutor_DestroyInputMemory failed, error happened when destroying input memory."); - return; + if (model == nullptr) { + LOGE("OH_NNBackend_AddOperationToModel failed, passed nullptr to model."); + return OH_NNCORE_INVALID_PARAMETER; } - *memory = nullptr; -} - -NNRT_API void OH_NNExecutor_DestroyOutputMemory(OH_NNExecutor *executor, uint32_t outputIndex, OH_NN_Memory **memory) -{ - if (executor == nullptr) { - LOGE("OH_NNExecutor_DestroyOutputMemory failed, passed nullptr to executor."); - return; + if (paramIndices == nullptr) { + LOGE("OH_NNBackend_AddOperationToModel failed, passed nullptr to paramIndices."); + return OH_NNCORE_INVALID_PARAMETER; } - if (memory == nullptr) { - LOGW("OH_NNExecutor_DestroyOutputMemory has no effect, passed nullptr to memory."); - return; + if (inputIndices == nullptr) { + LOGE("OH_NNBackend_AddOperationToModel failed, passed nullptr to inputIndices."); + return OH_NNCORE_INVALID_PARAMETER; } - if (*memory == nullptr) { - LOGW("OH_NNExecutor_DestroyOutputMemory has no effect, passed nullptr to *memory."); - return; + if (outputIndices == nullptr) { + LOGE("OH_NNBackend_AddOperationToModel failed, passed nullptr to outputIndices."); + return OH_NNCORE_INVALID_PARAMETER; } - Executor *innerExecutor = reinterpret_cast(executor); - OH_NN_ReturnCode ret = innerExecutor->DestroyOutputMemory(outputIndex, memory); - if (ret != OH_NN_SUCCESS) { - LOGE("OH_NNExecutor_DestroyOutputMemory failed, error happened when destroying output memory."); - return; + auto* innerModel = reinterpret_cast(model); + OH_NNCore_ReturnCode returnCode = + innerModel->AddOperation(operationType, *paramIndices, *inputIndices, *outputIndices); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("OH_NNBackend_AddOperationToModel failed, error happened when adding operation to model."); } - *memory = nullptr; + return returnCode; } -NNRT_API OH_NN_ReturnCode OH_NNExecutor_SetInputWithMemory(OH_NNExecutor *executor, - uint32_t inputIndex, - const OH_NN_Tensor *tensor, - const OH_NN_Memory *memory) +OH_NNCore_ReturnCode OH_NNBackend_GetModelAvailableOperations(OH_NNBackend_Model* model, + const char* backendName, + const bool** isSupported, + uint32_t* opNum) { - if (executor == nullptr) { - LOGE("OH_NNExecutor_SetInputWithMemory failed, passed nullptr to executor."); - return OH_NN_INVALID_PARAMETER; + if (model == nullptr) { + LOGE("OH_NNBackend_GetModelAvailableOperations failed, passed nullptr to model."); + return OH_NNCORE_INVALID_PARAMETER; } - if (tensor == nullptr) { - LOGE("OH_NNExecutor_SetInputWithMemory failed, passed nullptr to tensor."); - return OH_NN_INVALID_PARAMETER; + if (backendName == nullptr) { + LOGE("OH_NNBackend_GetModelAvailableOperations failed, passed nullptr to backendName."); + return OH_NNCORE_INVALID_PARAMETER; } - if (memory == nullptr) { - LOGE("OH_NNExecutor_SetInputWithMemory failed, passed nullptr to memory."); - return OH_NN_INVALID_PARAMETER; + if (isSupported == nullptr) { + LOGE("OH_NNBackend_GetModelAvailableOperations failed, passed nullptr to isSupported."); + return OH_NNCORE_INVALID_PARAMETER; } - Executor *innerExecutor = reinterpret_cast(executor); - return innerExecutor->SetInputFromMemory(inputIndex, *tensor, *memory); -} - -NNRT_API OH_NN_ReturnCode OH_NNExecutor_SetOutputWithMemory(OH_NNExecutor *executor, - uint32_t outputIndex, - const OH_NN_Memory *memory) -{ - if (executor == nullptr) { - LOGE("OH_NNExecutor_SetOutputWithMemory failed, passed nullptr to executor."); - return OH_NN_INVALID_PARAMETER; + if (*isSupported != nullptr) { + LOGE("OH_NNBackend_GetModelAvailableOperations failed, *isSupported should be nullptr."); + return OH_NNCORE_INVALID_PARAMETER; } - if (memory == nullptr) { - LOGE("OH_NNExecutor_SetOutputWithMemory failed, passed nullptr to memory."); - return OH_NN_INVALID_PARAMETER; + if (opNum == nullptr) { + LOGE("OH_NNBackend_GetModelAvailableOperations failed, passed nullptr to opNum."); + return OH_NNCORE_INVALID_PARAMETER; } - Executor *innerExecutor = reinterpret_cast(executor); - return innerExecutor->SetOutputFromMemory(outputIndex, *memory); + auto* innerModel = reinterpret_cast(model); + OH_NNCore_ReturnCode returnCode = innerModel->GetSupportedOperations(backendName, isSupported, *opNum); + return returnCode; } -NNRT_API void OH_NNExecutor_Destroy(OH_NNExecutor **executor) +void OH_NNBackend_DestroyModel(OH_NNBackend_Model** model) { - if (executor == nullptr) { - LOGW("OH_NNExecutor_Destroy has no effect, since executor is nullptr."); + if (model == nullptr) { + LOGW("Passed nullptr to model."); return; } - if ((*executor) == nullptr) { - LOGW("OH_NNExecutor_Destroy has no effect, since *executor is nullptr"); + if (*model == nullptr) { + LOGW("Passed nullptr to *model."); return; } - Executor *innerExecutor = reinterpret_cast(*executor); - delete innerExecutor; - *executor = nullptr; -} - -NNRT_API OH_NN_ReturnCode OH_NNDevice_GetAllDevicesID(const size_t **allDevicesID, uint32_t *deviceCount) -{ - if (allDevicesID == nullptr) { - LOGE("OH_NNDevice_GetAllDevicesID failed, passed nullptr to allDevicesID."); - return OH_NN_INVALID_PARAMETER; - } - - if ((*allDevicesID) != nullptr) { - LOGE("OH_NNDevice_GetAllDevicesID failed, *allDevicesID should be nullptr."); - return OH_NN_INVALID_PARAMETER; - } - - if (deviceCount == nullptr) { - LOGE("OH_NNDevice_GetAllDevicesID failed, passed nullptr to deviceCount."); - return OH_NN_INVALID_PARAMETER; - } - - DeviceManager& deviceManager = DeviceManager::GetInstance(); - const std::vector& allDevices = deviceManager.GetAllDeviceId(); - - if (allDevices.empty()) { - LOGW("OH_NNDevice_GetAllDevicesID got no device."); - *allDevicesID = nullptr; - *deviceCount = 0; - return OH_NN_SUCCESS; - } - - *allDevicesID = allDevices.data(); - // allDevices.size() will not exceed UINT32_MAX, it is safe to cast to uint32_t. - *deviceCount = static_cast(allDevices.size()); - - return OH_NN_SUCCESS; -} - -NNRT_API OH_NN_ReturnCode OH_NNDevice_GetName(size_t deviceID, const char **name) -{ - if (name == nullptr) { - LOGE("OH_NNDevice_GetName failed, passed nullptr to name."); - return OH_NN_INVALID_PARAMETER; - } - - if ((*name) != nullptr) { - LOGE("OH_NNDevice_GetName failed, *name should be nullptr."); - return OH_NN_INVALID_PARAMETER; - } - - DeviceManager& deviceManager = DeviceManager::GetInstance(); - const std::string& deviceName = deviceManager.GetDeviceName(deviceID); - if (deviceName.empty()) { - LOGE("OH_NNDevice_GetName failed, error happened when getting name of deviceID %zu.", deviceID); - *name = nullptr; - return OH_NN_FAILED; - } - - *name = deviceName.data(); - return OH_NN_SUCCESS; + auto* innerModel = reinterpret_cast(*model); + delete innerModel; + *model = nullptr; + LOGI("Destroy model successfully."); } -NNRT_API OH_NN_ReturnCode OH_NNDevice_GetType(size_t deviceID, OH_NN_DeviceType* deviceType) +OH_NNCore_ReturnCode OH_NNBackend_SetCacheVersion(OH_NNCore_Options* options, uint32_t version) { - DeviceManager& deviceManager = DeviceManager::GetInstance(); - std::shared_ptr device = deviceManager.GetDevice(deviceID); - if (device == nullptr) { - LOGE("OH_NNDevice_GetName failed, passed invalid deviceID."); - return OH_NN_INVALID_PARAMETER; + if (options == nullptr) { + LOGE("OH_NNBackend_SetCacheVersion failed, options is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; } - if (deviceType == nullptr) { - LOGE("OH_NNDevice_GetType failed, passed nullptr to deviceType."); - return OH_NN_INVALID_PARAMETER; + NNOptions* optionsImpl = reinterpret_cast(options); + OH_NNCore_ReturnCode ret = optionsImpl->SetCacheVersion(version); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("OH_NNBackend_SetCacheVersion failed, version is nullptr."); + return OH_NNCORE_FAILED; } - OH_NN_ReturnCode ret = device->GetDeviceType(*deviceType); - if (ret != OH_NN_SUCCESS) { - LOGE("OH_NNDevice_GetType failed, device id: %zu.", deviceID); - return ret; - } - return OH_NN_SUCCESS; + return OH_NNCORE_SUCCESS; } \ No newline at end of file diff --git a/frameworks/native/nn_validation.cpp b/frameworks/native/nn_validation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..afed0915a4411cd7d704167e2771b20f5e3a90a2 --- /dev/null +++ b/frameworks/native/nn_validation.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nn_validation.h" + +#include "compat/validation.h" +#include "validation.h" + +namespace OHOS { +namespace NeuralNetworkBackend { +namespace Validation { +bool ValidateTensorType(OH_NNBackend_TensorType tensorType) +{ + return OHOS::NeuralNetworkRuntime::Validation::ValidateTensorType((OH_NN_TensorType)tensorType); +} +} // namespace Validation +} // NeuralNetworkBackend +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/nn_validation.h b/frameworks/native/nn_validation.h new file mode 100644 index 0000000000000000000000000000000000000000..3ce5ff29a22e7024865b052b1e02b8a2fbf360d9 --- /dev/null +++ b/frameworks/native/nn_validation.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_BACKEND_VALIDATION_H +#define NEURAL_NETWORK_BACKEND_VALIDATION_H + +#include "neural_network_runtime_type.h" + +namespace OHOS { +namespace NeuralNetworkBackend { +namespace Validation { +bool ValidateTensorType(OH_NNBackend_TensorType tensorType); +} // namespace Validation +} // NeuralNetworkBackend +} // namespace OHOS +#endif // NEURAL_NETWORK_BACKEND_VALIDATION_H diff --git a/frameworks/native/nnbackend.cpp b/frameworks/native/nnbackend.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bd91837a48a10c65adaa725fb191999be2f7d6a4 --- /dev/null +++ b/frameworks/native/nnbackend.cpp @@ -0,0 +1,231 @@ +#include "nnbackend.h" + +#include +#include "common/log.h" +#include "nncompiler.h" +#include "nncompiled.h" +#include "nnexecutor.h" +#include "nnoptions.h" +#include "nntensor.h" +#include "tensor_desc.h" + + +namespace OHOS { +namespace NeuralNetworkBackend { +using namespace OHOS::NeuralNetworkCore; +using namespace OHOS::NeuralNetworkRuntime; + +OH_NNCore_BackendStatus TransDeviceStatus(const DeviceStatus& deviceStatus) +{ + switch (deviceStatus) { + case DeviceStatus::AVAILABLE: + return OH_NNCore_BackendStatus::OH_NNCORE_AVAILABLE; + case DeviceStatus::BUSY: + return OH_NNCore_BackendStatus::OH_NNCORE_BUSY; + case DeviceStatus::OFFLINE: + return OH_NNCore_BackendStatus::OH_NNCORE_OFFLINE; + default: + return OH_NNCore_BackendStatus::OH_NNCORE_UNKNOWN_BACKEND_STATUS; + } +} + +NNBackend::NNBackend(const std::shared_ptr& device, const std::string& backendName) + : m_backendName(backendName), + m_device(device) {} + +NNBackend::~NNBackend() +{ + if (m_device != nullptr) { + m_device = nullptr; + } + m_backendName.clear(); +} + +OH_NNCore_ReturnCode NNBackend::GetBackendName(std::string& backendName) const +{ + if (m_backendName.empty()) { + LOGE("GetBackendName failed, backend name is empty"); + return OH_NNCORE_FAILED; + } + backendName = m_backendName; + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNBackend::GetBackendStatus(OH_NNCore_BackendStatus& status) const +{ + DeviceStatus deviceStatus = UNKNOWN; + OH_NN_ReturnCode ret = m_device->GetDeviceStatus(deviceStatus); + if (ret != OH_NN_SUCCESS) { + LOGW("GetBackendStatus failed, cannot get device status."); + } + status = TransDeviceStatus(deviceStatus); + return OH_NNCORE_SUCCESS; +} + +Options* NNBackend::CreateOptions() +{ + NNOptions* optionsImpl = new (std::nothrow) NNOptions(m_backendName); + if (optionsImpl == nullptr) { + LOGE("CreateOptions failed, fail to create NN Options."); + return nullptr; + } + return reinterpret_cast(optionsImpl); +} + +OH_NNCore_ReturnCode NNBackend::DestroyOptions(Options* options) +{ + if (options == nullptr) { + LOGE("Destory options failed, input options is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + delete options; + options = nullptr; + + return OH_NNCORE_SUCCESS; +} + +Compiler* NNBackend::CreateCompiler() +{ + NNCompiler* compilerImpl = new (std::nothrow) NNCompiler(m_device, m_backendName); + if (compilerImpl == nullptr) { + LOGE("CreateCompiler failed, fail to create NN compiler."); + return nullptr; + } + return reinterpret_cast(compilerImpl); +} + +OH_NNCore_ReturnCode NNBackend::DestroyCompiler(Compiler* compiler) +{ + if (compiler == nullptr) { + LOGE("DestroyCompiler failed, input compiler is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + delete compiler; + compiler = nullptr; + + return OH_NNCORE_SUCCESS; +} + +Compiled* NNBackend::CreateCompiled(const std::string& filePath, const OH_NNCore_Options* options) +{ + if (filePath.empty()) { + LOGE("CreateCompiled failed, should supply a valid model file, not empty."); + return nullptr; + } + + NNCompiled* compiledImpl = new (std::nothrow) NNCompiled(m_backendName, m_device); + if (compiledImpl == nullptr) { + LOGE("CreateCompiled failed, fail to create nn compiled."); + return nullptr; + } + + auto* optionsImpl = reinterpret_cast(options); + OH_NNCore_ReturnCode returnCode = compiledImpl->Restore(filePath, optionsImpl); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("CreateCompiled failed, fail to restore from model file."); + delete compiledImpl; + compiledImpl = nullptr; + return nullptr; + } + + return reinterpret_cast(compiledImpl); +} + +Compiled* NNBackend::CreateCompiled(const void* buffer, const size_t modelSize, const OH_NNCore_Options* options) +{ + if (buffer == nullptr || modelSize == 0) { + LOGE("CreateCompiled failed, model-buffer is null or model-size is 0"); + return nullptr; + } + + NNCompiled* compiledImpl = new (std::nothrow) NNCompiled(m_backendName, m_device); + if (compiledImpl == nullptr) { + LOGE("CreateCompiled failed, fail to create nn compiled."); + return nullptr; + } + + auto* optionsImpl = reinterpret_cast(options); + OH_NNCore_ReturnCode ret = compiledImpl->Restore(buffer, modelSize, optionsImpl); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("CreateCompiled failed, fail to restore from model buffer."); + delete compiledImpl; + compiledImpl = nullptr; + return nullptr; + } + + return reinterpret_cast(compiledImpl); +} + +OH_NNCore_ReturnCode NNBackend::DestroyCompiled(Compiled* compiled) +{ + if (compiled == nullptr) { + LOGE("DestroyCompiled failed, input compiled is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + delete compiled; + compiled = nullptr; + + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNBackend::DestroyExecutor(Executor* executor) +{ + if (executor == nullptr) { + LOGE("DestroyExecutor failed, input executor is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + delete executor; + executor = nullptr; + + return OH_NNCORE_SUCCESS; +} + +Tensor* NNBackend::CreateTensor(const std::string& backendName, TensorDesc* desc) +{ + if (desc == nullptr) { + LOGE("CreateTensor failed, input tensor desc is nullptr."); + return nullptr; + } + + NNTensor* tensorImpl = new (std::nothrow) NNTensor(backendName, desc); + if (tensorImpl == nullptr) { + LOGE("CreateTensor failed, fail to create NN Tensor."); + return nullptr; + } + return reinterpret_cast(tensorImpl); +} + +OH_NNCore_ReturnCode NNBackend::DestroyTensor(Tensor* tensor) +{ + if (tensor == nullptr) { + LOGE("DestroyTensor failed, input tensor is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + delete tensor; + tensor = nullptr; + + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNBackend::SetDevice(std::pair> device) +{ + m_backendName = device.first; + m_device = device.second; + + return OH_NNCORE_SUCCESS; +} + +std::shared_ptr NNBackend::GetDevice() const +{ + if (m_device == nullptr) { + LOGE("GetDevice failed, the device in backend is not available."); + } + return m_device; +} +} // NeuralNetworkBackend +} // OHOS \ No newline at end of file diff --git a/frameworks/native/nnbackend.h b/frameworks/native/nnbackend.h new file mode 100644 index 0000000000000000000000000000000000000000..daa93e20d9961ba4860b1e66ae27fb87a4cd359d --- /dev/null +++ b/frameworks/native/nnbackend.h @@ -0,0 +1,52 @@ +#include "backend.h" +#include "compiler.h" +#include "compiled.h" +#include "executor.h" +#include "options.h" +#include "tensor.h" +#include "tensor_desc.h" +#include "compat/device.h" + +namespace OHOS { +namespace NeuralNetworkBackend { + +class NNBackend : public OHOS::NeuralNetworkCore::Backend { +public: + NNBackend(const std::shared_ptr& device, const std::string& backendName); + ~NNBackend(); + + // Backend Info + OH_NNCore_ReturnCode GetBackendName(std::string& backendName) const override; + OH_NNCore_ReturnCode GetBackendStatus(OH_NNCore_BackendStatus& status) const override; + + // Create & Destory options + OHOS::NeuralNetworkCore::Options* CreateOptions() override; + OH_NNCore_ReturnCode DestroyOptions(OHOS::NeuralNetworkCore::Options* options) override; + + // Create & Destory compiler + OHOS::NeuralNetworkCore::Compiler* CreateCompiler() override; + OH_NNCore_ReturnCode DestroyCompiler(OHOS::NeuralNetworkCore::Compiler* compiler) override; + + // Create & Destory compiled graph + OHOS::NeuralNetworkCore::Compiled* CreateCompiled(const std::string& filePath, const OH_NNCore_Options* options) override; + OHOS::NeuralNetworkCore::Compiled* CreateCompiled(const void* buffer, const size_t modelSize, const OH_NNCore_Options* options) override; + OH_NNCore_ReturnCode DestroyCompiled(OHOS::NeuralNetworkCore::Compiled* compiled) override; + + // Destory Executor + OH_NNCore_ReturnCode DestroyExecutor(OHOS::NeuralNetworkCore::Executor* executor) override; + + // Create & Destory Tensor + OHOS::NeuralNetworkCore::Tensor* CreateTensor( + const std::string& backendName, OHOS::NeuralNetworkCore::TensorDesc* desc) override; + OH_NNCore_ReturnCode DestroyTensor(OHOS::NeuralNetworkCore::Tensor* tensor) override; + + // Set & Get Device + OH_NNCore_ReturnCode SetDevice(std::pair> device); + std::shared_ptr GetDevice() const; + +private: + std::string m_backendName; + std::shared_ptr m_device; +}; +} // NeuralNetworkBackend +} // OHOS diff --git a/frameworks/native/nncompiled.cpp b/frameworks/native/nncompiled.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c8d5334e360308e824d384b8aef4b19abe60110c --- /dev/null +++ b/frameworks/native/nncompiled.cpp @@ -0,0 +1,529 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nncompiled.h" + +#include +#include + +#include "common/log.h" +#include "compat/transform.h" +#include "common/utils.h" +#include "backend_manager.h" +#include "transform.h" +#include "nnbackend.h" +#include "nnexecutor.h" +#include "securec.h" + +namespace OHOS { +namespace NeuralNetworkBackend { +namespace { +struct SerializedTensorDesc { +public: + SerializedTensorDesc() = default; + ~SerializedTensorDesc() = default; + + OH_NNCore_ReturnCode CopyFromTensorDesc(const OHOS::NeuralNetworkCore::TensorDesc& tensorDesc) + { + OH_NNCore_ReturnCode returnCode = tensorDesc.GetDataType(&m_dataType); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("CopyFromTensorDesc failed, error happened when getting data type from tensor desc."); + return returnCode; + } + + returnCode = tensorDesc.GetFormat(&m_format); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("CopyFromTensorDesc failed, error happened when getting format from tensor desc."); + return returnCode; + } + + returnCode = tensorDesc.GetShape(&m_shape, &m_shapeNum); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("CopyFromTensorDesc failed, error happened when getting shape from tensor desc."); + return returnCode; + } + + returnCode = tensorDesc.GetName(&m_name); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("CopyFromTensorDesc failed, error happened when getting name from tensor desc."); + return returnCode; + } + + return returnCode; + } + + OH_NNCore_ReturnCode CopyToTensorDesc(OHOS::NeuralNetworkCore::TensorDesc& tensorDesc) const + { + OH_NNCore_ReturnCode returnCode = tensorDesc.SetDataType(m_dataType); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("CopyToTensorDesc failed, error happened when setting data type to tensor desc."); + return returnCode; + } + + returnCode = tensorDesc.SetFormat(m_format); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("CopyToTensorDesc failed, error happened when setting format to tensor desc."); + return returnCode; + } + + returnCode = tensorDesc.SetShape(m_shape, m_shapeNum); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("CopyToTensorDesc failed, error happened when setting shape to tensor desc."); + return returnCode; + } + + returnCode = tensorDesc.SetName(m_name); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("CopyToTensorDesc failed, error happened when setting name to tensor desc."); + } + + return returnCode; + } + +public: + OH_NNCore_DataType m_dataType{OH_NNCORE_OTHER_TYPES}; + OH_NNCore_Format m_format{OH_NNCORE_FORMAT_NONE}; + size_t m_shapeNum{0}; + int32_t* m_shape{nullptr}; + const char* m_name{nullptr}; // null-terminated +}; + +const size_t SIZE_OF_DATATYPE = sizeof(SerializedTensorDesc::m_dataType); +const size_t SIZE_OF_FORMAT = sizeof(SerializedTensorDesc::m_format); +const size_t SIZE_OF_SHAPE_NUM = sizeof(SerializedTensorDesc::m_shapeNum); +} // namespace + +NNCompiled::NNCompiled(const std::string& backendName, + std::shared_ptr& preparedModel, + std::vector> inputTensors, + std::vector> outputTensors, + std::shared_ptr device) +{ + m_backendName = backendName; + m_preparedModel = preparedModel; + m_device = device; + + std::shared_ptr tensorDesc; + for (auto inputTensor : inputTensors) { + tensorDesc = OHOS::NeuralNetworkRuntime::CreateSharedPtr(); + inputTensor->ConvertToTensorDesc(*(tensorDesc.get())); + m_inputTensorDescs.emplace_back(tensorDesc); + } + + for (auto outputTensor : outputTensors) { + tensorDesc = OHOS::NeuralNetworkRuntime::CreateSharedPtr(); + outputTensor->ConvertToTensorDesc(*(tensorDesc.get())); + m_outputTensorDescs.emplace_back(tensorDesc); + } +} + +NNCompiled::NNCompiled(const std::string& backendName, std::shared_ptr device) +{ + m_backendName = backendName; + m_device = device; +} + +OH_NNCore_ReturnCode NNCompiled::Save(const std::string& cacheDir) const +{ + if (cacheDir.empty()) { + LOGE("NNCompiled::Save failed, cacheDir is empty."); + return OH_NNCORE_INVALID_PARAMETER; + } + + if (m_preparedModel == nullptr) { + LOGE("NNCompiled::Save failed, compilation is nullptr. Please construct NNCompiled with valid compilation or " + "use Restore() first."); + return OH_NNCORE_FAILED; + } + + if (m_backendName.empty()) { + LOGE("NNCompiled::Save failed, backendName is empty. Please construct NNCompiled with valid backendName."); + return OH_NNCORE_FAILED; + } + + if (m_version == INVALID_CAHCE_VERSION) { + LOGE("NNCompiled::Save failed, cache version is invalid. Please set a valid cache version."); + return OH_NNCORE_FAILED; + } + + std::vector caches; + OH_NN_ReturnCode ret = m_preparedModel->ExportModelCache(caches); + if (ret != OH_NN_SUCCESS) { + LOGE("Compiled::Save failed, error happened when exporting model cache."); + return OHOS::NeuralNetworkBackend::BackendToCore::ConvertReturnCode(ret); + } + + OHOS::NeuralNetworkBackend::NNCompiledCache compiledCache; + compiledCache.SetBackendName(m_backendName); + + OHOS::NeuralNetworkRuntime::Buffer inputTensorDescBuffer; + OH_NNCore_ReturnCode returnCode = SerializeTensorsToBuffer(m_inputTensorDescs, inputTensorDescBuffer); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("NNCompiled::Save failed, error happened when serializing input tensor desc."); + return returnCode; + } + caches.emplace_back(inputTensorDescBuffer); + + OHOS::NeuralNetworkRuntime::Buffer outputTensorDescBuffer; + returnCode = SerializeTensorsToBuffer(m_outputTensorDescs, outputTensorDescBuffer); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("NNCompiled::Save failed, error happened when serializing output tensor desc."); + return returnCode; + } + caches.emplace_back(outputTensorDescBuffer); + + returnCode = compiledCache.Save(caches, cacheDir, m_version); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("NNCompiled::Save failed, error happened when saving model cache."); + return returnCode; + } + + LOGI("[Compilation] Export model cache successfully."); + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNCompiled::Restore(const std::string& path, const OHOS::NeuralNetworkCore::Options* options) +{ + if (path.empty()) { + LOGE("NNCompiled::Restore failed, path is empty."); + return OH_NNCORE_INVALID_PARAMETER; + } + + if (m_preparedModel != nullptr) { + LOGE("NNCompiled::Restore failed, compilation is not nullptr. Do not pass preparedModel when constructing " + "NNCompiled."); + return OH_NNCORE_FAILED; + } + + const auto* nnOptions = reinterpret_cast(options); + m_version = nnOptions->GetCacheVersion(); + + if (m_version == INVALID_CAHCE_VERSION) { + LOGE("NNCompiled::Save failed, cache version is invalid. Please set a valid cache version."); + return OH_NNCORE_FAILED; + } + + if (m_backendName.empty()) { + LOGE("NNCompiled::Restore failed, backendName is empty. Please construct NNCompiled with valid backendName."); + return OH_NNCORE_FAILED; + } + + OHOS::NeuralNetworkBackend::NNCompiledCache compiledCache; + compiledCache.SetBackendName(m_backendName); + + std::vector caches; + OH_NNCore_ReturnCode returnCode = compiledCache.Restore(path, m_version, caches); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("NNCompiled::Restore failed, error happened when restoring model cache."); + return returnCode; + } + + size_t cacheNum = caches.size(); + returnCode = DeserializedTensorsFromBuffer(caches[cacheNum-2], m_inputTensorDescs); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("NNCompiled::Restore failed, error happened when deserializing input tensor desc."); + return returnCode; + } + + returnCode = DeserializedTensorsFromBuffer(caches[cacheNum-1], m_outputTensorDescs); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("NNCompiled::Restore failed, error happened when deserializing output tensor desc."); + return returnCode; + } + + // TODO: Add NNOption check here. + auto nnOptions = reinterpret_cast(options); + OHOS::NeuralNetworkRuntime::ModelConfig config; + config.enableFloat16 = nnOptions->GetEnabledFp16(); + config.mode = (OH_NN_PerformanceMode)nnOptions->GetPerformanceMode(); + config.priority = (OH_NN_Priority)nnOptions->GetPriority(); + std::vector modelOnlyCaches(caches.begin(), caches.end()-2); + OH_NN_ReturnCode ret = m_device->PrepareModelFromModelCache(modelOnlyCaches, config, m_preparedModel); + if (ret != OH_NN_SUCCESS) { + LOGE("NNCompiled::Restore failed, error happened when preparing model from cache."); + return OHOS::NeuralNetworkBackend::BackendToCore::ConvertReturnCode(ret); + } + + LOGI("[Compilation] Restore model cache successfully."); + + return returnCode; +} + +OH_NNCore_ReturnCode NNCompiled::Save(const void* buffer, size_t length, size_t* modelSize) const +{ + LOGE("NNCompiled::Save is not supported currently."); + return OH_NNCORE_UNSUPPORTED; +} + +OH_NNCore_ReturnCode NNCompiled::Restore(const void* buffer, size_t modelSize, const OHOS::NeuralNetworkCore::Options* options) +{ + LOGE("NNCompiled::Restore is not supported currently."); + return OH_NNCORE_UNSUPPORTED; +} + +// TODO: Change function name to CreateInputDesc +OH_NNCore_ReturnCode NNCompiled::GetInputDesc(size_t index, OH_NNCore_TensorDesc** tensorDesc) const +{ + if (m_preparedModel == nullptr) { + LOGE("NNCompiled::GetInputDesc failed, m_preparedModel is nullptr. Please construct NNCompiled with valid " + "preparedModel or use Restore() first."); + return OH_NNCORE_NULL_PTR; + } + + if (tensorDesc == nullptr) { + LOGE("NNCompiled::GetInputDesc failed, tensorDesc is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + if (*tensorDesc != nullptr) { + LOGE("NNCompiled::GetInputDesc failed, tensorDesc is not nullptr. Please pass empty pointer."); + return OH_NNCORE_INVALID_PARAMETER; + } + + if (index >= m_inputTensorDescs.size()) { + LOGE("NNCompiled::GetInputDesc failed, index %zu is out of range.", index); + return OH_NNCORE_INVALID_PARAMETER; + } + + OHOS::NeuralNetworkCore::TensorDesc* desc = new (std::nothrow) OHOS::NeuralNetworkCore::TensorDesc(); + if (desc == nullptr) { + LOGE("NNCompiled::GetInputDesc failed, failed to allocate memory."); + return OH_NNCORE_MEMORY_EXCEPTION; + } + + // Copy the member attributes to new tensor description + *desc = *(m_inputTensorDescs[index].get()); + + // The lifetime of desc is managed by tensorDesc, which is controlled be NNRt user. + *tensorDesc = (OH_NNCore_TensorDesc*)(desc); + + return OH_NNCORE_SUCCESS; +} + +// TODO: Change function name to CreateInputDesc +OH_NNCore_ReturnCode NNCompiled::GetOutputDesc(size_t index, OH_NNCore_TensorDesc** tensorDesc) const +{ + if (m_preparedModel == nullptr) { + LOGE("NNCompiled::GetOutputDesc failed, m_preparedModel is nullptr. Please construct NNCompiled with valid " + "preparedModel or use Restore() first."); + return OH_NNCORE_NULL_PTR; + } + + if (tensorDesc == nullptr) { + LOGE("NNCompiled::GetOutputDesc failed, tensorDesc is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + if (*tensorDesc != nullptr) { + LOGE("NNCompiled::GetOutputDesc failed, tensorDesc is not nullptr. Please pass empty pointer."); + return OH_NNCORE_INVALID_PARAMETER; + } + + if (index >= m_outputTensorDescs.size()) { + LOGE("NNCompiled::GetOutputDesc failed, index %zu is out of range.", index); + return OH_NNCORE_INVALID_PARAMETER; + } + + OHOS::NeuralNetworkCore::TensorDesc* desc = new (std::nothrow) OHOS::NeuralNetworkCore::TensorDesc(); + if (desc == nullptr) { + LOGE("NNCompiled::GetOutputDesc failed, failed to allocate memory."); + return OH_NNCORE_MEMORY_EXCEPTION; + } + + // Copy the member attributes to new tensor description + *desc = *(m_outputTensorDescs[index].get()); + + // The lifetime of desc is managed by tensorDesc, which is controlled be NNRt user. + *tensorDesc = (OH_NNCore_TensorDesc*)(desc); + + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNCompiled::GetInputCount(size_t* count) const +{ + if (m_preparedModel == nullptr) { + LOGE("NNCompiled::GetInputCount failed, m_preparedModel is nullptr. Please construct NNCompiled with valid " + "preparedModel or use Restore() first."); + return OH_NNCORE_NULL_PTR; + } + + *count = m_inputTensorDescs.size(); + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNCompiled::GetOutputCount(size_t* count) const +{ + if (m_preparedModel == nullptr) { + LOGE("NNCompiled::GetOutputCount failed, m_preparedModel is nullptr. Please construct NNCompiled with valid " + "preparedModel or use Restore() first."); + return OH_NNCORE_NULL_PTR; + } + + *count = m_outputTensorDescs.size(); + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNCompiled::SetCompiledOptions(const OH_NNCore_Options* options) +{ + if (options == nullptr) { + LOGE("NNCompiled::SetCompiledOptions failed, options is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + const auto* optionsImpl = reinterpret_cast(options); + + m_version = optionsImpl->GetCacheVersion(); + + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNCompiled::CreateExecutor(OH_NNCore_Executor** executor) const +{ + if (m_preparedModel == nullptr) { + LOGE("NNCompiled::CreateExecutor failed, m_preparedModel is nullptr. Please construct NNCompiled with valid " + "preparedModel or use Restore() first."); + return OH_NNCORE_NULL_PTR; + } + + OHOS::NeuralNetworkCore::BackendManager& backendManager = OHOS::NeuralNetworkCore::BackendManager::GetInstance(); + std::shared_ptr backend = backendManager.GetBackend(m_backendName); + if (backend == nullptr) { + LOGE("NNCompiled::CreateExecutor failed, backend with backendName %s is not exist.", m_backendName.c_str()); + return OH_NNCORE_INVALID_PARAMETER; + } + + auto* nnExecutor = new (std::nothrow) OHOS::NeuralNetworkBackend::NNExecutor(m_backendName, m_preparedModel); + if (executor == nullptr) { + LOGE("NNCompiled::CreateExecutor failed, error happend when allocating NNExecutor."); + return OH_NNCORE_MEMORY_EXCEPTION; + } + + *executor = (OH_NNCore_Executor*)(nnExecutor); + + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNCompiled::GetBackendName(std::string& backendName) const +{ + backendName = m_backendName; + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNCompiled::SerializeTensorsToBuffer( + const std::vector>& tensorDescs, + OHOS::NeuralNetworkRuntime::Buffer& buffer) const +{ + std::vector immediateTensorDescs; + OH_NNCore_ReturnCode returnCode{OH_NNCORE_SUCCESS}; + for (const auto tensorDesc : tensorDescs) { + SerializedTensorDesc immediateTensorDesc; + returnCode = immediateTensorDesc.CopyFromTensorDesc(*(tensorDesc.get())); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("NNCompiled::SerializeInputsToBuffer failed, error happened when copying tensorDesc to " + "SerializedTensorDesc."); + immediateTensorDescs.clear(); + return returnCode; + } + + immediateTensorDescs.emplace_back(immediateTensorDesc); + } + + size_t totalSize = 0; + for (const auto& tensorDesc : immediateTensorDescs) { + totalSize += SIZE_OF_DATATYPE; + totalSize += SIZE_OF_FORMAT; + totalSize += SIZE_OF_SHAPE_NUM; + totalSize += tensorDesc.m_shapeNum * sizeof(int32_t); + totalSize += strlen(tensorDesc.m_name) + 1; + } + + // Allocate memory for the serialized data + char* serializedData = new char[totalSize]; + char* currentPos = serializedData; + + // Serialize each tensor description + for (const auto& tensorDesc : immediateTensorDescs) { + memcpy_s(currentPos, SIZE_OF_DATATYPE, &tensorDesc.m_dataType, SIZE_OF_DATATYPE); + currentPos += SIZE_OF_DATATYPE; + + memcpy_s(currentPos, SIZE_OF_FORMAT, &tensorDesc.m_format, SIZE_OF_FORMAT); + currentPos += SIZE_OF_FORMAT; + + memcpy_s(currentPos, SIZE_OF_SHAPE_NUM, &tensorDesc.m_shapeNum, SIZE_OF_SHAPE_NUM); + currentPos += SIZE_OF_SHAPE_NUM; + + size_t sizeOfShape = tensorDesc.m_shapeNum * sizeof(int32_t); + memcpy_s(currentPos, sizeOfShape, tensorDesc.m_shape, sizeOfShape); + currentPos += sizeOfShape; + + size_t sizeOfName = strlen(tensorDesc.m_name) + 1; + strcpy_s(currentPos, sizeOfName, tensorDesc.m_name); + currentPos += sizeOfName; + } + + buffer.data = serializedData; + buffer.length = totalSize; + + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNCompiled::DeserializedTensorsFromBuffer( + const OHOS::NeuralNetworkRuntime::Buffer& buffer, + std::vector>& tensorDescs) +{ + std::vector immediateTensorDescs; + const char* ptr = static_cast(buffer.data); + const char* end = ptr + buffer.length; + while (ptr < end) { + SerializedTensorDesc desc; + + memcpy_s(&desc.m_dataType, SIZE_OF_DATATYPE, ptr, SIZE_OF_DATATYPE); + ptr += SIZE_OF_DATATYPE; + + memcpy_s(&desc.m_format, SIZE_OF_FORMAT, SIZE_OF_FORMAT); + ptr += SIZE_OF_FORMAT; + + memcpy_s(&desc.m_shapeNum, SIZE_OF_SHAPE_NUM, ptr, SIZE_OF_SHAPE_NUM); + ptr += SIZE_OF_SHAPE_NUM; + + // TODO: Need to delete + desc.m_shape = new int32_t[desc.m_shapeNum]; + size_t sizeOfShape = desc.m_shapeNum * sizeof(int32_t); + memcpy_s(desc.m_shape, sizeOfShape, ptr, sizeOfShape); + ptr += sizeOfShape; + + desc.m_name = ptr; + ptr += std::strlen(desc.m_name) + 1; // +1 for null terminator + + immediateTensorDescs.push_back(desc); + } + + OH_NNCore_ReturnCode returnCode {OH_NNCORE_SUCCESS}; + for (const auto& immediateTensorDesc : immediateTensorDescs) { + auto tensorDesc = OHOS::NeuralNetworkRuntime::CreateSharedPtr(); + returnCode = immediateTensorDesc.CopyToTensorDesc(*(tensorDesc.get())); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("NNCompiled::UnserializedInputsFromBuffer failed, error happened when copying " + "SerializedTensorDesc to TensorDesc."); + return returnCode; + } + + tensorDescs.emplace_back(tensorDesc); + } + + return returnCode; +} +} // namespace NeuralNetworkBackend +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/nncompiled.h b/frameworks/native/nncompiled.h new file mode 100644 index 0000000000000000000000000000000000000000..7bcaab0f04067542ce46226c004e19156fe5c1c7 --- /dev/null +++ b/frameworks/native/nncompiled.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_BACKEND_NNCOMPILED_H +#define NEURAL_NETWORK_BACKEND_NNCOMPILED_H + +#include "compiled.h" + +#include + +#include "compat/device.h" +#include "compat/prepared_model.h" +#include "nncompiled_cache.h" +#include "tensor_desc.h" +#include "nnoptions.h" + +namespace OHOS { +namespace NeuralNetworkBackend { + +class NNCompiled : public OHOS::NeuralNetworkCore::Compiled { +public: + NNCompiled() = delete; + ~NNCompiled() = default; + // Should be called when compiled for the first time. + NNCompiled(const std::string& backendName, + std::shared_ptr& preparedModel, + std::vector> inputTensors, + std::vector> outputTensors, + std::shared_ptr device); + + // Should be called when compiled from the cache. + NNCompiled(const std::string& backendName, std::shared_ptr device); + + OH_NNCore_ReturnCode Save(const std::string& path) const override; + OH_NNCore_ReturnCode Restore(const std::string& path, const OHOS::NeuralNetworkCore::Options* options) override; + OH_NNCore_ReturnCode Save(const void* buffer, size_t length, size_t* modelSize) const override; + OH_NNCore_ReturnCode Restore(const void* buffer, size_t modelSize, const OHOS::NeuralNetworkCore::Options* options) override; + + OH_NNCore_ReturnCode GetInputDesc(size_t index, OH_NNCore_TensorDesc** tensorDesc) const override; + OH_NNCore_ReturnCode GetOutputDesc(size_t index, OH_NNCore_TensorDesc** tensorDesc) const override; + + OH_NNCore_ReturnCode GetInputCount(size_t* count) const override; + OH_NNCore_ReturnCode GetOutputCount(size_t* count) const override; + + OH_NNCore_ReturnCode SetCompiledOptions(const OH_NNCore_Options* options) override; + + OH_NNCore_ReturnCode CreateExecutor(OH_NNCore_Executor** executor) const override; + OH_NNCore_ReturnCode GetBackendName(std::string& backendName) const override; + +private: + OH_NNCore_ReturnCode SerializeTensorsToBuffer( + const std::vector>& tensorDescs, + OHOS::NeuralNetworkRuntime::Buffer& buffer) const; + OH_NNCore_ReturnCode DeserializedTensorsFromBuffer( + const OHOS::NeuralNetworkRuntime::Buffer& buffer, + std::vector>& tensorDescs); + +private: + uint32_t m_version{INVALID_CAHCE_VERSION}; + std::string m_backendName; + std::shared_ptr m_preparedModel{nullptr}; + + std::vector> m_inputTensorDescs; + std::vector> m_outputTensorDescs; + std::shared_ptr m_device{nullptr}; +}; +} // namespace NeuralNetworkBackend +} // namespace OHOS +#endif // NEURAL_NETWORK_BACKEND_NNCOMPILED_H diff --git a/frameworks/native/nncompiled_cache.cpp b/frameworks/native/nncompiled_cache.cpp new file mode 100644 index 0000000000000000000000000000000000000000..367cbd9ab5a673ea777971e66463d28141707aa1 --- /dev/null +++ b/frameworks/native/nncompiled_cache.cpp @@ -0,0 +1,446 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nncompiled_cache.h" + +#include +#include +#include + +#include "common/log.h" +#include "backend_manager.h" +#include "nnbackend.h" + +namespace OHOS { +namespace NeuralNetworkBackend { +constexpr int MAX_MODEL_SIZE = 200 * 1024 * 1024; // 200MB +constexpr int OCT_UNIT = 8; +constexpr int NULL_PTR_LENGTH = 0; +constexpr int NUMBER_CACHE_INFO_MEMBERS = 3; + +// CRC16 Table is created based on the Polynomial of G(x) = x^16 + x^12 + x^15 + 1 and +// CRC register initialization value of "0" (0x0000) +static const unsigned short CRC16_TAB[256] = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, + 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, + 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, + 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, + 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, + 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, + 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, + 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, + 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, + 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, + 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, + 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, + 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, + 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, + 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0}; + +OH_NNCore_ReturnCode NNCompiledCache::Save(const std::vector& caches, + const std::string& cacheDir, + uint32_t version) +{ + if (caches.empty()) { + LOGE("NNCompiledCache::Save failed, caches is empty."); + return OH_NNCORE_INVALID_PARAMETER; + } + + if (m_backendName.empty()) { + LOGE("NNCompiledCache::Save failed, m_backendName is empty."); + return OH_NNCORE_INVALID_PARAMETER; + } + + OH_NNCore_ReturnCode returnCode = GenerateCacheFiles(caches, cacheDir, version); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("NNCompiledCache::Save failed, error happened when calling GenerateCacheFiles."); + return returnCode; + } + + LOGI("NNCompiledCache::Save success. %zu caches are saved.", caches.size()); + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNCompiledCache::Restore(const std::string& cacheDir, + uint32_t version, + std::vector& caches) +{ + if (cacheDir.empty()) { + LOGE("NNCompiledCache::Restore failed, cacheDir is empty."); + return OH_NNCORE_INVALID_PARAMETER; + } + + if (!caches.empty()) { + LOGE("NNCompiledCache::Restore failed, caches is not empty."); + return OH_NNCORE_INVALID_PARAMETER; + } + + if (m_backendName.empty()) { + LOGE("NNCompiledCache::Restore failed, m_backendName is empty."); + return OH_NNCORE_INVALID_PARAMETER; + } + + // TODO: Check whether it is necessary to check m_modelName + // if (m_modelName.empty()) { + // LOGE("NNCompiledCache::Restore failed, m_modelName is empty."); + // return OH_NNCORE_INVALID_PARAMETER; + // } + + std::string cacheInfoPath = cacheDir + m_modelName + "cache_info.nncache"; + if (access(cacheInfoPath.c_str(), 0) != 0) { + LOGE("NNCompiledCache::Restore failed, cacheInfoPath is not exist."); + return OH_NNCORE_INVALID_PATH; + } + + NNCompiledCacheInfo cacheInfo; + OH_NNCore_ReturnCode returnCode = CheckCacheInfo(cacheInfo, cacheInfoPath); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("NNCompiledCache::Restore failed, error happened when calling CheckCacheInfo."); + return returnCode; + } + + if ((uint64_t)version != cacheInfo.version) { + LOGE("NNCompiledCache::Restore failed, version is not match. The current version is %u, but the cache files " + "version is %llu.", + version, + cacheInfo.version); + return OH_NNCORE_INVALID_PARAMETER; + } + + for (uint32_t i = 0; i < cacheInfo.fileNumber; ++i) { + std::string cacheModelPath = cacheDir + m_modelName + std::to_string(i) + ".nncache"; + if (access(cacheModelPath.c_str(), 0) != 0) { + LOGE("NNCompiledCache::Restore failed, %s is not exist.", cacheModelPath.c_str()); + return OH_NNCORE_INVALID_PATH; + } + + OHOS::NeuralNetworkRuntime::Buffer modelBuffer; + returnCode = ReadCacheModelFile(cacheModelPath, modelBuffer); + if (returnCode != OH_NNCORE_SUCCESS) { + LOGE("NNCompiledCache::Restore failed, error happened when calling ReadCacheModelFile."); + return returnCode; + } + + if (GetCrc16(static_cast(modelBuffer.data), modelBuffer.length) != + cacheInfo.modelCheckSum[i]) { + LOGE("NNCompiledCache::Restore failed, the cache model file %s has been changed.", cacheModelPath.c_str()); + return OH_NNCORE_INVALID_FILE; + } + + caches.emplace_back(std::move(modelBuffer)); + } + + return returnCode; +} + +OH_NNCore_ReturnCode NNCompiledCache::SetBackendName(const std::string& backendName) +{ + if (backendName.empty()) { + LOGE("NNCompiledCache::SetBackend failed, m_backendName is empty."); + return OH_NNCORE_INVALID_PARAMETER; + } + + OHOS::NeuralNetworkCore::BackendManager& backendManager = OHOS::NeuralNetworkCore::BackendManager::GetInstance(); + std::shared_ptr backend = backendManager.GetBackend(backendName); + if (backend == nullptr) { + LOGE("NNCompiledCache::SetBackend failed, backend with backendName %s is not exist.", backendName.c_str()); + return OH_NNCORE_INVALID_PARAMETER; + } + + std::shared_ptr nnBackend = + std::dynamic_pointer_cast(backend); + m_device = nnBackend->GetDevice(); + if (m_device == nullptr) { + LOGE("NNCompiledCache::SetBackend failed, device with backendName %s is not exist.", backendName.c_str()); + return OH_NNCORE_FAILED; + } + + m_backendID = std::hash{}(backendName); + m_backendName = backendName; + return OH_NNCORE_SUCCESS; +} + +void NNCompiledCache::SetModelName(const std::string& modelName) +{ + m_modelName = modelName; +} + +void NNCompiledCache::SetInputTensorDescs( + std::vector> inputTensorDescs) +{ + m_inputTensorDescs = inputTensorDescs; +} + +void NNCompiledCache::SetOutputTensorDescs( + std::vector> outputTensorDescs) +{ + m_outputTensorDescs = outputTensorDescs; +} + +std::vector> NNCompiledCache::GetInputTensorDescs() const +{ + return m_inputTensorDescs; +} + +std::vector> NNCompiledCache::GetOutputTensorDescs() const +{ + return m_outputTensorDescs; +} + +OH_NNCore_ReturnCode NNCompiledCache::GenerateCacheFiles(const std::vector& caches, + const std::string& cacheDir, + uint32_t version) const +{ + const size_t cacheNumber = caches.size(); + uint32_t cacheSize = NUMBER_CACHE_INFO_MEMBERS + cacheNumber; + std::unique_ptr cacheInfo = std::make_unique(cacheSize); + if (cacheInfo == nullptr) { + LOGE("Fail to create cacheInfo instance."); + return OH_NNCORE_MEMORY_EXCEPTION; + } + + OH_NNCore_ReturnCode ret = GenerateCacheModel(caches, cacheInfo, cacheDir, version); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("NNCompiledCache::GenerateCacheFiles failed, error happened when calling GenerateCacheModel."); + return ret; + } + + uint32_t infoCharNumber = cacheSize * sizeof(uint64_t); + ret = WriteCacheInfo(infoCharNumber, cacheInfo, cacheDir); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("NNCompiledCache::GenerateCacheFiles failed, error happened when calling WriteCacheInfo."); + return ret; + } + + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNCompiledCache::GenerateCacheModel(const std::vector& caches, + std::unique_ptr& cacheInfo, + const std::string& cacheDir, + uint32_t version) const +{ + size_t cacheNumber = caches.size(); + + auto cacheInfoPtr = cacheInfo.get(); + *cacheInfoPtr++ = static_cast(cacheNumber); + *cacheInfoPtr++ = static_cast(version); + *cacheInfoPtr++ = static_cast(m_backendID); // Should call SetBackend first. + + for (size_t i = 0; i < cacheNumber; ++i) { + std::string cacheModelFile = cacheDir + m_modelName + std::to_string(i) + ".nncache"; + std::ofstream cacheModelStream(cacheModelFile, std::ios::binary | std::ios::out | std::ios::trunc); + if (cacheModelStream.fail()) { + LOGE("[Compilation] Model cache file is invalid."); + return OH_NNCORE_INVALID_FILE; + } + + uint64_t checkSum = + static_cast(GetCrc16(static_cast(caches[i].data), caches[i].length)); + *cacheInfoPtr++ = checkSum; + if (!cacheModelStream.write(static_cast(caches[i].data), caches[i].length)) { + LOGE("[Compilation] Fail to write cache model."); + cacheModelStream.close(); + return OH_NNCORE_FAILED; + }; + + cacheModelStream.close(); + } + + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNCompiledCache::WriteCacheInfo(uint32_t cacheSize, + std::unique_ptr& cacheInfo, + const std::string& cacheDir) const +{ + std::string cacheInfoPath = cacheDir + m_modelName + "cache_info.nncache"; + std::ofstream cacheInfoStream(cacheInfoPath, std::ios::binary | std::ios::out | std::ios::trunc); + if (cacheInfoStream.fail()) { + LOGE("[Compilation] Model cache info file is invalid."); + return OH_NNCORE_INVALID_FILE; + } + + if (!cacheInfoStream.write(reinterpret_cast(cacheInfo.get()), cacheSize)) { + LOGE("[Compilation] Fail to write cache info."); + cacheInfoStream.close(); + return OH_NNCORE_FAILED; + } + + cacheInfoStream.close(); + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNCompiledCache::CheckCacheInfo(NNCompiledCacheInfo& modelCacheInfo, + const std::string& cacheInfoPath) const +{ + // cacheInfoPath is validated outside. + std::ifstream infoCacheFile(cacheInfoPath.c_str(), std::ios::in | std::ios::binary); + if (!infoCacheFile) { + LOGE("NNCompiledCache::CheckCacheInfo failed, error happened when opening cache info file."); + return OH_NNCORE_INVALID_FILE; + } + + int charNumber = NUMBER_CACHE_INFO_MEMBERS * sizeof(uint64_t); + if (!infoCacheFile.read((char*)&(modelCacheInfo), charNumber)) { + LOGE("NNCompiledCache::CheckCacheInfo failed, error happened when reading cache info file."); + infoCacheFile.close(); + return OH_NNCORE_INVALID_FILE; + } + + // modelCacheInfo.deviceId type is int64_t, + // it is transformed from size_t value, so the transform here will not truncate value. + size_t deviceId = static_cast(modelCacheInfo.deviceId); + if (deviceId != m_backendID) { + LOGE("NNCompiledCache::CheckCacheInfo failed. The deviceId=%zu in the cache files is different from current " + "deviceId=%zu," + "please change the cache directory or current deviceId.", + deviceId, + m_backendID); + infoCacheFile.close(); + return OH_NNCORE_INVALID_PARAMETER; + } + + std::vector modelCheckSum; + modelCheckSum.resize(modelCacheInfo.fileNumber); + modelCacheInfo.modelCheckSum.resize(modelCacheInfo.fileNumber); + if (!infoCacheFile.read((char*)&modelCheckSum[0], modelCacheInfo.fileNumber * sizeof(uint64_t))) { + LOGE("NNCompiledCache::CheckCacheInfo failed. The info cache file has been changed."); + infoCacheFile.close(); + return OH_NNCORE_INVALID_FILE; + } + + for (uint32_t i = 0; i < modelCacheInfo.fileNumber; ++i) { + modelCacheInfo.modelCheckSum[i] = static_cast(modelCheckSum[i]); + } + + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNCompiledCache::ReadCacheModelFile(const std::string& filePath, + OHOS::NeuralNetworkRuntime::Buffer& cache) const +{ + // filePath is validate in NNCompiledCache::Restore, no need to check twice. + std::ifstream ifs(filePath.c_str(), std::ios::in | std::ios::binary); + if (!ifs) { + LOGE("NNCompiledCache::ReadCacheModelFile failed, file is invalid."); + return OH_NNCORE_INVALID_FILE; + } + + int fsize{-1}; + OH_NNCore_ReturnCode returnCode = GetCacheFileLength(ifs, fsize); + if (returnCode != OH_NNCORE_SUCCESS) { + ifs.close(); + return returnCode; + } + + ifs.seekg(0, std::ios::beg); + if (!ifs.good()) { + LOGE("NNCompiledCache::ReadCacheModelFile failed, file is invalid."); + ifs.close(); + return OH_NNCORE_INVALID_FILE; + } + + char* ptr = static_cast(m_device->AllocateBuffer(fsize)); + if (ptr == nullptr) { + LOGE("NNCompiledCache::ReadCacheModelFile failed, failed to allocate memory."); + ifs.close(); + return OH_NNCORE_MEMORY_EXCEPTION; + } + + ifs.read(ptr, fsize); + if (!ifs.good()) { + LOGE("NNCompiledCache::ReadCacheModelFile failed, failed to read file."); + ifs.close(); + m_device->ReleaseBuffer(ptr); + ptr = nullptr; + return OH_NNCORE_INVALID_FILE; + } + + ifs.close(); + cache.data = ptr; + cache.length = static_cast(fsize); // fsize should be non-negative, safe to cast. + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNCompiledCache::RemoveCacheFiles(const std::string& cacheDir, uint32_t fileNumber) const +{ + std::string cacheInfoPath = cacheDir + m_modelName + "cache_info.nncache"; + if (remove(cacheInfoPath.c_str()) == -1) { + LOGE("NNCompiledCache::RemoveCacheFiles failed to remove the file %s, please delete the file manually.", + cacheInfoPath.c_str()); + return OH_NNCORE_FAILED; + } + LOGI("NNCompiledCache::RemoveCacheFiles succeed to remove %s.", cacheInfoPath.c_str()); + + for (uint32_t i = 0; i < fileNumber; ++i) { + std::string fileName = m_modelName + std::to_string(i) + ".nncache"; + std::string cacheModelPath = cacheDir + fileName; + if (access(cacheModelPath.c_str(), 0) != 0) { + LOGW("The file %s does not exist, no need to delete the file.", cacheModelPath.c_str()); + continue; + } + + if (remove(cacheModelPath.c_str()) == -1) { + LOGE("NNCompiledCache::RemoveCacheFiles failed to remove the file %s, please delete the file manually.", + cacheModelPath.c_str()); + return OH_NNCORE_FAILED; + } + LOGI("NNCompiledCache::RemoveCacheFiles succeed to remove the file %s", cacheModelPath.c_str()); + } + return OH_NNCORE_SUCCESS; +} + +unsigned short NNCompiledCache::GetCrc16(const unsigned char* buffer, size_t length) const +{ + unsigned short crc16 = 0; + for (size_t i = 0; i < length; ++i) { + uint8_t tableIndex = ((crc16 >> OCT_UNIT) ^ *buffer++) & 0x00ff; + crc16 = (crc16 << OCT_UNIT) ^ CRC16_TAB[tableIndex]; + } + return crc16; +} + +OH_NNCore_ReturnCode NNCompiledCache::GetCacheFileLength(std::ifstream& ifs, int& fileSize) const +{ + ifs.seekg(0, std::ios::end); + if (!ifs.good()) { + LOGE("NNCompiledCache::GetCacheFileLength fail to set the position of the next character to be extracted from " + "the input stream."); + return OH_NNCORE_FAILED; + } + + int handleValue = ifs.tellg(); + if (handleValue == -1) { + LOGE("Compiled::GetCacheFileLength fail to get position of the input stream."); + return OH_NNCORE_INVALID_FILE; + } + + if ((handleValue > MAX_MODEL_SIZE) || (handleValue == NULL_PTR_LENGTH)) { + LOGE("NNCompiledCache::GetCacheFileLength failed, unable to read huge or empty input stream, get cache file " + "size=%d", + handleValue); + return OH_NNCORE_INVALID_FILE; + } + + fileSize = handleValue; + return OH_NNCORE_SUCCESS; +} +} // namespace NeuralNetworkBackend +} // namespace OHOS diff --git a/frameworks/native/nncompiled_cache.h b/frameworks/native/nncompiled_cache.h new file mode 100644 index 0000000000000000000000000000000000000000..b942e12f3b08d35b929164059171b7f858f4de40 --- /dev/null +++ b/frameworks/native/nncompiled_cache.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_BACKEND_NNCOMPILED_CACHE_H +#define NEURAL_NETWORK_BACKEND_NNCOMPILED_CACHE_H + +#include +#include +#include + +#include "compat/device.h" +#include "neural_network_runtime.h" +#include "tensor_desc.h" + +namespace OHOS { +namespace NeuralNetworkBackend { +const uint32_t INVALID_CAHCE_VERSION = UINT32_MAX; // UINT32_MAX is reserved for invalid cache version. + +struct NNCompiledCacheInfo { + uint64_t fileNumber{0}; + uint64_t version{0}; + uint64_t deviceId{0}; + std::vector modelCheckSum; +}; + +class NNCompiledCache { +public: + NNCompiledCache() = default; + ~NNCompiledCache() = default; + + OH_NNCore_ReturnCode Save(const std::vector& caches, + const std::string& cacheDir, + uint32_t version); + OH_NNCore_ReturnCode Restore(const std::string& cacheDir, + uint32_t version, + std::vector& caches); + + OH_NNCore_ReturnCode SetBackendName(const std::string& backendName); + void SetModelName(const std::string& modelName); + void SetInputTensorDescs(std::vector> inputTensorDescs); + void SetOutputTensorDescs(std::vector> outputTensorDescs); + std::vector> GetInputTensorDescs() const; + std::vector> GetOutputTensorDescs() const; + +private: + OH_NNCore_ReturnCode GenerateCacheFiles(const std::vector& caches, + const std::string& cacheDir, + uint32_t version) const; + OH_NNCore_ReturnCode GenerateCacheModel(const std::vector& caches, + std::unique_ptr& cacheInfo, + const std::string& cacheDir, + uint32_t version) const; + OH_NNCore_ReturnCode WriteCacheInfo(uint32_t cacheSize, + std::unique_ptr& cacheInfo, + const std::string& cacheDir) const; + OH_NNCore_ReturnCode CheckCacheInfo(NNCompiledCacheInfo& modelCacheInfo, const std::string& cacheInfoPath) const; + OH_NNCore_ReturnCode ReadCacheModelFile(const std::string& file, OHOS::NeuralNetworkRuntime::Buffer& cache) const; + OH_NNCore_ReturnCode RemoveCacheFiles(const std::string& cacheDir, uint32_t fileNumber) const; + unsigned short GetCrc16(const unsigned char* buffer, size_t length) const; + OH_NNCore_ReturnCode GetCacheFileLength(std::ifstream& ifs, int& fileSize) const; + +private: + size_t m_backendID{0}; + std::string m_backendName; + std::string m_modelName; + std::shared_ptr m_device{nullptr}; + std::vector> m_inputTensorDescs; + std::vector> m_outputTensorDescs; +}; + +} // namespace NeuralNetworkBackend +} // namespace OHOS + +#endif // NEURAL_NETWORK_BACKEND_NNCOMPILED_CACHE_H diff --git a/frameworks/native/nncompiler.cpp b/frameworks/native/nncompiler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9927f8945d64c5a93bfa01018834551a33f76d28 --- /dev/null +++ b/frameworks/native/nncompiler.cpp @@ -0,0 +1,206 @@ +#include "nncompiler.h" + +#include +#include +#include + +#include "mindir.h" +#include "compat/inner_model.h" +#include "nnoptions.h" +#include "nncompiled.h" +#include "compat/validation.h" + +namespace OHOS { +namespace NeuralNetworkBackend { +using namespace OHOS::NeuralNetworkCore; +using namespace OHOS::NeuralNetworkRuntime; + +NNCompiler::NNCompiler( + const std::shared_ptr& device, const std::string& backendName) + : m_backendName(backendName), + m_device(device) {} + +NNCompiler::~NNCompiler() +{ + if (m_prepareModel != nullptr) { + delete m_prepareModel; + m_prepareModel = nullptr; + } + + m_backendName.clear(); + m_cachePath.clear(); +} + +OH_NNCore_ReturnCode NNCompiler::SetOptions(const OH_NNCore_Options* options) +{ + if (m_isBuild) { + LOGE("Cannot set options after compiler build."); + return OH_NNCORE_OPERATION_FORBIDDEN; + } + + if (options == nullptr) { + return OH_NNCORE_INVALID_POINTER; + } + + const NNOptions* optionsImpl = reinterpret_cast(options); + OH_NNCore_ReturnCode ret = SetPerformance(optionsImpl->GetPerformanceMode()); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("[NNCompiler] Set performance mode failed."); + } + + ret = SetPriority(optionsImpl->GetPriority()); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("[NNCompiler] Set priority failed."); + } + + ret = SetEnableFp16(optionsImpl->GetEnabledFp16()); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("[NNCompiler] Set enabled fp16 failed."); + } + + m_options = const_cast(options); + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNCompiler::SetPerformance(OH_NNCore_PerformanceMode performance) +{ + if (m_device == nullptr) { + LOGE("[NNCompiler] Cannot set performance before set device, please set device first"); + return OH_NNCORE_OPERATION_FORBIDDEN; + } + + bool isSupportedPerformance {false}; + OH_NN_ReturnCode ret = m_device->IsPerformanceModeSupported(isSupportedPerformance); + if (ret != OH_NN_SUCCESS) { + LOGE("[NNCompiler] Call device %s failed.", m_backendName.c_str()); + return OH_NNCORE_FAILED; + } + + if (!isSupportedPerformance) { + LOGE("[NNCompiler] This device %s is not support performance setting.", m_backendName.c_str()); + return OH_NNCORE_OPERATION_FORBIDDEN; + } + + if (!Validation::ValidatePerformanceMode(static_cast(performance))) { + LOGE("[NNCompiler] SetPerformance passed invalid performance=%d", performance); + return OH_NNCORE_INVALID_PARAMETER; + } + + m_performance = performance; + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNCompiler::SetPriority(OH_NNCore_Priority priority) +{ + if (m_device == nullptr) { + LOGE("[NNCompiler] Cannot set priority before set device, please set device first"); + return OH_NNCORE_OPERATION_FORBIDDEN; + } + + bool isSupportedPriority {false}; + OH_NN_ReturnCode ret = m_device->IsPrioritySupported(isSupportedPriority); + if (ret != OH_NN_SUCCESS) { + LOGE("[NNCompiler] Call device %s failed.", m_backendName.c_str()); + return OH_NNCORE_FAILED; + } + + if (!isSupportedPriority) { + LOGE("[NNCompiler] This device %s is not support priority setting.", m_backendName.c_str()); + return OH_NNCORE_OPERATION_FORBIDDEN; + } + + if (!Validation::ValidatePriority(static_cast(priority))) { + LOGE("[NNCompiler] SetPriority passed invalid priority=%d", priority); + return OH_NNCORE_INVALID_PARAMETER; + } + + m_priority = priority; + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNCompiler::SetEnableFp16(bool isFp16) +{ + if (m_device == nullptr) { + LOGE("[NNCompiler] Cannot set enable fp16 before set device, please set device first"); + return OH_NNCORE_OPERATION_FORBIDDEN; + } + + bool isSupportedFp16 {false}; + OH_NN_ReturnCode ret = m_device->IsFloat16PrecisionSupported(isSupportedFp16); + if (ret != OH_NN_SUCCESS) { + LOGE("[NNCompiler] Call device %s failed.", m_backendName.c_str()); + return OH_NNCORE_FAILED; + } + + if (!isSupportedFp16) { + LOGE("[NNCompiler] This device %s is not support float16 precision setting.", m_backendName.c_str()); + return OH_NNCORE_OPERATION_FORBIDDEN; + } + + m_enableFp16 = isFp16; + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNCompiler::Build(const void* model, Compiled** compiled) +{ + if (m_isBuild) { + LOGE("[NNCompiler] Cannot build again."); + return OH_NNCORE_OPERATION_FORBIDDEN; + } + + const InnerModel* innerModel = reinterpret_cast(model); + std::shared_ptr liteGraph = innerModel->GetLiteGraphs(); + std::vector> inputTensors = innerModel->GetInputTensors(); + std::vector> outputTensors = innerModel->GetOutputTensors(); + void* metaGraph = innerModel->GetMetaGraph(); + Buffer quantBuffer = innerModel->GetQuantBuffer(); + + if ((liteGraph == nullptr) && (metaGraph == nullptr)) { + LOGE("[NNCompiler] Both liteGraph and metaGraph are nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + if ((liteGraph != nullptr) && (metaGraph != nullptr)) { + LOGE("[NNCompiler] Neither liteGraph nor metaGraph are nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + + OH_NN_ReturnCode ret {OH_NN_FAILED}; + ModelConfig config {m_enableFp16, static_cast(m_performance), + static_cast(m_priority)}; + std::shared_ptr preparedModel = nullptr; + if (liteGraph != nullptr) { + ret = m_device->PrepareModel(liteGraph, config, preparedModel); + } + if (metaGraph != nullptr) { + ret = m_device->PrepareModel(metaGraph, quantBuffer, config, preparedModel); + } + if (ret != OH_NN_SUCCESS) { + LOGE("[NNCompiler] Preparing model failed when normally building."); + return OH_NNCORE_FAILED; + } + + NNCompiled* nncompiled = new (std::nothrow) NNCompiled( + m_backendName, preparedModel, inputTensors, outputTensors, m_device); + if (nncompiled == nullptr) { + LOGE("[NNCompiler] Create nn compiled failed."); + return OH_NNCORE_NULL_PTR; + } + nncompiled->SetCompiledOptions(m_options); + *compiled = reinterpret_cast(nncompiled); + + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNCompiler::Build(const std::string& filePath, Compiled** compiled) +{ + return OH_NNCORE_OPERATION_FORBIDDEN; +} + +OH_NNCore_ReturnCode NNCompiler::Build(const void* modelData, size_t modelSize, Compiled** compiled) +{ + return OH_NNCORE_OPERATION_FORBIDDEN; +} + +} // NeuralNetworkBackend +} // OHOS \ No newline at end of file diff --git a/frameworks/native/nncompiler.h b/frameworks/native/nncompiler.h new file mode 100644 index 0000000000000000000000000000000000000000..6284033e45a1233c03de4d6dd01ee9900e9cba74 --- /dev/null +++ b/frameworks/native/nncompiler.h @@ -0,0 +1,39 @@ +#include "compiler.h" + +#include "compat/device.h" +#include "compat/prepared_model.h" +#include "compiled.h" +#include "neural_network_runtime.h" + +namespace OHOS { +namespace NeuralNetworkBackend { + +class NNCompiler : public OHOS::NeuralNetworkCore::Compiler { +public: + NNCompiler(const std::shared_ptr& device, const std::string& backendName); + ~NNCompiler(); + + OH_NNCore_ReturnCode SetOptions(const OH_NNCore_Options* options) override; + OH_NNCore_ReturnCode Build(const void* model, OHOS::NeuralNetworkCore::Compiled** compiled) override; + OH_NNCore_ReturnCode Build(const std::string& filePath, OHOS::NeuralNetworkCore::Compiled** compiled) override; + OH_NNCore_ReturnCode Build( + const void* modelData, size_t modelSize, OHOS::NeuralNetworkCore::Compiled** compiled) override; + +private: + OH_NNCore_ReturnCode SetPerformance(OH_NNCore_PerformanceMode performance); + OH_NNCore_ReturnCode SetPriority(OH_NNCore_Priority priority); + OH_NNCore_ReturnCode SetEnableFp16(bool isFp16); + +private: + bool m_isBuild {false}; + bool m_enableFp16 {false}; + std::string m_backendName; + std::string m_cachePath; + OH_NNCore_Options* m_options {nullptr}; + OH_NNCore_Priority m_priority {OH_NNCORE_PRIORITY_NONE}; + OH_NNCore_PerformanceMode m_performance {OH_NNCORE_PERFORMANCE_NONE}; + std::shared_ptr m_device {nullptr}; + OHOS::NeuralNetworkRuntime::PreparedModel* m_prepareModel {nullptr}; +}; +} // NeuralNetworkBackend +} // OHOS \ No newline at end of file diff --git a/frameworks/native/nnexecutor.cpp b/frameworks/native/nnexecutor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ada4f1e91f0cf9e3110add0db7a79cbc32d2a9a0 --- /dev/null +++ b/frameworks/native/nnexecutor.cpp @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "nnexecutor.h" +#include "nntensor.h" +#include "nnbackend.h" +#include "backend_manager.h" +#include "common/log.h" +#include "compat/cpp_type.h" +#include "v1_0/neural_network_runtime_type_compat.h" + +namespace OHOS { +namespace NeuralNetworkBackend { +NNExecutor::NNExecutor( + std::string backendName, std::shared_ptr preparedModel) +{ + m_backendName = backendName; + m_preparedModel = preparedModel; +} + + +OH_NNCore_ReturnCode NNExecutor::SetOnRunDone(OH_NNCore_OnRunDone onRunDone) +{ + LOGE("NNExecutor::SetOnRunDone failed, SetOnRunDone is not supported."); + return OH_NNCORE_UNSUPPORTED; +} + +OH_NNCore_ReturnCode NNExecutor::SetOnServiceDied(OH_NNCore_OnServiceDied onServiceDied) +{ + LOGE("NNExecutor::SetOnServiceDied failed, SetOnServiceDied is not supported."); + return OH_NNCORE_UNSUPPORTED; +} + +OH_NNCore_ReturnCode NNExecutor::SetOptions(const OH_NNCore_Options* options) +{ + LOGE("NNExecutor::SetExecutorOptions failed, SetExecutorOptions is not supported."); + return OH_NNCORE_UNSUPPORTED; +} + +OH_NNCore_ReturnCode NNExecutor::RunSync(OH_NNCore_Tensor* inputTensors[], size_t inputSize, + OH_NNCore_Tensor* outputTensors[], size_t outputSize) +{ + OH_NNCore_ReturnCode ret {OH_NNCORE_FAILED}; + ret = CheckInputDimRanges(inputTensors, inputSize); + if (ret != OH_NNCORE_UNSUPPORTED && ret != OH_NNCORE_SUCCESS) { + LOGE("NNExecutor::RunSync failed, failed to check input dim ranges."); + return ret; + } + + OHOS::NeuralNetworkRuntime::IOTensor tensor; + std::vector inputTensorsVec; + for (size_t i = 0; i < inputSize; ++i) { + inputTensorsVec.emplace_back(inputTensors[i]); + } + + std::vector outputTensorsVec; + for (size_t i = 0; i < outputSize; ++i) { + outputTensorsVec.emplace_back(outputTensors[i]); + } + + std::vector> outputsDims; + std::vector isSufficientDataBuffer; + auto oldRet = m_preparedModel->Run(inputTensorsVec, outputTensorsVec, outputsDims, isSufficientDataBuffer); + if (oldRet != OH_NN_SUCCESS) { + LOGE("NNExecutor::RunSync failed, failed to run in prepared model."); + return OH_NNCORE_FAILED; + } + + // Set the output NNTensor's dimensions from output IOTensor if it is dynamic. + // NNTensor::SetDimensions will check if the tensor buffer is enough for the new dimensions. + if (outputsDims.size() != outputSize) { + LOGE("NNExecutor::RunSync failed, size of outputsDims is not equal to outputTensors."); + return OH_NNCORE_INVALID_PARAMETER; + } + for (size_t i = 0; i < outputSize; ++i) { + NNTensor* nnTensor = reinterpret_cast(outputTensors[i]); + OHOS::NeuralNetworkCore::TensorDesc* nnTensorDesc = nnTensor->GetTensorDesc(); + if (nnTensorDesc == nullptr) { + LOGE("NNExecutor::RunSync failed, failed to get desc from tensor."); + return OH_NNCORE_NULL_PTR; + } + ret = nnTensorDesc->SetShape(outputsDims[i].data(), outputsDims[i].size()); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("NNExecutor::RunSync failed, error happened when setting output tensor's dimensions," + " output id: %zu.", i); + return ret; + } + } + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNExecutor::RunAsync(OH_NNCore_Tensor* inputTensors[], size_t inputSize, + OH_NNCore_Tensor* outputTensors[], size_t outputSize, int32_t timeout, void* userData) +{ + LOGE("NNExecutor::RunAsync failed, RunAsync is not supported."); + return OH_NNCORE_UNSUPPORTED; +} + +OH_NNCore_ReturnCode NNExecutor::GetBackendName(std::string& backendName) +{ + if (m_backendName.empty()) { + LOGE("NNExecutor::GetBackendName failed, m_backendName is empty."); + return OH_NNCORE_INVALID_PARAMETER; + } + backendName = m_backendName; + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNExecutor::CheckInputDimRanges(OH_NNCore_Tensor* inputTensors[], size_t inputSize) const +{ + std::vector> minInputDims; + std::vector> maxInputDims; + OH_NN_ReturnCode oldRet = m_preparedModel->GetInputDimRanges(minInputDims, maxInputDims); + if (oldRet != OH_NN_SUCCESS) { + LOGW("NNExecutor::CheckInputDimRanges failed, current version don't support get input dim ranges."); + return OH_NNCORE_UNSUPPORTED; + } + + if (inputSize != minInputDims.size()) { + LOGE("NNExecutor::CheckInputDimRanges failed, size of minInputDims is not equal to inputSize."); + return OH_NNCORE_INVALID_PARAMETER; + } + + if (inputSize != maxInputDims.size()) { + LOGE("NNExecutor::CheckInputDimRanges failed, size of maxInputDims is not equal to inputSize."); + return OH_NNCORE_INVALID_PARAMETER; + } + + const NNTensor* nnTensor = nullptr; + OH_NNCore_ReturnCode ret {OH_NNCORE_FAILED}; + for (size_t i = 0; i < inputSize; ++i) { + const std::vector& minSingleInputDims = minInputDims[i]; + const std::vector& maxSingleInputDims = maxInputDims[i]; + nnTensor = reinterpret_cast(inputTensors[i]); + if (nnTensor == nullptr) { + LOGE("NNExecutor::CheckInputDimRanges failed, input %{public}zu is nullptr.", i); + return OH_NNCORE_NULL_PTR; + } + ret = nnTensor->CheckDimRanges(minSingleInputDims, maxSingleInputDims); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("NNExecutor::CheckInputDimRanges failed, failed to check input dim ranges of input %{public}zu", i); + return ret; + } + } + + return OH_NNCORE_SUCCESS; +} +} // namespace NeuralNetworkBackend +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/nnexecutor.h b/frameworks/native/nnexecutor.h new file mode 100644 index 0000000000000000000000000000000000000000..abc071bd4f9a8055b4f4280d1b51bb13e60a2b95 --- /dev/null +++ b/frameworks/native/nnexecutor.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_BACKEND_EXECUTOR_H +#define NEURAL_NETWORK_BACKEND_EXECUTOR_H + +#include "executor.h" +#include "compat/device.h" +#include "compat/prepared_model.h" + +namespace OHOS { +namespace NeuralNetworkBackend { +class NNExecutor : public OHOS::NeuralNetworkCore::Executor { +public: + NNExecutor(std::string backendName, + std::shared_ptr preparedModel); + virtual ~NNExecutor() = default; + + virtual OH_NNCore_ReturnCode SetOnRunDone(OH_NNCore_OnRunDone onRunDone) override; + virtual OH_NNCore_ReturnCode SetOnServiceDied(OH_NNCore_OnServiceDied onServiceDied) override; + virtual OH_NNCore_ReturnCode SetOptions(const OH_NNCore_Options* options) override; + virtual OH_NNCore_ReturnCode RunSync(OH_NNCore_Tensor* inputTensors[], + size_t inputSize, + OH_NNCore_Tensor* outputTensors[], + size_t outputSize) override; + virtual OH_NNCore_ReturnCode RunAsync(OH_NNCore_Tensor* inputTensors[], + size_t inputSize, + OH_NNCore_Tensor* outputTensors[], + size_t outputSize, + int32_t timeout, + void* userData) override; + virtual OH_NNCore_ReturnCode GetBackendName(std::string& backendName) override; + +private: + OH_NNCore_ReturnCode CheckInputDimRanges(OH_NNCore_Tensor* inputTensors[], size_t inputSize) const; + +private: + std::string m_backendName; + std::shared_ptr m_preparedModel; + // std::vector> m_modelInputs; + // std::vector> m_modelOutputs; +}; +} // namespace NeuralNetworkBackend +} // namespace OHOS +#endif // NEURAL_NETWORK_BACKEND_EXECUTOR_H diff --git a/frameworks/native/nnmemory.cpp b/frameworks/native/nnmemory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dd759f3fcd807818e234e8e98bbc33db347b7b83 --- /dev/null +++ b/frameworks/native/nnmemory.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nnmemory.h" +#include "common/log.h" + +#include +#include + +namespace OHOS { +namespace NeuralNetworkBackend { +const size_t ALLOCATE_BUFFER_LIMIT = 1024 * 1024 * 1024; +NNMemory::NNMemory(int fd, size_t length) +{ + m_fd = fd; + m_length = length; +} + +NNMemory::~NNMemory() +{ + Clear(); +} + +void* NNMemory::GetData() +{ + if (m_data != nullptr) { + return m_data; + } + + if (m_fd < 0) { + LOGE("Invalid fd, fd must greater than 0."); + return nullptr; + } + + if (m_length <= 0 || m_length > ALLOCATE_BUFFER_LIMIT) { + LOGE("Invalid buffer size, it must greater than 0 and less than 1Gb. length=%zu", m_length); + return nullptr; + } + + m_data = mmap(nullptr, m_length, PROT_READ | PROT_WRITE, MAP_SHARED, m_fd, 0); + if (m_data == MAP_FAILED) { + LOGE("Map fd to address failed."); + m_data = nullptr; + return nullptr; + } + return m_data; +} + +size_t NNMemory::GetLength() const +{ + return m_length; +} + +int NNMemory::GetFd() const +{ + return m_fd; +} + +OH_NNCore_ReturnCode NNMemory::Clear() +{ + if (m_data == nullptr) { + LOGI("No need to clear, data is nullptr."); + return OH_NNCORE_SUCCESS; + } + + auto unmapResult = munmap(m_data, m_length); + if (unmapResult != 0) { + LOGE("NNMemory::Clear failed. Please try again."); + return OH_NNCORE_MEMORY_EXCEPTION; + } + m_data = nullptr; + m_length = 0; + + if (close(m_fd) != 0) { + LOGE("NNMemory::Clear failed. fd=%{public}d", m_fd); + return OH_NNCORE_MEMORY_EXCEPTION; + } + m_fd = 0; + + return OH_NNCORE_SUCCESS; +} +} // namespace NeuralNetworkBackend +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/nnmemory.h b/frameworks/native/nnmemory.h new file mode 100644 index 0000000000000000000000000000000000000000..502105996ee388d10db5ba86bbd396e3ac8a4158 --- /dev/null +++ b/frameworks/native/nnmemory.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_BACKEND_MEMORY_H +#define NEURAL_NETWORK_BACKEND_MEMORY_H + +#include "v2_0/neural_network_core_type.h" + +namespace OHOS { +namespace NeuralNetworkBackend { +class NNMemory { +public: + NNMemory(int fd, size_t length); + ~NNMemory(); + + void* GetData(); + size_t GetLength() const; + int GetFd() const; + + OH_NNCore_ReturnCode Clear(); + +private: + int m_fd{0}; + void* m_data{nullptr}; + size_t m_length{0}; +}; +} // namespace NeuralNetworkBackend +} // namespace OHOS +#endif // NEURAL_NETWORK_BACKEND_MEMORY_H \ No newline at end of file diff --git a/frameworks/native/nnoptions.cpp b/frameworks/native/nnoptions.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ac4a096356a8e6d7802caa5deca3c717a29149a3 --- /dev/null +++ b/frameworks/native/nnoptions.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nnoptions.h" +#include "compat/validation.h" +#include "v2_0/neural_network_runtime_type.h" + +namespace OHOS { +namespace NeuralNetworkBackend { +using namespace OHOS::NeuralNetworkCore; +using namespace OHOS::NeuralNetworkRuntime; + +OH_NNCore_ReturnCode NNOptions::SetPerformanceMode(OH_NNCore_PerformanceMode performance) +{ + if (!Validation::ValidatePerformanceMode(static_cast(performance))) { + LOGE("[NNOptions] SetPerformance passed invalid performance=%d", performance); + return OH_NNCORE_INVALID_PARAMETER; + } + + m_performanceMode = performance; + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNOptions::SetPriority(OH_NNCore_Priority priority) +{ + if (!Validation::ValidatePriority(static_cast(priority))) { + LOGE("[NNOptions] SetPriority passed invalid priority=%d", priority); + return OH_NNCORE_INVALID_PARAMETER; + } + + m_priority = priority; + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNOptions::SetEnableFp16(bool enableFp16) +{ + m_enableFp16 = enableFp16; + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNOptions::GetBackendName(std::string& backendName) +{ + backendName = m_backendName; + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNOptions::SetCacheVersion(uint32_t version) +{ + m_cacheVersion = version; + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_PerformanceMode NNOptions::GetPerformanceMode() const +{ + return m_performanceMode; +} + +OH_NNCore_Priority NNOptions::GetPriority() const +{ + return m_priority; +} + +bool NNOptions::GetEnabledFp16() const +{ + return m_enableFp16; +} + +uint32_t NNOptions::GetCacheVersion() const +{ + return m_cacheVersion; +} +} // namespace NeuralNetworkBackend +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/nnoptions.h b/frameworks/native/nnoptions.h new file mode 100644 index 0000000000000000000000000000000000000000..3582808cab2dc949b0cb2686aec2755be2ea9cf9 --- /dev/null +++ b/frameworks/native/nnoptions.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_BACKEND_OPTIONS_H +#define NEURAL_NETWORK_BACKEND_OPTIONS_H + +#include "options.h" + +namespace OHOS { +namespace NeuralNetworkBackend { +class NNOptions : public OHOS::NeuralNetworkCore::Options { +public: + explicit NNOptions(std::string backendName) : m_backendName(backendName) {}; + ~NNOptions() = default; + + OH_NNCore_ReturnCode SetPerformanceMode(OH_NNCore_PerformanceMode performance) override; + OH_NNCore_ReturnCode SetPriority(OH_NNCore_Priority priority) override; + OH_NNCore_ReturnCode SetEnableFp16(bool enableFp16) override; + OH_NNCore_ReturnCode GetBackendName(std::string& backendName) override; + + OH_NNCore_ReturnCode SetCacheVersion(uint32_t version); + OH_NNCore_PerformanceMode GetPerformanceMode() const; + OH_NNCore_Priority GetPriority() const; + bool GetEnabledFp16() const; + uint32_t GetCacheVersion() const; + +private: + OH_NNCore_PerformanceMode m_performanceMode {OH_NNCORE_PERFORMANCE_NONE}; + OH_NNCore_Priority m_priority {OH_NNCORE_PRIORITY_NONE}; + bool m_enableFp16 {false}; + std::string m_backendName; + uint32_t m_cacheVersion {0}; +}; +} // namespace NeuralNetworkBackend +} // namespace OHOS + +#endif // NEURAL_NETWORK_BACKEND_OPTIONS_H \ No newline at end of file diff --git a/frameworks/native/nntensor.cpp b/frameworks/native/nntensor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..615f8a498f6c1dd3f9c4b9f6d5d248004e687a0d --- /dev/null +++ b/frameworks/native/nntensor.cpp @@ -0,0 +1,313 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nnbackend.h" +#include "nntensor.h" +#include "common/log.h" +#include "backend_manager.h" +#include +#include +#include "v1_0/neural_network_runtime_type_compat.h" + +namespace OHOS { +namespace NeuralNetworkBackend { +const size_t ALLOCATE_BUFFER_LIMIT = 1024 * 1024 * 1024; + +NNTensor::~NNTensor() +{ + if (!m_isUserData) { + ReleaseMemory(); + } + + m_tensorDesc = nullptr; + m_data = nullptr; + m_fd = 0; + m_offset = 0; + m_size = 0; + m_isUserData = false; +} + +OH_NNCore_ReturnCode NNTensor::CreateData() +{ + if (m_data != nullptr) { + LOGE("NNTensor::CreateData failed, m_data has been created before."); + return OH_NNCORE_FAILED; + } + + size_t byteSize = 0; + auto ret = m_tensorDesc->GetByteSize(&byteSize); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("NNTensor::CreateData failed, failed to get byte size from tensorDesc."); + return ret; + } + if (byteSize > ALLOCATE_BUFFER_LIMIT) { + LOGE("NNTensor::CreateData failed, Invalid buffer size, " + "it must greater than 0 and less than 1Gb. length=%{public}zu", byteSize); + return OH_NNCORE_INVALID_PARAMETER; + } + + ret = AllocateMemory(byteSize); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("NNTensor::CreateData failed, failed to allocate memory."); + return ret; + } + m_isUserData = false; + return OH_NNCORE_SUCCESS; +} +OH_NNCore_ReturnCode NNTensor::CreateData(size_t size) +{ + if (m_data != nullptr) { + LOGE("NNTensor::CreateData failed, m_data has been created before."); + return OH_NNCORE_FAILED; + } + if (size > ALLOCATE_BUFFER_LIMIT) { + LOGE("NNTensor::CreateData failed, Invalid buffer size, " + "it must greater than 0 and less than 1Gb. length=%{public}zu", size); + return OH_NNCORE_INVALID_PARAMETER; + } + + auto ret = AllocateMemory(size); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("NNTensor::CreateData failed, failed to allocate memory."); + return ret; + } + m_isUserData = false; + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNTensor::CreateData(int fd, size_t size, size_t offset) +{ + if (m_data != nullptr) { + LOGE("NNTensor::CreateData failed, m_data has been created before."); + return OH_NNCORE_FAILED; + } + + size_t byteSize = 0; + auto ret = m_tensorDesc->GetByteSize(&byteSize); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("NNTensor::CreateData failed, failed to get byte size from tensorDesc."); + return ret; + } + if ((size - offset) < byteSize) { + LOGE("NNTensor::CreateData failed, size of fd is insufficient."); + return OH_NNCORE_INVALID_PARAMETER; + } + + m_data = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset); + if (m_data == MAP_FAILED) { + LOGE("NNTensor::AllocateMemory failed, Map fd to address failed."); + m_data = nullptr; + return OH_NNCORE_MEMORY_EXCEPTION; + } + + m_fd = fd; + m_size = size; + m_offset = offset; + m_isUserData = true; + return OH_NNCORE_SUCCESS; +} + +OHOS::NeuralNetworkCore::TensorDesc* NNTensor::GetTensorDesc() const +{ + return m_tensorDesc; +} + +void* NNTensor::GetData() const +{ + return m_data; +} + +int NNTensor::GetFd() const +{ + return m_fd; +} + +size_t NNTensor::GetSize() const +{ + return m_size; +} + +size_t NNTensor::GetOffset() const +{ + return m_offset; +} + +OH_NNCore_ReturnCode NNTensor::AllocateMemory(size_t length) +{ + OHOS::NeuralNetworkCore::BackendManager& backendManager = OHOS::NeuralNetworkCore::BackendManager::GetInstance(); + std::shared_ptr backend = backendManager.GetBackend(m_backendName); + if (backend == nullptr) { + LOGE("NNTensor::AllocateMemory failed, failed to get backend of %{public}s.", m_backendName.c_str()); + return OH_NNCORE_NULL_PTR; + } + + // todo backend中拿到device 分配内存 + auto* nnBackend = dynamic_cast(backend.get()); + if (nnBackend == nullptr) { + LOGE("NNTensor::AllocateMemory failed, failed to convert backend to nnbackend."); + return OH_NNCORE_NULL_PTR; + } + auto device = nnBackend->GetDevice(); + if (device == nullptr) { + LOGE("NNTensor::AllocateMemory failed, device of nnbackend is nullptr."); + return OH_NNCORE_NULL_PTR; + } + int fd = 0; + auto oldRet = device->AllocateBuffer(length, fd); + if (oldRet != OH_NN_SUCCESS) { + LOGE("NNTensor::AllocateMemory failed, failed to allocate buffer."); + return OH_NNCORE_MEMORY_EXCEPTION; + } + if (fd < 0) { + LOGE("NNTensor::AllocateMemory failed, fd must greater than 0."); + return OH_NNCORE_INVALID_PARAMETER; + } + + m_data = mmap(nullptr, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (m_data == MAP_FAILED) { + LOGE("NNTensor::AllocateMemory failed, Map fd to address failed."); + m_data = nullptr; + return OH_NNCORE_MEMORY_EXCEPTION; + } + m_fd = fd; + m_offset = 0; + m_size = length; + + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNTensor::ReleaseMemory() +{ + if (m_size == 0 || m_data == nullptr) { + return OH_NNCORE_SUCCESS; + } + if (m_fd < 0) { + LOGE("NNTensor::ReleaseMemory failed, m_fd must greater than 0."); + return OH_NNCORE_INVALID_PARAMETER; + } + + OHOS::NeuralNetworkCore::BackendManager& backendManager = OHOS::NeuralNetworkCore::BackendManager::GetInstance(); + std::shared_ptr backend = backendManager.GetBackend(m_backendName); + if (backend == nullptr) { + LOGE("NNTensor::ReleaseMemory failed, failed to get backend of %{public}s.", m_backendName.c_str()); + return OH_NNCORE_NULL_PTR; + } + // todo backend中拿到device 分配内存 + auto* nnrtBackend = dynamic_cast(backend.get()); + if (nnrtBackend == nullptr) { + LOGE("NNTensor::ReleaseMemory failed, failed to convert backend to nnbackend."); + return OH_NNCORE_NULL_PTR; + } + auto device = nnrtBackend->GetDevice(); + if (device == nullptr) { + LOGE(""); + return OH_NNCORE_NULL_PTR; + } + auto oldRet = device->ReleaseBuffer(m_fd, m_size); + if (oldRet != OH_NN_SUCCESS) { + LOGE("NNTensor::ReleaseMemory failed, failed to release buffer."); + return OH_NNCORE_MEMORY_EXCEPTION; + } + + auto unmapResult = munmap(m_data, m_size); + if (unmapResult != 0) { + LOGE("NNTensor::ReleaseMemory failed. Please try again."); + return OH_NNCORE_MEMORY_EXCEPTION; + } + m_data = nullptr; + m_size = 0; + + if (close(m_fd) != 0) { + LOGE("NNTensor::ReleaseMemory failed. fd=%{public}d", m_fd); + return OH_NNCORE_MEMORY_EXCEPTION; + } + m_fd = 0; + + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode NNTensor::GetBackendName(std::string& backendName) const +{ + if (m_backendName.empty()) { + LOGE("NNTensor::GetBackendName failed, m_backendName is empty."); + return OH_NNCORE_INVALID_PARAMETER; + } + backendName = m_backendName; + return OH_NNCORE_SUCCESS; +} + +bool NNTensor::CheckTensorData() const +{ + if (m_tensorDesc == nullptr) { + LOGE("NNTensor::CheckTensorData failed, m_tensorDesc is nullptr."); + return false; + } + + size_t byteSize = 0; + auto ret = m_tensorDesc->GetByteSize(&byteSize); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("NNTensor::CheckTensorData failed, failed to get byte size from tensorDesc."); + return false; + } + if ((m_size - m_offset) < byteSize) { + LOGE("NNTensor::CheckTensorData failed, m_size is less than byte size."); + return false; + } + + if (m_data == nullptr) { + LOGE("NNTensor::CheckTensorData failed, m_data is nullptr."); + return false; + } + + if (m_fd < 0) { + LOGE("NNTensor::CheckTensorData failed, m_fd is less than zero."); + return false; + } + + return true; +} + +OH_NNCore_ReturnCode NNTensor::CheckDimRanges( + const std::vector& minDimRanges, const std::vector& maxDimRanges) const +{ + if (m_tensorDesc == nullptr) { + LOGE("NNTensor::CheckInputDimRanges failed, m_tensorDesc is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + int32_t* shape = nullptr; + size_t shapeSize = 0; + auto ret = m_tensorDesc->GetShape(&shape, &shapeSize); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("NNTensor::CheckInputDimRanges failed, failed to get shape from desc."); + return ret; + } + for (size_t j = 0; j < shapeSize; ++j) { + // Dimensions cannot be negative + if (shape[j] < 0) { + LOGE("Dimension %{public}zu is %{public}d.", j, shape[j]); + return OH_NNCORE_INVALID_PARAMETER; + } + uint32_t dim = static_cast(shape[j]); + if (dim < minDimRanges[j] || dim > maxDimRanges[j]) { + LOGE("Dimension %{public}zu is %{public}u, which is out of range " + "[%{public}u, %{public}u]", j, dim, minDimRanges[j], maxDimRanges[j]); + return OH_NNCORE_INVALID_PARAMETER; + } + } + + return OH_NNCORE_SUCCESS; +} +} // namespace NeuralNetworkBackend +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/nntensor.h b/frameworks/native/nntensor.h new file mode 100644 index 0000000000000000000000000000000000000000..d6acd447d4cdb46208403ec08dbad4fba8513343 --- /dev/null +++ b/frameworks/native/nntensor.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_BACKEND_TENSOR_H +#define NEURAL_NETWORK_BACKEND_TENSOR_H + +#include "tensor.h" +#include + +namespace OHOS { +namespace NeuralNetworkBackend { +class NNTensor : public OHOS::NeuralNetworkCore::Tensor { +public: + NNTensor(const std::string& backendName, OHOS::NeuralNetworkCore::TensorDesc* tensorDesc) : + m_backendName(backendName), m_tensorDesc(tensorDesc) {} + virtual ~NNTensor(); + + OH_NNCore_ReturnCode CreateData() override; + OH_NNCore_ReturnCode CreateData(size_t size) override; + OH_NNCore_ReturnCode CreateData(int fd, size_t size, size_t offset) override; + + OHOS::NeuralNetworkCore::TensorDesc* GetTensorDesc() const override; + void* GetData() const override; + int GetFd() const override; + size_t GetSize() const override; + size_t GetOffset() const override; + OH_NNCore_ReturnCode GetBackendName(std::string& backendName) const override; + + bool CheckTensorData() const; + + OH_NNCore_ReturnCode CheckDimRanges(const std::vector& minDimRanges, + const std::vector& maxDimRanges) const; + +private: + OH_NNCore_ReturnCode AllocateMemory(size_t length); + OH_NNCore_ReturnCode ReleaseMemory(); + +private: + std::string m_backendName; + OHOS::NeuralNetworkCore::TensorDesc* m_tensorDesc{nullptr}; + void* m_data{nullptr}; + int m_fd{0}; + size_t m_size{0}; + size_t m_offset{0}; + bool m_isUserData{false}; +}; +} // namespace NeuralNetworkBackend +} // namespace OHOS +#endif // NEURAL_NETWORK_BACKEND_TENSOR_H \ No newline at end of file diff --git a/frameworks/native/ops/add_builder.cpp b/frameworks/native/ops/add_builder.cpp index 96dd2951b2f359935712f85fcd03ba56596ceb95..fa1e055257647acb92938f4b34668df3e9a63455 100644 --- a/frameworks/native/ops/add_builder.cpp +++ b/frameworks/native/ops/add_builder.cpp @@ -15,8 +15,8 @@ #include "add_builder.h" -#include "frameworks/native/transform.h" -#include "frameworks/native/validation.h" +#include "frameworks/native/compat/transform.h" +#include "frameworks/native/compat/validation.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/add_builder.h b/frameworks/native/ops/add_builder.h index c08d4d9741121eab58d3d54012d9f126178875fd..6d9f6980f54ca51c43e916b67f04b5c8f42ce83a 100644 --- a/frameworks/native/ops/add_builder.h +++ b/frameworks/native/ops/add_builder.h @@ -18,8 +18,8 @@ #include "mindir.h" -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/argmax_builder.h b/frameworks/native/ops/argmax_builder.h index 73139e383129f9e94be1d7e06b9586f84344beda..c7ce3610f4ffbdab819edb3f8c6c2c991d0fd61e 100644 --- a/frameworks/native/ops/argmax_builder.h +++ b/frameworks/native/ops/argmax_builder.h @@ -18,8 +18,8 @@ #include "mindir.h" -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/avgpool_builder.h b/frameworks/native/ops/avgpool_builder.h index fc58d41478ef02cd080c2650855d0bc262c89009..b32b5e6e83ae8434533d0b4eca39aabe1e8a932e 100644 --- a/frameworks/native/ops/avgpool_builder.h +++ b/frameworks/native/ops/avgpool_builder.h @@ -17,7 +17,7 @@ #define NEURAL_NETWORK_AVGPOOL_BUILDER_H #include "pooling_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/batch_to_space_nd_builder.h b/frameworks/native/ops/batch_to_space_nd_builder.h index beab53a68b74ea6049d81366275ad3f4867147eb..d6b9ac2e1f0c679db595dc484ca5633faacd96cc 100644 --- a/frameworks/native/ops/batch_to_space_nd_builder.h +++ b/frameworks/native/ops/batch_to_space_nd_builder.h @@ -18,8 +18,8 @@ #include "mindir.h" -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/batchnorm_builder.cpp b/frameworks/native/ops/batchnorm_builder.cpp index 1fd5997f0d6ef8dee1e85077524de4a97ddaac23..1d2c5d210f35422ffdffbb900edb5a4407d442fd 100644 --- a/frameworks/native/ops/batchnorm_builder.cpp +++ b/frameworks/native/ops/batchnorm_builder.cpp @@ -17,7 +17,7 @@ #include "mindir.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/batchnorm_builder.h b/frameworks/native/ops/batchnorm_builder.h index c8b4e9c31c36a91d843d0c8a711a9d22a23df9c1..3a626b02054ad3c5c0ca2dfdb4cf5856dfb267fe 100644 --- a/frameworks/native/ops/batchnorm_builder.h +++ b/frameworks/native/ops/batchnorm_builder.h @@ -16,7 +16,7 @@ #ifndef NEURAL_NETWORK_RUNTIME_BATHNORM_BUILDER_H #define NEURAL_NETWORK_RUNTIME_BATHNORM_BUILDER_H -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/bias_add_builder.h b/frameworks/native/ops/bias_add_builder.h index 410bfe88aa9655ac77c16e8d7e48fa7ba332ce07..90198d11d44fce8caa20ed7f36d80d316bf2fdc4 100644 --- a/frameworks/native/ops/bias_add_builder.h +++ b/frameworks/native/ops/bias_add_builder.h @@ -18,8 +18,8 @@ #include "mindir.h" -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/cast_builder.cpp b/frameworks/native/ops/cast_builder.cpp index 6336926209671c077fe40afd083ba5cfaab5f097..ba846bf79a20952ff7d6844704a6896648749fcb 100644 --- a/frameworks/native/ops/cast_builder.cpp +++ b/frameworks/native/ops/cast_builder.cpp @@ -15,8 +15,8 @@ #include "cast_builder.h" -#include "frameworks/native/transform.h" -#include "frameworks/native/validation.h" +#include "frameworks/native/compat/transform.h" +#include "frameworks/native/compat/validation.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/cast_builder.h b/frameworks/native/ops/cast_builder.h index 09682db5400e2a23dcb45b68cbb2c652657f3662..ab6c98976258a40902ead0c7dbb131b44d290199 100644 --- a/frameworks/native/ops/cast_builder.h +++ b/frameworks/native/ops/cast_builder.h @@ -18,8 +18,8 @@ #include "mindir.h" -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/concat_builder.h b/frameworks/native/ops/concat_builder.h index c80a53a6e0744f1606c35f0e70e2de2ab06f5cb5..349859288f7ccf706809c2c939c14d125edb2fd7 100644 --- a/frameworks/native/ops/concat_builder.h +++ b/frameworks/native/ops/concat_builder.h @@ -18,8 +18,8 @@ #include "mindir.h" -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/conv2d_builder.cpp b/frameworks/native/ops/conv2d_builder.cpp index df2394653a8fd4e24855130792c29f496dc6e693..763f91ce9b9a84032817f2c3990a0b22ee7c43b9 100644 --- a/frameworks/native/ops/conv2d_builder.cpp +++ b/frameworks/native/ops/conv2d_builder.cpp @@ -15,8 +15,8 @@ #include "conv2d_builder.h" -#include "frameworks/native/transform.h" -#include "frameworks/native/validation.h" +#include "frameworks/native/compat/transform.h" +#include "frameworks/native/compat/validation.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/conv2d_builder.h b/frameworks/native/ops/conv2d_builder.h index 412427ee9e53a1a2db7de76e47ae95ab3ced4c81..082d7008411a2fcf97c10b733e93ecd93e1f4053 100644 --- a/frameworks/native/ops/conv2d_builder.h +++ b/frameworks/native/ops/conv2d_builder.h @@ -16,8 +16,8 @@ #ifndef NEURAL_NETWORK_RUNTIME_CONV2D_BUILDER_H #define NEURAL_NETWORK_RUNTIME_CONV2D_BUILDER_H -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" #include "mindir.h" namespace OHOS { diff --git a/frameworks/native/ops/conv2d_transpose_builder.cpp b/frameworks/native/ops/conv2d_transpose_builder.cpp index 9111b5570c6e548b7706045ef2505de97f16726e..1e73bd623bada58c8b599092817feb77d5d5c61b 100644 --- a/frameworks/native/ops/conv2d_transpose_builder.cpp +++ b/frameworks/native/ops/conv2d_transpose_builder.cpp @@ -15,8 +15,8 @@ #include "conv2d_transpose_builder.h" -#include "frameworks/native/transform.h" -#include "frameworks/native/validation.h" +#include "frameworks/native/compat/transform.h" +#include "frameworks/native/compat/validation.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/conv2d_transpose_builder.h b/frameworks/native/ops/conv2d_transpose_builder.h index f54cb509ae41d1a8cba413db658bad24e9379801..bb1d4ce8d70b7b5e3d7ea276dcadf25261736399 100644 --- a/frameworks/native/ops/conv2d_transpose_builder.h +++ b/frameworks/native/ops/conv2d_transpose_builder.h @@ -16,8 +16,8 @@ #ifndef NEURAL_NETWORK_RUNTIME_CONV2DTRANSPOSE_BUILDER_H #define NEURAL_NETWORK_RUNTIME_CONV2DTRANSPOSE_BUILDER_H -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" #include "mindir.h" namespace OHOS { diff --git a/frameworks/native/ops/depthwise_conv2d_native_builder.cpp b/frameworks/native/ops/depthwise_conv2d_native_builder.cpp index d1fbeb89c3f0415dbe1de8a35dd5ce513cdf2247..49c4d9e9dd53a7f805598b6b2a2fcdfd7e8bf53a 100644 --- a/frameworks/native/ops/depthwise_conv2d_native_builder.cpp +++ b/frameworks/native/ops/depthwise_conv2d_native_builder.cpp @@ -15,8 +15,8 @@ #include "depthwise_conv2d_native_builder.h" -#include "frameworks/native/transform.h" -#include "frameworks/native/validation.h" +#include "frameworks/native/compat/transform.h" +#include "frameworks/native/compat/validation.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/depthwise_conv2d_native_builder.h b/frameworks/native/ops/depthwise_conv2d_native_builder.h index f1663f4694331048c7a1dddea66031244649717a..c65c6a2fb317aac9647b20574fd6e1d79d183731 100644 --- a/frameworks/native/ops/depthwise_conv2d_native_builder.h +++ b/frameworks/native/ops/depthwise_conv2d_native_builder.h @@ -16,8 +16,8 @@ #ifndef NEURAL_NETWORK_RUNTIME_DEPTHWISE_CONV2D_NATIVE_BUILDER_H #define NEURAL_NETWORK_RUNTIME_DEPTHWISE_CONV2D_NATIVE_BUILDER_H -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" #include "mindir.h" namespace OHOS { diff --git a/frameworks/native/ops/div_builder.cpp b/frameworks/native/ops/div_builder.cpp index 17dd34e26f8d7e5bcfba0bd5866b811e2cc67e3b..333d88764a655e467760b032839ead2735c30b75 100644 --- a/frameworks/native/ops/div_builder.cpp +++ b/frameworks/native/ops/div_builder.cpp @@ -15,8 +15,8 @@ #include "div_builder.h" -#include "frameworks/native/transform.h" -#include "frameworks/native/validation.h" +#include "frameworks/native/compat/transform.h" +#include "frameworks/native/compat/validation.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/div_builder.h b/frameworks/native/ops/div_builder.h index 3c0905c51874484a065421a8ca56d600194c4942..63b726a9af7beee1fc2899be29a2ddc8328d049d 100644 --- a/frameworks/native/ops/div_builder.h +++ b/frameworks/native/ops/div_builder.h @@ -18,8 +18,8 @@ #include "mindir.h" -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/eltwise_builder.h b/frameworks/native/ops/eltwise_builder.h index 09ff0d13fd5d4217fc5ce4f5b8a2800934881f94..f3216cd72870a1efda1d5a11dbe4f942d999a2b4 100644 --- a/frameworks/native/ops/eltwise_builder.h +++ b/frameworks/native/ops/eltwise_builder.h @@ -18,8 +18,8 @@ #include "mindir.h" -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/expandims_builder.h b/frameworks/native/ops/expandims_builder.h index 4e16b9b76b0c8b656a6b0d049de696697144daf1..9ac7c4dc52dfe08ada2d9c8629a6c7cf22c9933d 100644 --- a/frameworks/native/ops/expandims_builder.h +++ b/frameworks/native/ops/expandims_builder.h @@ -18,8 +18,8 @@ #include "mindir.h" -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/fill_builder.cpp b/frameworks/native/ops/fill_builder.cpp index 83c085cd0ffa3285aafe522d0048bce6b4991d21..84411dd5a971d2dd3e15e9a0b646c4c051b19042 100644 --- a/frameworks/native/ops/fill_builder.cpp +++ b/frameworks/native/ops/fill_builder.cpp @@ -17,7 +17,7 @@ #include "mindir.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/fill_builder.h b/frameworks/native/ops/fill_builder.h index 8e9f2241eed6f72548beb6d2176a617a52cd12a0..0ea1cb43fd6013b1d740b21fdda278860d66e053 100644 --- a/frameworks/native/ops/fill_builder.h +++ b/frameworks/native/ops/fill_builder.h @@ -16,7 +16,7 @@ #ifndef NEURAL_NETWORK_RUNTIME_FILL_BUILDER_H #define NEURAL_NETWORK_RUNTIME_FILL_BUILDER_H -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/fullconnection_builder.cpp b/frameworks/native/ops/fullconnection_builder.cpp index ce464a3f2f120b81c0fc3f1e2707fb3599280096..a0daadfbdf220f275a9b3672b42f6f21b5963163 100644 --- a/frameworks/native/ops/fullconnection_builder.cpp +++ b/frameworks/native/ops/fullconnection_builder.cpp @@ -15,8 +15,8 @@ #include "fullconnection_builder.h" -#include "frameworks/native/transform.h" -#include "frameworks/native/validation.h" +#include "frameworks/native/compat/transform.h" +#include "frameworks/native/compat/validation.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/fullconnection_builder.h b/frameworks/native/ops/fullconnection_builder.h index 50eaa38c62b200d947efe1e3e3ff8a21b50dad0e..8dd4cdf5a3b094295a46301cbaa9aa5db022ca59 100644 --- a/frameworks/native/ops/fullconnection_builder.h +++ b/frameworks/native/ops/fullconnection_builder.h @@ -18,8 +18,8 @@ #include "mindir.h" -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/gather_builder.cpp b/frameworks/native/ops/gather_builder.cpp index aba0bfc790c0170a824133f0c7a252768c025074..162543bf4cc78253303c46dfd640a70e3af1df45 100644 --- a/frameworks/native/ops/gather_builder.cpp +++ b/frameworks/native/ops/gather_builder.cpp @@ -17,7 +17,7 @@ #include "mindir.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/gather_builder.h b/frameworks/native/ops/gather_builder.h index 7fe35dfb8e077a44213db9ea556227a940d4ca0f..d9dc316a3bc5e4daae316d172bbdbd10a22b2958 100644 --- a/frameworks/native/ops/gather_builder.h +++ b/frameworks/native/ops/gather_builder.h @@ -16,7 +16,7 @@ #ifndef NEURAL_NETWORK_RUNTIME_GATHER_BUILDER_H #define NEURAL_NETWORK_RUNTIME_GATHER_BUILDER_H -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/gelu_builder.cpp b/frameworks/native/ops/gelu_builder.cpp index 0f7592200f9848e956b103508720e08a97b70028..76741f4aac5814d4be0185491a9b5c50fde7cce3 100644 --- a/frameworks/native/ops/gelu_builder.cpp +++ b/frameworks/native/ops/gelu_builder.cpp @@ -17,7 +17,7 @@ #include "mindir.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/gelu_builder.h b/frameworks/native/ops/gelu_builder.h index 6f0346a13fcddf7dcd519e9ca6b5bc00c061f42e..13b13472d95230ee31858d6d2f360af0ef799988 100644 --- a/frameworks/native/ops/gelu_builder.h +++ b/frameworks/native/ops/gelu_builder.h @@ -16,7 +16,7 @@ #ifndef NEURAL_NETWORK_RUNTIME_GELU_BUILDER_H #define NEURAL_NETWORK_RUNTIME_GELU_BUILDER_H -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/hswish_builder.cpp b/frameworks/native/ops/hswish_builder.cpp index 3a9cae54263edff7221daa2c02a0a6160a9613d2..75e806894f243a54c30a9c4ed85c76713aca8a3c 100644 --- a/frameworks/native/ops/hswish_builder.cpp +++ b/frameworks/native/ops/hswish_builder.cpp @@ -17,7 +17,7 @@ #include "mindir.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/hswish_builder.h b/frameworks/native/ops/hswish_builder.h index 0d9a9050f5b64245613d24bbb9be42849d4b2802..9f471d011cdfb9913c2dd922d30d5c57e9963adb 100644 --- a/frameworks/native/ops/hswish_builder.h +++ b/frameworks/native/ops/hswish_builder.h @@ -16,7 +16,7 @@ #ifndef NEURAL_NETWORK_RUNTIME_HSWISH_BUILDER_H #define NEURAL_NETWORK_RUNTIME_HSWISH_BUILDER_H -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/layernorm_builder.cpp b/frameworks/native/ops/layernorm_builder.cpp index a8938ab457b9169e8c795d932f983f4a99c54ada..dcc90c481049941b9f21379599f76c2154249ebf 100644 --- a/frameworks/native/ops/layernorm_builder.cpp +++ b/frameworks/native/ops/layernorm_builder.cpp @@ -17,7 +17,7 @@ #include "mindir.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/layernorm_builder.h b/frameworks/native/ops/layernorm_builder.h index 68847b7b04648ab3b44ed5cc04d9bc5c19f6f8b7..546579a43a16971435088d6d94238446f1f5694f 100644 --- a/frameworks/native/ops/layernorm_builder.h +++ b/frameworks/native/ops/layernorm_builder.h @@ -16,7 +16,7 @@ #ifndef NEURAL_NETWORK_RUNTIME_LAYERNORM_BUILDER_H #define NEURAL_NETWORK_RUNTIME_LAYERNORM_BUILDER_H -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/lessequal_builder.cpp b/frameworks/native/ops/lessequal_builder.cpp index a74445efc744385694e0a8796acf732998a9416e..9af019dc5365bec0c37b35be9309530d2f7d56dd 100644 --- a/frameworks/native/ops/lessequal_builder.cpp +++ b/frameworks/native/ops/lessequal_builder.cpp @@ -17,7 +17,7 @@ #include "mindir.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/lessequal_builder.h b/frameworks/native/ops/lessequal_builder.h index 6933ffed2869e714db6b9d5f3f018a05bac3a933..63286347ef028efa6b25bf65e96bd1a751151de8 100644 --- a/frameworks/native/ops/lessequal_builder.h +++ b/frameworks/native/ops/lessequal_builder.h @@ -16,7 +16,7 @@ #ifndef NEURAL_NETWORK_RUNTIME_LESSEQUAL_BUILDER_H #define NEURAL_NETWORK_RUNTIME_LESSEQUAL_BUILDER_H -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/matmul_builder.cpp b/frameworks/native/ops/matmul_builder.cpp index 9b0440f5970c4a1504dd2c130eb2b3f4e20922ac..03583db3b1f94fdbab6200f18b60e091a3f052d2 100644 --- a/frameworks/native/ops/matmul_builder.cpp +++ b/frameworks/native/ops/matmul_builder.cpp @@ -15,9 +15,9 @@ #include "matmul_builder.h" -#include "frameworks/native/transform.h" -#include "frameworks/native/validation.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/transform.h" +#include "frameworks/native/compat/validation.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/matmul_builder.h b/frameworks/native/ops/matmul_builder.h index 1efcdf14a848fd53cef6a57405cc51451e495d26..87007deda499d60dc1558afe0c059aad9dce1d08 100644 --- a/frameworks/native/ops/matmul_builder.h +++ b/frameworks/native/ops/matmul_builder.h @@ -18,7 +18,7 @@ #include "mindir.h" -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/maximum_builder.cpp b/frameworks/native/ops/maximum_builder.cpp index b681ec1cc8fcfae48a8cef854cd4cf55db1da4c2..97bed745685ec1eef89a5bb0272a35b39b9078ec 100644 --- a/frameworks/native/ops/maximum_builder.cpp +++ b/frameworks/native/ops/maximum_builder.cpp @@ -17,7 +17,7 @@ #include "mindir.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/maximum_builder.h b/frameworks/native/ops/maximum_builder.h index 5308c5d4eecb4a2f851658283dc5537c41311ac9..74c60c20d169d74a2ced883bd6d819e4e4c3def8 100644 --- a/frameworks/native/ops/maximum_builder.h +++ b/frameworks/native/ops/maximum_builder.h @@ -16,7 +16,7 @@ #ifndef NEURAL_NETWORK_RUNTIME_MAXIMUM_BUILDER_H #define NEURAL_NETWORK_RUNTIME_MAXIMUM_BUILDER_H -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/maxpool_builder.h b/frameworks/native/ops/maxpool_builder.h index 2022b6efa3ac53213cb585102fd0d001f691fe1c..a91610e77d37e9a5b3586ad249be1342548127ac 100644 --- a/frameworks/native/ops/maxpool_builder.h +++ b/frameworks/native/ops/maxpool_builder.h @@ -17,7 +17,7 @@ #define NEURAL_NETWORK_RUNTIME_MAXPOOL_BUILDER_H #include "pooling_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/mul_builder.cpp b/frameworks/native/ops/mul_builder.cpp index f055d285386269a194224d647b59c66ad626a927..c1a838d1cc19d3f701af537c1eca7fbbd3476a60 100644 --- a/frameworks/native/ops/mul_builder.cpp +++ b/frameworks/native/ops/mul_builder.cpp @@ -15,9 +15,9 @@ #include "mul_builder.h" -#include "frameworks/native/transform.h" -#include "frameworks/native/validation.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/transform.h" +#include "frameworks/native/compat/validation.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/mul_builder.h b/frameworks/native/ops/mul_builder.h index 25cd5ac0dd6cef5608aa73137dd9d3a8a1b469df..dbe951f0c4e4d7829b91145a328c203edf10d6b7 100644 --- a/frameworks/native/ops/mul_builder.h +++ b/frameworks/native/ops/mul_builder.h @@ -18,7 +18,7 @@ #include "mindir.h" -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/onehot_builder.cpp b/frameworks/native/ops/onehot_builder.cpp index b06840863c63c4342c2f087841de9d50940fe029..84d1cc8c18b7d5bdfc9878679efe85f181708033 100644 --- a/frameworks/native/ops/onehot_builder.cpp +++ b/frameworks/native/ops/onehot_builder.cpp @@ -17,7 +17,7 @@ #include "mindir.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/onehot_builder.h b/frameworks/native/ops/onehot_builder.h index 537855bd4ec538612790399c7fe4d92ca239bc4b..c275e6a5743a04c8630dfd7cebc022b0160ef431 100644 --- a/frameworks/native/ops/onehot_builder.h +++ b/frameworks/native/ops/onehot_builder.h @@ -16,7 +16,7 @@ #ifndef NEURAL_NETWORK_RUNTIME_ONEHOT_BUILDER_H #define NEURAL_NETWORK_RUNTIME_ONEHOT_BUILDER_H -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/pad_builder.cpp b/frameworks/native/ops/pad_builder.cpp index b14d8a63343ee922631539c931eb82bac1f1b52f..4c6e6db80f55e268c36d710b9406d80f00c21394 100644 --- a/frameworks/native/ops/pad_builder.cpp +++ b/frameworks/native/ops/pad_builder.cpp @@ -17,7 +17,7 @@ #include "mindir.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/pad_builder.h b/frameworks/native/ops/pad_builder.h index a5968a42ecb8735627855d61d2839fd3fb0d39a1..9023cbac78d571409ed341e100a428f8f6f20601 100644 --- a/frameworks/native/ops/pad_builder.h +++ b/frameworks/native/ops/pad_builder.h @@ -16,7 +16,7 @@ #ifndef NEURAL_NETWORK_RUNTIME_PAD_BUILDER_H #define NEURAL_NETWORK_RUNTIME_PAD_BUILDER_H -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/pooling_builder.cpp b/frameworks/native/ops/pooling_builder.cpp index 7338ed401588c6f49fc17b0bf8d0fcb17741d5f3..01e5a9be90cfbec7be6e30d5e01b57e7873155da 100644 --- a/frameworks/native/ops/pooling_builder.cpp +++ b/frameworks/native/ops/pooling_builder.cpp @@ -15,8 +15,8 @@ #include "pooling_builder.h" -#include "frameworks/native/transform.h" -#include "frameworks/native/validation.h" +#include "frameworks/native/compat/transform.h" +#include "frameworks/native/compat/validation.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/pooling_builder.h b/frameworks/native/ops/pooling_builder.h index 4a42b4a2674ccfc026d3a595f0aaf5ff6d79bd31..249b380d8f7e2d646092b9a031200bfed4bf2bbc 100644 --- a/frameworks/native/ops/pooling_builder.h +++ b/frameworks/native/ops/pooling_builder.h @@ -18,7 +18,7 @@ #include "mindir.h" -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/pow_builder.cpp b/frameworks/native/ops/pow_builder.cpp index 71e9df7fe6db128a09935ce8869d005605b8afa8..f062a248550ac5e7731812d00d7b0e16527f2c14 100644 --- a/frameworks/native/ops/pow_builder.cpp +++ b/frameworks/native/ops/pow_builder.cpp @@ -17,7 +17,7 @@ #include "mindir.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/pow_builder.h b/frameworks/native/ops/pow_builder.h index 10ec7279d86b60dba114b86ceb643f77dac1775e..a7e749f3d9d782f5cfc7e5b57324b3b740c21a3f 100644 --- a/frameworks/native/ops/pow_builder.h +++ b/frameworks/native/ops/pow_builder.h @@ -16,7 +16,7 @@ #ifndef NEURAL_NETWORK_RUNTIME_POW_BUILDER_H #define NEURAL_NETWORK_RUNTIME_POW_BUILDER_H -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/prelu_builder.cpp b/frameworks/native/ops/prelu_builder.cpp index d8fcc56c98d89ca51611d5ed860d6c54b5e43de4..00cb6ca9547f8bb55316cfacfb8ea4cdaf4a9c33 100644 --- a/frameworks/native/ops/prelu_builder.cpp +++ b/frameworks/native/ops/prelu_builder.cpp @@ -17,7 +17,7 @@ #include "mindir.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/prelu_builder.h b/frameworks/native/ops/prelu_builder.h index 117343c7c90ab86255eda31cab0a628b2cf817f2..07a86874135b3957111bf66d7047a13c715e79be 100644 --- a/frameworks/native/ops/prelu_builder.h +++ b/frameworks/native/ops/prelu_builder.h @@ -16,7 +16,7 @@ #ifndef NEURAL_NETWORK_RUNTIME_PRELU_BUILDER_H #define NEURAL_NETWORK_RUNTIME_PRELU_BUILDER_H -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/quant_dtype_cast_builder.cpp b/frameworks/native/ops/quant_dtype_cast_builder.cpp index 79ce59c493a342aec5660ac200268ab2df3a015d..8ffa190b17d3cd557fc6e4189a64b8962d9f15f3 100644 --- a/frameworks/native/ops/quant_dtype_cast_builder.cpp +++ b/frameworks/native/ops/quant_dtype_cast_builder.cpp @@ -17,7 +17,7 @@ #include "mindir.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/quant_dtype_cast_builder.h b/frameworks/native/ops/quant_dtype_cast_builder.h index bd4a1b323b0486fac2fad129cb98e1fd9fcd052f..f74f14bde88a0c61cacf015e804e9246f7a0ce79 100644 --- a/frameworks/native/ops/quant_dtype_cast_builder.h +++ b/frameworks/native/ops/quant_dtype_cast_builder.h @@ -16,7 +16,7 @@ #ifndef NEURAL_NETWORK_RUNTIME_QUANTDTYPECAST_BUILDER_H #define NEURAL_NETWORK_RUNTIME_QUANTDTYPECAST_BUILDER_H -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/reduceall_builder.cpp b/frameworks/native/ops/reduceall_builder.cpp index fbf0406a1a6d8e1afc0a4122337b6d4acc32142e..88c42b1797998f3b3aa856997b5ebb6305a71e6d 100644 --- a/frameworks/native/ops/reduceall_builder.cpp +++ b/frameworks/native/ops/reduceall_builder.cpp @@ -15,7 +15,7 @@ #include "reduceall_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/reduceall_builder.h b/frameworks/native/ops/reduceall_builder.h index 141d69b0f5c0338d9912adf7f00550e07b2602ea..0783d0c1f67e26dea549b6039d7abcebfda8e5f2 100644 --- a/frameworks/native/ops/reduceall_builder.h +++ b/frameworks/native/ops/reduceall_builder.h @@ -18,7 +18,7 @@ #include "mindir.h" -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/reducemean_builder.cpp b/frameworks/native/ops/reducemean_builder.cpp index 5f60e0570ac71248a4c6543357aeb60c2dbc44ce..57b0b8354645cca1577be5850cd66272ad79e308 100644 --- a/frameworks/native/ops/reducemean_builder.cpp +++ b/frameworks/native/ops/reducemean_builder.cpp @@ -15,7 +15,7 @@ #include "reducemean_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/reducemean_builder.h b/frameworks/native/ops/reducemean_builder.h index 7ddc3b30cdc0c12ede4ffefab2480fb35519e2d2..c85892b5ce868befede58bcca3a2673301110b1a 100644 --- a/frameworks/native/ops/reducemean_builder.h +++ b/frameworks/native/ops/reducemean_builder.h @@ -18,7 +18,7 @@ #include "mindir.h" -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/reduceprod_builder.cpp b/frameworks/native/ops/reduceprod_builder.cpp index e22b2c5cc68f89a162229a2f0b076401d601db1f..f22633d5297eea5ae183459079586731b297d205 100644 --- a/frameworks/native/ops/reduceprod_builder.cpp +++ b/frameworks/native/ops/reduceprod_builder.cpp @@ -15,7 +15,7 @@ #include "reduceprod_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/reduceprod_builder.h b/frameworks/native/ops/reduceprod_builder.h index b1314aab3ed098681888e4a9799912ea6990b70f..dfe7e424e5746bb17005002ed6ca34d4a1f53658 100644 --- a/frameworks/native/ops/reduceprod_builder.h +++ b/frameworks/native/ops/reduceprod_builder.h @@ -18,7 +18,7 @@ #include "mindir.h" -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/relu6_builder.cpp b/frameworks/native/ops/relu6_builder.cpp index eaa347492605e14e425c8b5ca32a3b1202f80f81..fccf90aeec2f16bc5331534468db1dce30fa1664 100644 --- a/frameworks/native/ops/relu6_builder.cpp +++ b/frameworks/native/ops/relu6_builder.cpp @@ -17,7 +17,7 @@ #include "mindir.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/relu6_builder.h b/frameworks/native/ops/relu6_builder.h index 71f61966c8f44334c4f0a1afb6265052f68d384f..44ac2be0f4cc7b073ded5461dd211e4655c48beb 100644 --- a/frameworks/native/ops/relu6_builder.h +++ b/frameworks/native/ops/relu6_builder.h @@ -16,7 +16,7 @@ #ifndef NEURAL_NETWORK_RUNTIME_RELU6_BUILDER_H #define NEURAL_NETWORK_RUNTIME_RELU6_BUILDER_H -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/relu_builder.cpp b/frameworks/native/ops/relu_builder.cpp index 6f397feaeed3653fd17d538fa8f2739d0afb92df..c997c84da021d3f3bb66d5dea7780c0d8b2bfba3 100644 --- a/frameworks/native/ops/relu_builder.cpp +++ b/frameworks/native/ops/relu_builder.cpp @@ -17,7 +17,7 @@ #include "mindir.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/relu_builder.h b/frameworks/native/ops/relu_builder.h index 9c8b9d73a0db02fe6af5b0a20dcbff0b621bf809..f9a4a4f205ae9a36b70647a669f80aace6e81a55 100644 --- a/frameworks/native/ops/relu_builder.h +++ b/frameworks/native/ops/relu_builder.h @@ -16,7 +16,7 @@ #ifndef NEURAL_NETWORK_RUNTIME_RELU_BUILDER_H #define NEURAL_NETWORK_RUNTIME_RELU_BUILDER_H -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/reshape_builder.cpp b/frameworks/native/ops/reshape_builder.cpp index e1469bcc71b0287d53f9a5385203ce7ca1b49d9d..85f6bebd2741ed6fcd81f281e78bc692cbdf7136 100644 --- a/frameworks/native/ops/reshape_builder.cpp +++ b/frameworks/native/ops/reshape_builder.cpp @@ -17,7 +17,7 @@ #include "mindir.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/reshape_builder.h b/frameworks/native/ops/reshape_builder.h index ef24166e923ed3b7c07b5911bdd548e50ea9b84d..9c2f9c752b09ba6f6c41c9777ee0db50fb52e77e 100644 --- a/frameworks/native/ops/reshape_builder.h +++ b/frameworks/native/ops/reshape_builder.h @@ -16,7 +16,7 @@ #ifndef NEURAL_NETWORK_RUNTIME_RESHAPE_BUILDER_H #define NEURAL_NETWORK_RUNTIME_RESHAPE_BUILDER_H -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/resize_bilinear_builder.cpp b/frameworks/native/ops/resize_bilinear_builder.cpp index 5c868f2fa4c0bd5fc7751a86bb0c28e2e5c57531..374a436985753d48d85d54920c427102819c25fb 100644 --- a/frameworks/native/ops/resize_bilinear_builder.cpp +++ b/frameworks/native/ops/resize_bilinear_builder.cpp @@ -15,7 +15,7 @@ #include "resize_bilinear_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/resize_bilinear_builder.h b/frameworks/native/ops/resize_bilinear_builder.h index ce8eb56945512f7e57bd2415212189d66a332860..24bd9c43e1a64a797b0663e897db56fe836f0562 100644 --- a/frameworks/native/ops/resize_bilinear_builder.h +++ b/frameworks/native/ops/resize_bilinear_builder.h @@ -18,7 +18,7 @@ #include "mindir.h" -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/rsqrt_builder.cpp b/frameworks/native/ops/rsqrt_builder.cpp index b38400571ca511995ae4634995e3ba11c9647725..2c37b9dfab19133c7a2793bb7336d75a22d4b3bc 100644 --- a/frameworks/native/ops/rsqrt_builder.cpp +++ b/frameworks/native/ops/rsqrt_builder.cpp @@ -17,7 +17,7 @@ #include "mindir.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/rsqrt_builder.h b/frameworks/native/ops/rsqrt_builder.h index 9d1f6c0e2b44d15fb9cf8846726f505db3b73784..cfd9fb9fc7ab58d8f8f71705a9704561f6501cc9 100644 --- a/frameworks/native/ops/rsqrt_builder.h +++ b/frameworks/native/ops/rsqrt_builder.h @@ -16,7 +16,7 @@ #ifndef NEURAL_NETWORK_RUNTIME_RSQRT_BUILDER_H #define NEURAL_NETWORK_RUNTIME_RSQRT_BUILDER_H -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/scale_builder.cpp b/frameworks/native/ops/scale_builder.cpp index defccf7bc2979d01f38e94674c8907d20e96575a..2edb403e45c3013c2e6d3c0b070e7120eb762fa4 100644 --- a/frameworks/native/ops/scale_builder.cpp +++ b/frameworks/native/ops/scale_builder.cpp @@ -15,9 +15,9 @@ #include "scale_builder.h" -#include "frameworks/native/ops_registry.h" -#include "frameworks/native/validation.h" -#include "frameworks/native/transform.h" +#include "frameworks/native/compat/ops_registry.h" +#include "frameworks/native/compat/validation.h" +#include "frameworks/native/compat/transform.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/scale_builder.h b/frameworks/native/ops/scale_builder.h index 362f4ab14cd4be5a0c64a8b680017a36e134cbb3..f9095216668c44a62cced8b7c95be2294a5b2a35 100644 --- a/frameworks/native/ops/scale_builder.h +++ b/frameworks/native/ops/scale_builder.h @@ -18,7 +18,7 @@ #include "mindir.h" -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/shape_builder.cpp b/frameworks/native/ops/shape_builder.cpp index 9164b0e3f55f198b8e77765155709f96dd94db0d..abf65e506b2a59b0b91c11ce227ca2f0f890fb9b 100644 --- a/frameworks/native/ops/shape_builder.cpp +++ b/frameworks/native/ops/shape_builder.cpp @@ -17,7 +17,7 @@ #include "mindir.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/shape_builder.h b/frameworks/native/ops/shape_builder.h index bd3d7989e1e461f0a37f23a7da8f03922bd9ff8c..a7e042a13ea6a0a73b5c393edbe6159ea7399953 100644 --- a/frameworks/native/ops/shape_builder.h +++ b/frameworks/native/ops/shape_builder.h @@ -16,7 +16,7 @@ #ifndef NEURAL_NETWORK_RUNTIME_SHAPE_BUILDER_H #define NEURAL_NETWORK_RUNTIME_SHAPE_BUILDER_H -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/sigmoid_builder.cpp b/frameworks/native/ops/sigmoid_builder.cpp index ae7df183cb5611cfa7267c4a18eccf5ca4249841..6c4f4aafc9bdc154e10d11e25f17faa0581efa08 100644 --- a/frameworks/native/ops/sigmoid_builder.cpp +++ b/frameworks/native/ops/sigmoid_builder.cpp @@ -17,7 +17,7 @@ #include "mindir.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/sigmoid_builder.h b/frameworks/native/ops/sigmoid_builder.h index 63d9c8eb89db33dd10c016a42f4c43d00c3daa4b..2ebe33508a072c076d6206aec4372d260d603329 100644 --- a/frameworks/native/ops/sigmoid_builder.h +++ b/frameworks/native/ops/sigmoid_builder.h @@ -16,7 +16,7 @@ #ifndef NEURAL_NETWORK_RUNTIME_SIGMOID_BUILDER_H #define NEURAL_NETWORK_RUNTIME_SIGMOID_BUILDER_H -#include "frameworks/native/ops_builder.h" +#include "frameworks/native/compat/ops_builder.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/slice_builder.h b/frameworks/native/ops/slice_builder.h index 3494d6efd1b5278d21fd4a5a667695aa75b65d33..176f1a7275cb4d7bd0761488d7f986c25b6b54ff 100644 --- a/frameworks/native/ops/slice_builder.h +++ b/frameworks/native/ops/slice_builder.h @@ -16,8 +16,8 @@ #ifndef NEURAL_NETWORK_RUNTIME_SLICE_BUILDER_H #define NEURAL_NETWORK_RUNTIME_SLICE_BUILDER_H -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/softmax_builder.h b/frameworks/native/ops/softmax_builder.h index 4a449b2113008231959bcf0eccf5855415481fb5..d2acd4a3e9686cfd99839d7460a5aa2b2a9cc29f 100644 --- a/frameworks/native/ops/softmax_builder.h +++ b/frameworks/native/ops/softmax_builder.h @@ -16,8 +16,8 @@ #ifndef NEURAL_NETWORK_RUNTIME_SOFTMAX_BUILDER_H #define NEURAL_NETWORK_RUNTIME_SOFTMAX_BUILDER_H -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/space_to_batch_nd_builder.h b/frameworks/native/ops/space_to_batch_nd_builder.h index 0944183c6247b3a73941178bc8bcbc1d29184a6e..e8ff39b3c199b06919438afecd52a83298e937a2 100644 --- a/frameworks/native/ops/space_to_batch_nd_builder.h +++ b/frameworks/native/ops/space_to_batch_nd_builder.h @@ -16,8 +16,8 @@ #ifndef NEURAL_NETWORK_RUNTIME_SPACETOBATCHND_BUILDER_H #define NEURAL_NETWORK_RUNTIME_SPACETOBATCHND_BUILDER_H -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/split_builder.h b/frameworks/native/ops/split_builder.h index 2ab4cf6b918b6172a260a5ee20d0aad692039c6a..518cf21fdb7dbc1ec80301aaf271c5dfc673f596 100644 --- a/frameworks/native/ops/split_builder.h +++ b/frameworks/native/ops/split_builder.h @@ -18,8 +18,8 @@ #include "mindir.h" -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/sqrt_builder.h b/frameworks/native/ops/sqrt_builder.h index ad835b8c3378bd33966fbb56e49d2c65fdae8534..6354247d00aa617cac05812310e341c591c48a3f 100644 --- a/frameworks/native/ops/sqrt_builder.h +++ b/frameworks/native/ops/sqrt_builder.h @@ -16,8 +16,8 @@ #ifndef NEURAL_NETWORK_RUNTIME_SQRT_BUILDER_H #define NEURAL_NETWORK_RUNTIME_SQRT_BUILDER_H -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/squared_difference_builder.h b/frameworks/native/ops/squared_difference_builder.h index d51847c4db7f4f3df91971065f297f9db3831e40..4d1288dbb4c9cb0b8780eba6305c8efecdfa12ec 100644 --- a/frameworks/native/ops/squared_difference_builder.h +++ b/frameworks/native/ops/squared_difference_builder.h @@ -16,8 +16,8 @@ #ifndef NEURAL_NETWORK_RUNTIME_SQUAREDDIFFERENCE_BUILDER_H #define NEURAL_NETWORK_RUNTIME_SQUAREDDIFFERENCE_BUILDER_H -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/squeeze_builder.h b/frameworks/native/ops/squeeze_builder.h index 989caa1c270488723a2f94b11b70b8f41dafda15..0ac8a3e7480af5c51342f5e20b05ef05f5dd73ac 100644 --- a/frameworks/native/ops/squeeze_builder.h +++ b/frameworks/native/ops/squeeze_builder.h @@ -16,8 +16,8 @@ #ifndef NEURAL_NETWORK_RUNTIME_SQUEEZE_BUILDER_H #define NEURAL_NETWORK_RUNTIME_SQUEEZE_BUILDER_H -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/stack_builder.h b/frameworks/native/ops/stack_builder.h index 1e80ecd212b45616c7f9f9fd49c5a4f1d4b7c1c9..0f6c6d2474770ed6b0d0b80d91f84ca31c999ab6 100644 --- a/frameworks/native/ops/stack_builder.h +++ b/frameworks/native/ops/stack_builder.h @@ -16,8 +16,8 @@ #ifndef NEURAL_NETWORK_RUNTIME_STACK_BUILDER_H #define NEURAL_NETWORK_RUNTIME_STACK_BUILDER_H -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/strided_slice_builder.cpp b/frameworks/native/ops/strided_slice_builder.cpp index 4f25d85db795cc4fa7602ac9ecd7bbe128b8261e..a381967fee3bd6aebbc73f95c0aa3eda7d39174a 100644 --- a/frameworks/native/ops/strided_slice_builder.cpp +++ b/frameworks/native/ops/strided_slice_builder.cpp @@ -17,8 +17,6 @@ #include "mindir.h" -#include "interfaces/kits/c/neural_network_runtime_type.h" - namespace OHOS { namespace NeuralNetworkRuntime { namespace Ops { diff --git a/frameworks/native/ops/strided_slice_builder.h b/frameworks/native/ops/strided_slice_builder.h index 45637b05e47dfb16904d9cab0e688ffe29414ce9..e8c7be4ecda91daa473be534c232b75eb7f295f1 100644 --- a/frameworks/native/ops/strided_slice_builder.h +++ b/frameworks/native/ops/strided_slice_builder.h @@ -16,8 +16,8 @@ #ifndef NEURAL_NETWORK_RUNTIME_STRIDEDSLICE_BUILDER_H #define NEURAL_NETWORK_RUNTIME_STRIDEDSLICE_BUILDER_H -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/sub_builder.cpp b/frameworks/native/ops/sub_builder.cpp index 6021c17531d94fd0fe4188928ae44cd56ccd2b9f..b840e004276e2d50cd42710ad9ea0d80f2304c05 100644 --- a/frameworks/native/ops/sub_builder.cpp +++ b/frameworks/native/ops/sub_builder.cpp @@ -14,8 +14,8 @@ */ #include "sub_builder.h" -#include "frameworks/native/transform.h" -#include "frameworks/native/validation.h" +#include "frameworks/native/compat/transform.h" +#include "frameworks/native/compat/validation.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/sub_builder.h b/frameworks/native/ops/sub_builder.h index 19dc8d23ee0e77896b25160240e149ef29d68c92..e807ecba9cad2daa9275210d5376673edafee54d 100644 --- a/frameworks/native/ops/sub_builder.h +++ b/frameworks/native/ops/sub_builder.h @@ -18,8 +18,8 @@ #include "mindir.h" -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/tanh_builder.h b/frameworks/native/ops/tanh_builder.h index 32fd2a7cec85872d2d157f9ad3bd02acff1a0fe2..e9c3e4d4c7d4aabf1f0bdc5e21f94b8846cbcb9b 100644 --- a/frameworks/native/ops/tanh_builder.h +++ b/frameworks/native/ops/tanh_builder.h @@ -18,8 +18,8 @@ #include "mindir.h" -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/tile_builder.h b/frameworks/native/ops/tile_builder.h index fc9321251af8606b6da49688b9af77b102fd32aa..cca280e4875b7b54ec999097dd898570ac568f88 100644 --- a/frameworks/native/ops/tile_builder.h +++ b/frameworks/native/ops/tile_builder.h @@ -16,8 +16,8 @@ #ifndef NEURAL_NETWORK_RUNTIME_TILE_BUILDER_H #define NEURAL_NETWORK_RUNTIME_TILE_BUILDER_H -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/top_k_builder.h b/frameworks/native/ops/top_k_builder.h index 69d50806e3c11f199e43b6d51bba3de75c4a00bd..4fd88d89cdb2c1aec4b5db828ca89c4a9768e328 100644 --- a/frameworks/native/ops/top_k_builder.h +++ b/frameworks/native/ops/top_k_builder.h @@ -16,8 +16,8 @@ #ifndef NEURAL_NETWORK_RUNTIME_TOPK_BUILDER_H #define NEURAL_NETWORK_RUNTIME_TOPK_BUILDER_H -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/transpose_builder.h b/frameworks/native/ops/transpose_builder.h index 998d5803a0c7771dabf02ad0da88340f92e3197c..c953578c55e5eb0c7a19c6fb4327f23537180171 100644 --- a/frameworks/native/ops/transpose_builder.h +++ b/frameworks/native/ops/transpose_builder.h @@ -16,8 +16,8 @@ #ifndef NEURAL_NETWORK_RUNTIME_TRANSPOSE_BUILDER_H #define NEURAL_NETWORK_RUNTIME_TRANSPOSE_BUILDER_H -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/ops/unsqueeze_builder.h b/frameworks/native/ops/unsqueeze_builder.h index 663395740d3ee93d80bde99e01b6bd9d3fe41081..e78048fcabc8574e88c8c695430f5a9c7cc17c48 100644 --- a/frameworks/native/ops/unsqueeze_builder.h +++ b/frameworks/native/ops/unsqueeze_builder.h @@ -16,8 +16,8 @@ #ifndef NEURAL_NETWORK_RUNTIME_UNSQUEEZE_BUILDER_H #define NEURAL_NETWORK_RUNTIME_UNSQUEEZE_BUILDER_H -#include "frameworks/native/ops_builder.h" -#include "frameworks/native/ops_registry.h" +#include "frameworks/native/compat/ops_builder.h" +#include "frameworks/native/compat/ops_registry.h" namespace OHOS { namespace NeuralNetworkRuntime { diff --git a/frameworks/native/options.h b/frameworks/native/options.h new file mode 100644 index 0000000000000000000000000000000000000000..09bce682b5f16f9b6710238fd1c007498b6af950 --- /dev/null +++ b/frameworks/native/options.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_CORE_OPTIONS_H +#define NEURAL_NETWORK_CORE_OPTIONS_H + +#include + +#include "v2_0/neural_network_core.h" + +namespace OHOS { +namespace NeuralNetworkCore { +class Options { +public: + Options() = default; + virtual ~Options() = default; + + virtual OH_NNCore_ReturnCode SetPerformanceMode(OH_NNCore_PerformanceMode performance) = 0; + virtual OH_NNCore_ReturnCode SetPriority(OH_NNCore_Priority priority) = 0; + virtual OH_NNCore_ReturnCode SetEnableFp16(bool isFp16) = 0; + virtual OH_NNCore_ReturnCode GetBackendName(std::string& backendName) = 0; +}; +} // namespace NeuralNetworkCore +} // namespace OHOS + +#endif diff --git a/frameworks/native/quant_param.cpp b/frameworks/native/quant_param.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4860a18cc128175b911ee38f2b1d1d448dfa8c60 --- /dev/null +++ b/frameworks/native/quant_param.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "quant_param.h" + +#include "common/log.h" + +namespace OHOS { +namespace NeuralNetworkBackend { +void QuantParam::SetScales(std::vector scales) +{ + m_scales = scales; +} + +void QuantParam::SetZeroPoints(std::vector zeroPoints) +{ + m_zeroPoints = zeroPoints; +} + +void QuantParam::SetNumBits(std::vector numBits) +{ + m_numBits = numBits; +} + +std::vector QuantParam::GetScales() const +{ + return m_scales; +} + +std::vector QuantParam::GetZeroPoints() const +{ + return m_zeroPoints; +} + +std::vector QuantParam::GetNumBits() const +{ + return m_numBits; +} + +OH_NNCore_ReturnCode QuantParam::CopyToCompat(std::vector& compatQuantParams) const +{ + if ((m_scales.size() != m_zeroPoints.size()) || (m_zeroPoints.size() != m_numBits.size())) { + LOGE("CopyToCompat failed, the size of scales(%zu), zeroPoints(%zu) and numBits(%zu) are not equal.", m_scales.size(), m_zeroPoints.size(), m_numBits.size()); + return OH_NNCORE_INVALID_PARAMETER; + } + + size_t quantCount = m_scales.size(); + for (size_t i = 0; i < quantCount; i++) { + compatQuantParams.push_back({ + .numBits = m_numBits[i], + .scale = m_scales[i], + .zeroPoint = m_zeroPoints[i], + }); + } + + return OH_NNCORE_SUCCESS; +} +} // namespace NeuralNetworkBackend +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/quant_param.h b/frameworks/native/quant_param.h new file mode 100644 index 0000000000000000000000000000000000000000..1d607a953fda3af485ab9ef4c2f96300fbcdbf30 --- /dev/null +++ b/frameworks/native/quant_param.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_BACKEND_QUANT_PARAM_H +#define NEURAL_NETWORK_BACKEND_QUANT_PARAM_H + +#include +#include + +#include "interfaces/kits/c/v2_0/neural_network_runtime.h" +#include "compat/cpp_type.h" + +namespace OHOS { +namespace NeuralNetworkBackend { +class QuantParam { +public: + QuantParam() = default; + ~QuantParam() = default; + + void SetScales(std::vector scales); + void SetZeroPoints(std::vector zeroPoints); + void SetNumBits(std::vector numBits); + + std::vector GetScales() const; + std::vector GetZeroPoints() const; + std::vector GetNumBits() const; + + OH_NNCore_ReturnCode CopyToCompat(std::vector& compatQuantParams) const; + +private: + std::vector m_scales; + std::vector m_zeroPoints; + std::vector m_numBits; +}; +} // namespace NeuralNetworkBackend +} // namespace OHOS +#endif \ No newline at end of file diff --git a/frameworks/native/register_hdi_device_v1_0.cpp b/frameworks/native/register_hdi_device_v1_0.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d9724c154eabbeb5fc00e74c6a5707263d965a8a --- /dev/null +++ b/frameworks/native/register_hdi_device_v1_0.cpp @@ -0,0 +1,63 @@ +#include + +#include "compat/hdi_device_v1_0.h" +#include "common/log.h" +#include "common/utils.h" +#include "nnbackend.h" +#include "backend_registrar.h" + +using namespace OHOS::NeuralNetworkCore; +using namespace OHOS::NeuralNetworkRuntime; + +namespace OHOS { +namespace NeuralNetworkBackend { +std::shared_ptr HDIDeviceV1_0Creator() +{ + std::string deviceName; + std::string vendorName; + std::string version; + + // only one device from HDI now. + OHOS::sptr iDevice = V1_0::INnrtDevice::Get(); + if (iDevice == nullptr) { + LOGW("Get HDI device failed."); + return nullptr; + } + + auto hdiRet = iDevice->GetDeviceName(deviceName); + if (hdiRet != HDF_SUCCESS) { + LOGW("Get device name failed. ErrorCode=%d", hdiRet); + return nullptr; + } + + hdiRet = iDevice->GetVendorName(vendorName); + if (hdiRet != HDF_SUCCESS) { + LOGW("Get vendor name failed. ErrorCode=%d", hdiRet); + return nullptr; + } + + std::pair hdiVersion; + hdiRet = iDevice->GetVersion(hdiVersion.first, hdiVersion.second); + if (hdiRet != HDF_SUCCESS) { + LOGW("Get version failed. ErrorCode=%d", hdiRet); + return nullptr; + } + version = 'v' + std::to_string(hdiVersion.first) + '_' + std::to_string(hdiVersion.second); + const std::string& backendName = deviceName + '_' + vendorName + '_' + version; + + std::shared_ptr device = CreateSharedPtr(iDevice); + if (device == nullptr) { + LOGW("Failed to register device, because fail to create device instance."); + return nullptr; + } + + std::shared_ptr backend = std::make_shared(device, backendName); + if (backend == nullptr) { + LOGW("Failed to register backend, because fail to create backend."); + } + return backend; +} + +REGISTER_BACKEND(HDIDeviceV1_0, HDIDeviceV1_0Creator) +} // namespace NeuralNetworkBackend +} // namespace OHOS diff --git a/frameworks/native/register_hdi_device_v2_0.cpp b/frameworks/native/register_hdi_device_v2_0.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e3a5e11a5dd31c4f44d527a6dfc263d5033387d8 --- /dev/null +++ b/frameworks/native/register_hdi_device_v2_0.cpp @@ -0,0 +1,80 @@ +#include + +#include "compat/hdi_device_v2_0.h" +#include "compat/hdi_returncode_utils.h" +#include "common/log.h" +#include "common/utils.h" +#include "nnbackend.h" +#include "backend_registrar.h" + +using namespace OHOS::NeuralNetworkCore; +using namespace OHOS::NeuralNetworkRuntime; + +namespace OHOS { +namespace NeuralNetworkBackend { +std::shared_ptr HDIDeviceV2_0Creator() +{ + std::string deviceName; + std::string vendorName; + std::string version; + + // only one device from HDI now. + OHOS::sptr iDevice = V2_0::INnrtDevice::Get(); + if (iDevice == nullptr) { + LOGW("Get HDI device failed."); + return nullptr; + } + + auto ret = iDevice->GetDeviceName(deviceName); + int32_t nnrtSuccess = static_cast(V2_0::NNRT_ReturnCode::NNRT_SUCCESS); + if (ret != nnrtSuccess) { + if (ret < nnrtSuccess) { + LOGW("Get device name failed. An error occurred in HDI, errorcode is %{public}d.", ret); + } else { + OHOS::HDI::Nnrt::V2_0::NNRT_ReturnCode nnrtRet = static_cast(ret); + LOGW("Get device name failed. Errorcode is %{public}s.", ConverterRetToString(nnrtRet).c_str()); + } + return nullptr; + } + + ret = iDevice->GetVendorName(vendorName); + if (ret != nnrtSuccess) { + if (ret < nnrtSuccess) { + LOGW("Get vendor name failed. An error occurred in HDI, errorcode is %{public}d.", ret); + } else { + OHOS::HDI::Nnrt::V2_0::NNRT_ReturnCode nnrtRet = static_cast(ret); + LOGW("Get vendor name failed. Errorcode is %{public}s.", ConverterRetToString(nnrtRet).c_str()); + } + return nullptr; + } + + std::pair hdiVersion; + ret = iDevice->GetVersion(hdiVersion.first, hdiVersion.second); + if (ret != nnrtSuccess) { + if (ret < nnrtSuccess) { + LOGW("Get version failed. An error occurred in HDI, errorcode is %{public}d.", ret); + } else { + OHOS::HDI::Nnrt::V2_0::NNRT_ReturnCode nnrtRet = static_cast(ret); + LOGW("Get version failed. Errorcode is %{public}s.", ConverterRetToString(nnrtRet).c_str()); + } + return nullptr; + } + version = 'v' + std::to_string(hdiVersion.first) + '_' + std::to_string(hdiVersion.second); + const std::string& backendName = deviceName + '_' + vendorName + '_' + version; + + std::shared_ptr device = CreateSharedPtr(iDevice); + if (device == nullptr) { + LOGW("Failed to create device, because fail to create device instance."); + return nullptr; + } + + std::shared_ptr backend = std::make_shared(device, backendName); + if (backend == nullptr) { + LOGW("Failed to register backend, because fail to create backend."); + } + return backend; +} + +REGISTER_BACKEND(HDIDeviceV2_0, HDIDeviceV2_0Creator) +} // namespace NeuralNetworkBackend +} // namespace OHOS diff --git a/frameworks/native/tensor.h b/frameworks/native/tensor.h new file mode 100644 index 0000000000000000000000000000000000000000..68665aecb0bc2a359f072028ada8562148e38fe7 --- /dev/null +++ b/frameworks/native/tensor.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_CORE_TENSOR_H +#define NEURAL_NETWORK_CORE_TENSOR_H + +#include "tensor_desc.h" +#include + +namespace OHOS { +namespace NeuralNetworkCore { +class Tensor { +public: + Tensor() = default; + Tensor(const std::string& backendName, TensorDesc* tensorDesc); + virtual ~Tensor() = default; + + virtual OH_NNCore_ReturnCode CreateData() = 0; + virtual OH_NNCore_ReturnCode CreateData(size_t size) = 0; + virtual OH_NNCore_ReturnCode CreateData(int fd, size_t size, size_t offset) = 0; + + virtual TensorDesc* GetTensorDesc() const = 0; + virtual void* GetData() const = 0; + virtual int GetFd() const = 0; + virtual size_t GetSize() const = 0; + virtual size_t GetOffset() const = 0; + virtual OH_NNCore_ReturnCode GetBackendName(std::string& backendName) const = 0; +}; +} // namespace NeuralNetworkCore +} // namespace OHOS +#endif // NEURAL_NETWORK_CORE_TENSOR_H \ No newline at end of file diff --git a/frameworks/native/tensor_desc.cpp b/frameworks/native/tensor_desc.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dbb3391c078be69aa8b929cb85e3d18aa90a4611 --- /dev/null +++ b/frameworks/native/tensor_desc.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "tensor_desc.h" +#include "transform.h" +#include "validation.h" +#include "common/log.h" + +namespace OHOS { +namespace NeuralNetworkCore { +OH_NNCore_ReturnCode TensorDesc::GetDataType(OH_NNCore_DataType* dataType) const +{ + if (dataType == nullptr) { + LOGE("GetDataType failed, dataType is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + *dataType = m_dataType; + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode TensorDesc::SetDataType(OH_NNCore_DataType dataType) +{ + if (!Validation::ValidateDataType(dataType)) { + LOGE("TensorDesc::SetDataType failed, dataType %{public}d is invalid.", static_cast(dataType)); + return OH_NNCORE_INVALID_PARAMETER; + } + m_dataType = dataType; + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode TensorDesc::GetFormat(OH_NNCore_Format* format) const +{ + if (format == nullptr) { + LOGE("GetFormat failed, format is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + *format = m_format; + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode TensorDesc::SetFormat(OH_NNCore_Format format) +{ + if (!Validation::ValidateFormat(format)) { + LOGE("TensorDesc::SetFormat failed, format %{public}d is invalid.", static_cast(format)); + return OH_NNCORE_INVALID_PARAMETER; + } + m_format = format; + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode TensorDesc::GetShape(int32_t** shape, size_t* shapeNum) const +{ + if (shape == nullptr) { + LOGE("GetShape failed, shape is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (*shape != nullptr) { + LOGE("GetShape failed, *shape is not nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (shapeNum == nullptr) { + LOGE("GetShape failed, shapeNum is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + *shape = const_cast(m_shape.data()); + *shapeNum = m_shape.size(); + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode TensorDesc::SetShape(const int32_t* shape, size_t shapeNum) +{ + if (shape == nullptr) { + LOGE("SetShape failed, shape is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (shapeNum == 0) { + LOGE("SetShape failed, shapeNum is 0."); + return OH_NNCORE_INVALID_PARAMETER; + } + m_shape.clear(); + for (size_t i = 0; i < shapeNum; ++i) { + m_shape.emplace_back(shape[i]); + } + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode TensorDesc::GetElementNum(size_t* elementNum) const +{ + if (elementNum == nullptr) { + LOGE("GetElementNum failed, elementNum is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (m_shape.empty()) { + LOGE("GetElementNum failed, shape is empty."); + return OH_NNCORE_INVALID_PARAMETER; + } + *elementNum = 1; + size_t shapeNum = m_shape.size(); + for (size_t i = 0; i < shapeNum; ++i) { + if (m_shape[i] <= 0) { + LOGE("GetElementNum failed, shape[%{public}zu] should larger than zero, now is %{public}d.", i, m_shape[i]); + *elementNum = 0; + return OH_NNCORE_INVALID_PARAMETER; + } + (*elementNum) *= m_shape[i]; + } + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode TensorDesc::GetByteSize(size_t* byteSize) const +{ + if (byteSize == nullptr) { + LOGE("GetByteSize failed, byteSize is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + size_t elementNum = 0; + auto ret = GetElementNum(&elementNum); + if (ret != OH_NNCORE_SUCCESS) { + LOGE("GetByteSize failed, get element num failed."); + return ret; + } + + uint32_t typeSize = GetTypeSize(m_dataType); + if (typeSize == 0) { + LOGE("GetByteSize failed, data type is invalid."); + return OH_NNCORE_INVALID_PARAMETER; + } + + *byteSize = elementNum * typeSize; + + return OH_NNCORE_SUCCESS; +} + +OH_NNCore_ReturnCode TensorDesc::SetName(const char* name) +{ + m_name = name; + return OH_NNCORE_SUCCESS; +} + +// *name will be invalid after TensorDesc is destroyed +OH_NNCore_ReturnCode TensorDesc::GetName(const char** name) const +{ + if (name == nullptr) { + LOGE("GetName failed, name is nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + if (*name != nullptr) { + LOGE("GetName failed, *name is not nullptr."); + return OH_NNCORE_INVALID_PARAMETER; + } + *name = m_name.c_str(); + return OH_NNCORE_SUCCESS; +} +} // namespace NeuralNetworkBackend +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/tensor_desc.h b/frameworks/native/tensor_desc.h new file mode 100644 index 0000000000000000000000000000000000000000..bc19dd6b3b053603941b5129ce6b9c5e874de416 --- /dev/null +++ b/frameworks/native/tensor_desc.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_CORE_TENSOR_DESC_H +#define NEURAL_NETWORK_CORE_TENSOR_DESC_H + +#include "v2_0/neural_network_core_type.h" +#include +#include + +namespace OHOS { +namespace NeuralNetworkCore { +class TensorDesc{ +public: + TensorDesc() = default; + ~TensorDesc() = default; + + OH_NNCore_ReturnCode GetDataType(OH_NNCore_DataType* dataType) const; + OH_NNCore_ReturnCode SetDataType(OH_NNCore_DataType dataType); + + OH_NNCore_ReturnCode GetFormat(OH_NNCore_Format* format) const; + OH_NNCore_ReturnCode SetFormat(OH_NNCore_Format format); + + OH_NNCore_ReturnCode GetShape(int32_t** shape, size_t* shapeNum) const; + OH_NNCore_ReturnCode SetShape(const int32_t* shape, size_t shapeNum); + + OH_NNCore_ReturnCode GetElementNum(size_t* elementNum) const; + OH_NNCore_ReturnCode GetByteSize(size_t* byteSize) const; + + OH_NNCore_ReturnCode SetName(const char* name); + OH_NNCore_ReturnCode GetName(const char** name) const; + + +private: + OH_NNCore_DataType m_dataType{OH_NNCORE_OTHER_TYPES}; + OH_NNCore_Format m_format{OH_NNCORE_FORMAT_NONE}; + std::vector m_shape; + std::string m_name; + +}; +} // namespace NeuralNetworkCore +} // namespace OHOS +#endif // NEURAL_NETWORK_CORE_TENSOR_DESC_H \ No newline at end of file diff --git a/frameworks/native/transform.cpp b/frameworks/native/transform.cpp index 12e51b05209f2a7e2fd1c63b07c26bf6854805a4..aff843be6e50b2c72409e1fee0865042b3b6cb23 100644 --- a/frameworks/native/transform.cpp +++ b/frameworks/native/transform.cpp @@ -15,168 +15,37 @@ #include "transform.h" -#include "memory_manager.h" -#include "common/log.h" - namespace OHOS { -namespace NeuralNetworkRuntime { +namespace NeuralNetworkCore { const uint32_t BIT8_TO_BYTE = 1; const uint32_t BIT16_TO_BYTE = 2; const uint32_t BIT32_TO_BYTE = 4; const uint32_t BIT64_TO_BYTE = 8; -uint32_t GetTypeSize(OH_NN_DataType type) +uint32_t GetTypeSize(OH_NNCore_DataType type) { switch (type) { - case OH_NN_BOOL: + case OH_NNCORE_BOOL: return sizeof(bool); - case OH_NN_INT8: - case OH_NN_UINT8: + case OH_NNCORE_INT8: + case OH_NNCORE_UINT8: return BIT8_TO_BYTE; - case OH_NN_INT16: - case OH_NN_UINT16: - case OH_NN_FLOAT16: + case OH_NNCORE_INT16: + case OH_NNCORE_UINT16: + case OH_NNCORE_FLOAT16: return BIT16_TO_BYTE; - case OH_NN_INT32: - case OH_NN_UINT32: - case OH_NN_FLOAT32: + case OH_NNCORE_INT32: + case OH_NNCORE_UINT32: + case OH_NNCORE_FLOAT32: return BIT32_TO_BYTE; - case OH_NN_INT64: - case OH_NN_UINT64: - case OH_NN_FLOAT64: + case OH_NNCORE_INT64: + case OH_NNCORE_UINT64: + case OH_NNCORE_FLOAT64: + case OH_NNCORE_DOUBLE: return BIT64_TO_BYTE; default: return 0; } } - -mindspore::lite::DataType NNToMS::TransformDataType(OH_NN_DataType type) -{ - switch (type) { - case OH_NN_BOOL: - return mindspore::lite::DATA_TYPE_BOOL; - case OH_NN_INT8: - return mindspore::lite::DATA_TYPE_INT8; - case OH_NN_INT16: - return mindspore::lite::DATA_TYPE_INT16; - case OH_NN_INT32: - return mindspore::lite::DATA_TYPE_INT32; - case OH_NN_INT64: - return mindspore::lite::DATA_TYPE_INT64; - case OH_NN_UINT8: - return mindspore::lite::DATA_TYPE_UINT8; - case OH_NN_UINT16: - return mindspore::lite::DATA_TYPE_UINT16; - case OH_NN_UINT32: - return mindspore::lite::DATA_TYPE_UINT32; - case OH_NN_UINT64: - return mindspore::lite::DATA_TYPE_UINT64; - case OH_NN_FLOAT16: - return mindspore::lite::DATA_TYPE_FLOAT16; - case OH_NN_FLOAT32: - return mindspore::lite::DATA_TYPE_FLOAT32; - case OH_NN_FLOAT64: - return mindspore::lite::DATA_TYPE_FLOAT64; - default: - return mindspore::lite::DATA_TYPE_UNKNOWN; - } -} - -mindspore::lite::Format NNToMS::TransformFormat(OH_NN_Format type) -{ - switch (type) { - case OH_NN_FORMAT_NCHW: - return mindspore::lite::FORMAT_NCHW; - case OH_NN_FORMAT_NHWC: - return mindspore::lite::FORMAT_NHWC; - default: - return mindspore::lite::FORMAT_NHWC; - } -} - -mindspore::lite::ActivationType NNToMS::TransfromFusionType(OH_NN_FuseType type) -{ - switch (type) { - case OH_NN_FUSED_NONE: - return mindspore::lite::ACTIVATION_TYPE_NO_ACTIVATION; - case OH_NN_FUSED_RELU: - return mindspore::lite::ACTIVATION_TYPE_RELU; - case OH_NN_FUSED_RELU6: - return mindspore::lite::ACTIVATION_TYPE_RELU6; - default: - return mindspore::lite::ACTIVATION_TYPE_UNKNOWN; - } -} - -mindspore::lite::QuantType NNToMS::TransformQuantType(OHOS::NeuralNetworkRuntime::Ops::OpsQuantType type) -{ - switch (type) { - case OHOS::NeuralNetworkRuntime::Ops::OpsQuantType::QUANT_NONE: - return mindspore::lite::QUANT_TYPE_NONE; - case OHOS::NeuralNetworkRuntime::Ops::OpsQuantType::QUANT_ALL: - return mindspore::lite::QUANT_TYPE_ALL; - default: return mindspore::lite::QUANT_TYPE_NONE; - } -} - -mindspore::lite::PadMode NNToMS::TransformPadModeValue(int8_t padMode) -{ - // The value is an optional value of the int8_t type. The value 0 indicates the same, - // and the value 1 indicates valid. - return (padMode == 0) ? mindspore::lite::PadMode::PAD_MODE_SAME : - mindspore::lite::PadMode::PAD_MODE_VALID; -} - -OH_NN_DataType MSToNN::TransformDataType(mindspore::lite::DataType type) -{ - switch (type) { - case mindspore::lite::DATA_TYPE_BOOL: - return OH_NN_BOOL; - case mindspore::lite::DATA_TYPE_INT8: - return OH_NN_INT8; - case mindspore::lite::DATA_TYPE_INT16: - return OH_NN_INT16; - case mindspore::lite::DATA_TYPE_INT32: - return OH_NN_INT32; - case mindspore::lite::DATA_TYPE_INT64: - return OH_NN_INT64; - case mindspore::lite::DATA_TYPE_UINT8: - return OH_NN_UINT8; - case mindspore::lite::DATA_TYPE_UINT16: - return OH_NN_UINT16; - case mindspore::lite::DATA_TYPE_UINT32: - return OH_NN_UINT32; - case mindspore::lite::DATA_TYPE_UINT64: - return OH_NN_UINT64; - case mindspore::lite::DATA_TYPE_FLOAT16: - return OH_NN_FLOAT16; - case mindspore::lite::DATA_TYPE_FLOAT32: - return OH_NN_FLOAT32; - case mindspore::lite::DATA_TYPE_FLOAT64: - return OH_NN_FLOAT64; - default: - return OH_NN_UNKNOWN; - } -} - -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}); - } - return nnQuantParam; -} - -OH_NN_Format MSToNN::TransformFormat(mindspore::lite::Format msFormat) -{ - if (msFormat == mindspore::lite::FORMAT_NHWC) { - return OH_NN_Format::OH_NN_FORMAT_NHWC; - } else if (msFormat == mindspore::lite::FORMAT_NCHW) { - return OH_NN_Format::OH_NN_FORMAT_NCHW; - } - - return OH_NN_Format::OH_NN_FORMAT_NONE; -} -} // namespace NeuralNetworkRuntime +} // namespace NeuralNetworkCore } // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/transform.h b/frameworks/native/transform.h index fc05ab5a7a27ce08c72c79f6334d3295b32f2b5f..48562e1a9286d1ad093f948de89f63b93c0b20ac 100644 --- a/frameworks/native/transform.h +++ b/frameworks/native/transform.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,43 +13,14 @@ * limitations under the License. */ -#ifndef NEURAL_NETWORK_RUNTIME_TRANSFORM_H -#define NEURAL_NETWORK_RUNTIME_TRANSFORM_H +#ifndef NEURAL_NETWORK_CORE_TRANSFORM_H +#define NEURAL_NETWORK_CORE_TRANSFORM_H -#include "interfaces/kits/c/neural_network_runtime_type.h" -#include "cpp_type.h" -#include "mindir.h" -#include "mindir_types.h" -#include "ops_builder.h" +#include "v2_0/neural_network_core_type.h" namespace OHOS { -namespace NeuralNetworkRuntime { -template -std::vector ConstructVectorFromArray(const T* data, size_t size) -{ - std::vector array; - if (data != nullptr) { - array.assign(data, data + size); - } - return array; -} - -uint32_t GetTypeSize(OH_NN_DataType type); - - -namespace NNToMS { -mindspore::lite::DataType TransformDataType(OH_NN_DataType type); -mindspore::lite::Format TransformFormat(OH_NN_Format type); -mindspore::lite::ActivationType TransfromFusionType(OH_NN_FuseType type); -mindspore::lite::QuantType TransformQuantType(OHOS::NeuralNetworkRuntime::Ops::OpsQuantType type); -mindspore::lite::PadMode TransformPadModeValue(int8_t padMode); -} // NNToMS - -namespace MSToNN { -OH_NN_DataType TransformDataType(mindspore::lite::DataType type); -std::vector TransformQuantParams(std::vector msQuantParams); -OH_NN_Format TransformFormat(mindspore::lite::Format msFormat); -} // namespace MSToNN -} // namespace NeuralNetworkRuntime +namespace NeuralNetworkCore { +uint32_t GetTypeSize(OH_NNCore_DataType type); +} // namespace NeuralNetworkCore } // namespace OHOS -#endif // NEURAL_NETWORK_RUNTIME_TRANSFORM_H \ No newline at end of file +#endif // NEURAL_NETWORK_CORE_TRANSFORM_H diff --git a/frameworks/native/validation.cpp b/frameworks/native/validation.cpp index d451601d122036d916cf0fac1dd5eb7f2a240318..8075d2c29cf2c3cdf3757c8a7e47f8ffa47ba97f 100644 --- a/frameworks/native/validation.cpp +++ b/frameworks/native/validation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,68 +13,32 @@ * limitations under the License. */ -#include "mindir_types.h" - #include "validation.h" namespace OHOS { -namespace NeuralNetworkRuntime { +namespace NeuralNetworkCore { namespace Validation { -bool ValidateTensorDataType(OH_NN_DataType dataType) -{ - if (dataType >= OH_NN_UNKNOWN && dataType <= OH_NN_FLOAT64) { - return true; - } - return false; -} - -bool ValidateTensorFormat(OH_NN_Format format) -{ - if ((format >= OH_NN_FORMAT_NONE) && (format <= OH_NN_FORMAT_NHWC)) { - return true; - } - return false; -} - -bool ValidatePerformanceMode(OH_NN_PerformanceMode performanceMode) -{ - if ((performanceMode >= OH_NN_PERFORMANCE_NONE) && (performanceMode <= OH_NN_PERFORMANCE_EXTREME)) { - return true; - } - return false; -} - -bool ValidatePriority(OH_NN_Priority priority) +bool ValidateFormat(OH_NNCore_Format format) { - if ((priority >= OH_NN_PRIORITY_NONE) && (priority <= OH_NN_PRIORITY_HIGH)) { + if ((format >= OH_NNCORE_FORMAT_NCHW) && (format <= OH_NNCORE_ND)) { return true; } - return false; -} - -bool ValidateFuseType(OH_NN_FuseType fuseType) -{ - if ((fuseType >= OH_NN_FUSED_NONE) && (fuseType <= OH_NN_FUSED_RELU6)) { + if (format == OH_NNCORE_FORMAT_NONE) { return true; } return false; } -bool ValidatePadMode(int8_t padMode) +bool ValidateDataType(OH_NNCore_DataType dataType) { - if ((padMode >= mindspore::lite::PAD_MODE_PAD) && (padMode <= mindspore::lite::PAD_MODE_VALID)) { + if ((dataType >= OH_NNCORE_UINT8) && (dataType <= OH_NNCORE_FLOAT64)) { return true; } - return false; -} - -bool ValidateTensorType(OH_NN_TensorType nnTensorType) -{ - if ((nnTensorType >= OH_NN_TENSOR) && (nnTensorType <= OH_NN_UNSQUEEZE_AXIS)) { + if (dataType == OH_NNCORE_OTHER_TYPES) { return true; } - return false; + return true; } } // namespace Validation -} // namespace NeuralNetworkRuntime +} // NeuralNetworkCore } // namespace OHOS diff --git a/frameworks/native/validation.h b/frameworks/native/validation.h index 7c6d54012a3dfb923e4edcb21b61c7abac399758..1718b2194f874cd814eaad10bdf096c213783fca 100644 --- a/frameworks/native/validation.h +++ b/frameworks/native/validation.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,35 +13,18 @@ * limitations under the License. */ -#ifndef NEURAL_NETWORK_RUNTIME_VALIDATION_H -#define NEURAL_NETWORK_RUNTIME_VALIDATION_H +#ifndef NEURAL_NETWORK_CORE_VALIDATION_H +#define NEURAL_NETWORK_CORE_VALIDATION_H -#include "common/log.h" -#include "interfaces/kits/c/neural_network_runtime.h" +#include "v2_0/neural_network_core_type.h" namespace OHOS { -namespace NeuralNetworkRuntime { +namespace NeuralNetworkCore { namespace Validation { -template -OH_NN_ReturnCode ValidateArray(const T* data, size_t size) -{ - if ((data != nullptr) != (size > 0)) { - LOGE("ValidateArray failed, data should passed a valid pointer when size is larger than 0, " - "otherwise, data should be nullptr when size is 0."); - return OH_NN_INVALID_PARAMETER; - } - return OH_NN_SUCCESS; -} - -bool ValidateTensorType(OH_NN_TensorType nnTensorType); -bool ValidateTensorDataType(OH_NN_DataType dataType); -bool ValidateTensorFormat(OH_NN_Format format); -bool ValidatePerformanceMode(OH_NN_PerformanceMode performanceMode); -bool ValidatePriority(OH_NN_Priority priority); -bool ValidateFuseType(OH_NN_FuseType fuseType); -bool ValidatePadMode(int8_t padMode); +bool ValidateFormat(OH_NNCore_Format format); +bool ValidateDataType(OH_NNCore_DataType dataType); } // namespace Validation -} // NeuralNetworkRuntime +} // NeuralNetworkCore } // namespace OHOS -#endif // NEURAL_NETWORK_RUNTIME_VALIDATION_H +#endif // NEURAL_NETWORK_CORE_VALIDATION_H diff --git a/interfaces/innerkits/c/neural_network_runtime_inner.h b/interfaces/innerkits/c/neural_network_runtime_inner.h index 314e986ff92704608cf8d0cb5674c5ff07aae082..28de2c6bba39fc9c7e3b54bfc4102d03951923b9 100644 --- a/interfaces/innerkits/c/neural_network_runtime_inner.h +++ b/interfaces/innerkits/c/neural_network_runtime_inner.h @@ -16,7 +16,7 @@ #ifndef NEURAL_NETWORK_RUNTIME_INNER_H #define NEURAL_NETWORK_RUNTIME_INNER_H -#include "interfaces/kits/c/neural_network_runtime_type.h" +#include "interfaces/kits/c/v1_0/neural_network_runtime_type_compat.h" #ifdef __cplusplus extern "C" { diff --git a/interfaces/kits/c/BUILD.gn b/interfaces/kits/c/BUILD.gn index 856097adcf97de1304cc37f8b1fdf2fa03d4382e..101e7aa2c119be34c19360a85ee82030ccf1b490 100644 --- a/interfaces/kits/c/BUILD.gn +++ b/interfaces/kits/c/BUILD.gn @@ -28,7 +28,9 @@ ohos_ndk_library("libneural_network_runtime_ndk") { ohos_ndk_headers("libneural_network_runtime_header") { dest_dir = "$ndk_headers_out_dir/neural_network_runtime" sources = [ - "neural_network_runtime.h", - "neural_network_runtime_type.h", + "v2_0/neural_network_core.h", + "v2_0/neural_network_core_type.h", + "v2_0/neural_network_runtime.h", + "v2_0/neural_network_runtime_type.h", ] } diff --git a/interfaces/kits/c/neural_network_runtime.h b/interfaces/kits/c/v1_0/neural_network_runtime_compat.h similarity index 99% rename from interfaces/kits/c/neural_network_runtime.h rename to interfaces/kits/c/v1_0/neural_network_runtime_compat.h index b7740e18b332cf62ae3e71445f2e79965194699d..d722b7bbe65f9aeb96a068fc2f07d907c22c9442 100644 --- a/interfaces/kits/c/neural_network_runtime.h +++ b/interfaces/kits/c/v1_0/neural_network_runtime_compat.h @@ -36,10 +36,10 @@ * @version 1.0 */ -#ifndef NEURAL_NETWORK_RUNTIME_H -#define NEURAL_NETWORK_RUNTIME_H +#ifndef NEURAL_NETWORK_RUNTIME_COMPAT_H +#define NEURAL_NETWORK_RUNTIME_COMPAT_H -#include "neural_network_runtime_type.h" +#include "neural_network_runtime_type_compat.h" #ifdef __cplusplus extern "C" { @@ -688,4 +688,4 @@ OH_NN_ReturnCode OH_NNDevice_GetType(size_t deviceID, OH_NN_DeviceType *deviceTy #endif // __cplusplus /** @} */ -#endif // NEURAL_NETWORK_RUNTIME_H +#endif // NEURAL_NETWORK_RUNTIME_COMPAT_H diff --git a/interfaces/kits/c/neural_network_runtime_type.h b/interfaces/kits/c/v1_0/neural_network_runtime_type_compat.h similarity index 99% rename from interfaces/kits/c/neural_network_runtime_type.h rename to interfaces/kits/c/v1_0/neural_network_runtime_type_compat.h index 00aefb6562d55ee218615a0a923c6e90423bc633..a8c2370c01bd61e9a396160ca5e27c2bf780fdf6 100644 --- a/interfaces/kits/c/neural_network_runtime_type.h +++ b/interfaces/kits/c/v1_0/neural_network_runtime_type_compat.h @@ -34,8 +34,8 @@ * @version 1.0 */ -#ifndef NEURAL_NETWORK_RUNTIME_TYPE_H -#define NEURAL_NETWORK_RUNTIME_TYPE_H +#ifndef NEURAL_NETWORK_RUNTIME_TYPE_COMPAT_H +#define NEURAL_NETWORK_RUNTIME_TYPE_COMPAT_H #include #include @@ -1781,4 +1781,4 @@ typedef struct OH_NN_Memory { #endif // __cplusplus /** @} */ -#endif // NEURAL_NETWORK_RUNTIME_TYPE_H +#endif // NEURAL_NETWORK_RUNTIME_TYPE_COMPAT_H diff --git a/interfaces/kits/c/v2_0/en/neural_network_core.h b/interfaces/kits/c/v2_0/en/neural_network_core.h new file mode 100644 index 0000000000000000000000000000000000000000..2ca03ab44523c2a405147b13c9ad36e863d237b0 --- /dev/null +++ b/interfaces/kits/c/v2_0/en/neural_network_core.h @@ -0,0 +1,569 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_CORE_API_H +#define NEURAL_NETWORK_CORE_API_H + +#include "neural_network_core_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Compilation APIs +OH_NNCore_ReturnCode OH_NNCore_GetBackendNum(size_t* backendNum); + +OH_NNCore_ReturnCode OH_NNCore_GetBackendName(size_t index, const char** backendName); + +OH_NNCore_Compilation* OH_NNCore_ConstructCompilationWithNNModel(const void* model); + +OH_NNCore_Compilation* OH_NNCore_ConstructCompilationWithOfflineModel(const char* filePath); + +OH_NNCore_Compilation* OH_NNCore_ConstructCompilationWithOfflineBuffer(const void* modelData, size_t modelSize); + +/** + * @brief Execute model compilation + * + * This interface is used to compile the built {@link OH_NNCore_Compilation} instance into a {@link OH_NNCore_Compiled} instance. The device and + * compilation options required for compilation can be set through backend and options. + * + * After creating the {@link OH_NNCore_Compiled} instance, if you no longer need to compile, you can call the {@link OH_NNCore_DestroyCompilation} interface to release + * the {@link OH_NNCore_Compilation} object. + * + * @param compilation Pointer to the {@link OH_NNCore_Compiliation} instance. + * @param backendName Device name + * @param options Pointer to the {@link OH_NNCore_Options} instance. + * @return Pointer to the {@link OH_NNCore_Compiled}. + * @since 11 + * @version 2.0 + */ +OH_NNCore_Compiled* OH_NNCore_BuildCompilation(OH_NNCore_Compilation* compilation, + const char* backendName, + OH_NNCore_Options* options); + +OH_NNCore_ReturnCode OH_NNCore_DestroyCompilation(OH_NNCore_Compilation** compilation); + +// Compiled APIs +/** + * @brief Save the compiled model cache to a file + * + * On hardware that supports caching, the model can be saved as a cache file after being compiled at the hardware driver level, and the model can be read directly from the cache file during the next compilation to reduce the compilation time.\n + * + * @param compiled A pointer to an instance of {@link OH_NNCore_Compiled}. + * @param filePath The directory where the model cache is saved. + * @return The result status of the function execution. Returns OH_NNCORE_SUCCESS if successful; returns a specific error code if failed, and the specific failure error code can be found in {@link OH_NNCore_ReturnCode}. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_SaveCompiledToFile(const OH_NNCore_Compiled* compiled, const char* filePath); + +/** + * @brief Load the model cache from the cache file + * + * On hardware that supports caching, you can load the model cache previously saved by calling {@link OH_NNCore_SaveCompiledToFile} to reduce the compilation time.\n + * + * @param filePath The directory where the model cache is saved. + * @param backendName Specifies the hardware name to use. + * @param options A pointer to an instance of {@link OH_NNCore_Options}. + * @param compiled A pointer to a pointer to an instance of {@link OH_NNCore_Compiled}. It is required that `(*compiled)` is a null pointer, otherwise {@link OH_NNCORE_INVALID_PARAMETER} will be returned. + * @return The result status of the function execution. Returns OH_NNCORE_SUCCESS if successful; returns a specific error code if failed, and the specific failure error code can be found in {@link OH_NNCore_ReturnCode}. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_RestoreCompiledFromFile(const char* filePath, + const char* backendName, + const OH_NNCore_Options* options, + OH_NNCore_Compiled** compiled); + +/** + * @brief Save the compiled model cache to a buffer + * + * On hardware that supports caching, the model can be saved to the specified buffer after being compiled at the hardware driver level, and the model can be loaded directly from the model cache during the next compilation to reduce the compilation time.\n + * + * @param compiled A pointer to an instance of {@link OH_NNCore_Compiled}. + * @param buffer A pointer to the buffer. + * @param length The size of the buffer. + * @param modelSize The size of the model cache. + * @return The result status of the function execution. Returns OH_NNCORE_SUCCESS if successful; returns a specific error code if failed, and the specific failure error code can be found in {@link OH_NNCore_ReturnCode}. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_SaveCompiledToBuffer(const OH_NNCore_Compiled* compiled, + const void* buffer, + size_t length, + size_t* modelSize); + +/** + * @brief Load the model cache from the buffer + * + * On hardware that supports caching, you can load the model cache previously saved by calling {@link OH_NNCore_SaveCompiledToBuffer} to reduce the compilation time.\n + * + * @param buffer A pointer to the buffer. + * @param modelSize The size of the model cache. + * @param backendName Specifies the hardware name to use. + * @param options A pointer to an instance of {@link OH_NNCore_Options}. + * @param compiled A pointer to a pointer to an instance of {@link OH_NNCore_Compiled}. It is required that `(*compiled)` is a null pointer, otherwise {@link OH_NNCORE_INVALID_PARAMETER} will be returned. + * @return The result status of the function execution. Returns OH_NNCORE_SUCCESS if successful; returns a specific error code if failed, and the specific failure error code can be found in {@link OH_NNCore_ReturnCode}. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_RestoreCompiledFromBuffer(const void* buffer, + size_t modelSize, + const char* backendName, + const OH_NNCore_Options* options, + OH_NNCore_Compiled** compiled); + +/** + * @brief Get the number of input tensors of the compiled model + * + * After the model is compiled, you can call this interface to obtain the number of input tensors, and use {@link OH_NNCore_CreateCompiledInputDesc} to obtain the specified input tensor descriptor.\n + * + * @param compiled A pointer to an instance of {@link OH_NNCore_Compiled}. + * @param inputNum The number of input tensors. + * @return The result status of the function execution. Returns OH_NNCORE_SUCCESS if successful; returns a specific error code if failed, and the specific failure error code can be found in {@link OH_NNCore_ReturnCode}. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_GetCompiledInputNum(const OH_NNCore_Compiled* compiled, size_t* inputNum); + +/** + * @brief Create the input tensor descriptor of the compiled model + * + * After the model compilation is complete, this interface can be called to create the input tensor descriptor specified by index. The {@link OH_NNCore_Compiled} instance created by this interface + * needs to call {@link OH_NNCore_DestroyTensorDesc} to destroy.\n + * + * @param compiled Pointer to the {@link OH_NNCore_Compiled} instance + * @param inputNum Number of input tensors + * @return The result status of the function execution. If the execution is successful, return OH_NNCOER_SUCCESS; if it fails, return a specific error code, the specific failure error code can refer to {@link OH_NNCore_ReturnCode}. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_CreateCompiledInputDesc(const OH_NNCore_Compiled* compiled, + size_t index, + OH_NNCore_TensorDesc** tensorDesc); + +/** + * @brief Get the number of output tensors of the compiled model + * + * After the model compilation is complete, this interface can be called to get the number of output tensors, and combined with {@link OH_NNCore_CreateCompiledOutputDesc}, get the specified output tensor descriptor.\n + * + * @param compiled Pointer to the {@link OH_NNCore_Compiled} instance. + * @param inputNum Number of input tensors + * @return The result status of the function execution. If the execution is successful, return OH_NNCOER_SUCCESS; if it fails, return a specific error code, the specific failure error code can refer to {@link OH_NNCore_ReturnCode}. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_GetCompiledOutputNum(const OH_NNCore_Compiled* compiled, size_t* outputNum); + +/** + * @brief Create the output tensor descriptor of the compiled model + * + * After the model compilation is complete, this interface can be called to create the output tensor descriptor specified by index. The {@link OH_NNCore_Compiled} instance created by this interface + * needs to call {@link OH_NNCore_DestroyTensorDesc} to destroy.\n + * + * @param compiled Pointer to the {@link OH_NNCore_Compiled} instance + * @param inputNum Number of output tensors + * @return The result status of the function execution. If the execution is successful, return OH_NNCOER_SUCCESS; if it fails, return a specific error code, the specific failure error code can refer to {@link OH_NNCore_ReturnCode}. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_CreateCompiledOutputDesc(const OH_NNCore_Compiled* compiled, + size_t index, + OH_NNCore_TensorDesc** tensorDesc); + +/** + * @brief Release the compiled model instance. + * + * The {@link OH_NNCore_Compiled} instance created by calling {@link OH_NNCore_BuildCompilation}, {@link OH_NNCore_RestoreCompiledFromFile} or {@link OH_NNCore_RestoreCompiledFromBuffer} + * needs to call this method to actively release, otherwise it will cause memory leaks.\n + * + * If compiled is a null pointer or *compiled is a null pointer, this method only prints a warning log and does not execute the release logic.\n + * + * @param compiled A second-level pointer to the {@link OH_NNCore_Compiled} instance. After the model instance is destroyed, this method actively sets *compiled to a null pointer. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_DestroyCompiled(OH_NNCore_Compiled** compiled); + +/** + * @brief Create an OH_NNCore_TensorDesc instance object. + * + * This interface creates an OH_NNCore_TensorDesc object, which is used to describe various Tensor information, including name/dataType/shape/format and other information. + * With the OH_NNCore_TensorDesc instance object, you can further call OH_NNCore_CreateTensor to create a Tensor instance object and get the Tensor memory. + * + * @return A pointer to the OH_NNCore_TensorDesc object. + * @since 11 + * @version 2.0 + */ +OH_NNCore_TensorDesc* OH_NNCore_CreateTensorDesc(); + +/** + * @brief Release the OH_NNCore_TensorDesc instance object. + * + * After creating the OH_NNCore_TensorDesc instance, if you no longer need to use it, call this interface to release the OH_NNCore_TensorDesc object, otherwise it will cause memory leaks. + * + * If tensorDesc or *tensorDesc is a null pointer, the interface will return an error code. + * + * @param tensorDesc A second-level pointer to the OH_NNCore_TensorDesc object. + * @return Returns the function execution result status code. If the execution is successful, return OH_NNCORE_SUCCESS, otherwise return other types of error codes OH_NNCore_ReturnCode. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_DestroyTensorDesc(OH_NNCore_TensorDesc** tensorDesc); + +/** + * @brief Set the name of the OH_NNCore_TensorDesc object. + * + * After creating the OH_NNCore_TensorDesc instance, call this interface to set the Tensor name for the OH_NNCore_TensorDesc object. + * + * If tensorDesc or name is a null pointer, the interface will return an error code. + * + * @param tensorDesc Pointer to the OH_NNCore_TensorDesc object. + * @param name Tensor name. + * @return Returns the function execution result status code. If the execution is successful, return OH_NNCORE_SUCCESS, otherwise return other types of error codes OH_NNCore_ReturnCode. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_SetTensorDescName(OH_NNCore_TensorDesc* tensorDesc, const char* name); + +/** + * @brief Get the name of the OH_NNCore_TensorDesc object. + * + * Call this interface to get the name of the specified OH_NNCore_TensorDesc object. + * + * If tensorDesc or name is a null pointer, the interface will return an error code. As an output parameter, *name must be a null pointer, otherwise the interface will return an error code. + * + * @param tensorDesc Pointer to the OH_NNCore_TensorDesc object. + * @param name Return Tensor name. + * @return Returns the function execution result status code. If the execution is successful, return OH_NNCORE_SUCCESS, otherwise return other types of error codes OH_NNCore_ReturnCode. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_GetTensorDescName(const OH_NNCore_TensorDesc* tensorDesc, const char** name); + +/** + * @brief Set the data type of the OH_NNCore_TensorDesc object. + * + * After creating the OH_NNCore_TensorDesc instance, call this interface to set the data type for the OH_NNCore_TensorDesc object. + * + * If tensorDesc is a null pointer, the interface will return an error code. + * + * @param tensorDesc Pointer to the OH_NNCore_TensorDesc object. + * @param dataType Tensor data type. + * @return Returns the function execution result status code. If the execution is successful, return OH_NNCORE_SUCCESS, otherwise return other types of error codes OH_NNCore_ReturnCode. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_SetTensorDescDataType(OH_NNCore_TensorDesc* tensorDesc, OH_NNCore_DataType dataType); + +/** + * @brief Get the data type of the OH_NNCore_TensorDesc object. + * + * Call this interface to get the data type of the specified OH_NNCore_TensorDesc object. + * + * If tensorDesc or dataType is a null pointer, the interface will return an error code. + * + * @param tensorDesc Pointer to the OH_NNCore_TensorDesc object. + * @param dataType Return Tensor data type. + * @return Returns the function execution result status code. If the execution is successful, return OH_NNCORE_SUCCESS, otherwise return other types of error codes OH_NNCore_ReturnCode. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_GetTensorDescDataType(const OH_NNCore_TensorDesc* tensorDesc, + OH_NNCore_DataType* dataType); + +/** + * @brief Set the shape information of the OH_NNCore_TensorDesc object. + * + * After creating the OH_NNCore_TensorDesc instance, call this interface to set the shape information for the OH_NNCore_TensorDesc object. + * + * If tensorDesc or shape is a null pointer, or if shapeNum is 0, the interface will return an error code. + * + * @param tensorDesc Pointer to the OH_NNCore_TensorDesc object. + * @param shape Pointer to the array of shape information. + * @param shapeNum The length of the above shape array. + * @return Returns the function execution result status code. If the execution is successful, return OH_NNCORE_SUCCESS, otherwise return other types of error codes OH_NNCore_ReturnCode. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_SetTensorDescShape(OH_NNCore_TensorDesc* tensorDesc, + const int32_t* shape, + size_t shapeNum); + +/** + * @brief Get the shape information of the OH_NNCore_TensorDesc object. + * + * Call this interface to get the shape information of the specified OH_NNCore_TensorDesc object. + * + * If tensorDesc, shape, or shapeNum is a null pointer, the interface will return an error code. As an output parameter, *shape must be a null pointer, otherwise the interface will return an error code. + * + * @param tensorDesc Pointer to the OH_NNCore_TensorDesc object. + * @param shape Return Tensor shape array information. + * @param shapeNum Return Tensor shape array length. + * @return Returns the function execution result status code. If the execution is successful, return OH_NNCORE_SUCCESS, otherwise return other types of error codes OH_NNCore_ReturnCode. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_GetTensorDescShape(const OH_NNCore_TensorDesc* tensorDesc, + int32_t** shape, + size_t* shapeNum); + +/** + * @brief Set the format information of the OH_NNCore_TensorDesc object. + * + * After creating the OH_NNCore_TensorDesc instance, call this interface to set the format information for the OH_NNCore_TensorDesc object. + * + * If tensorDesc is a null pointer, the interface will return an error code. + * + * @param tensorDesc Pointer to the OH_NNCore_TensorDesc object. + * @param format Tensor format information. + * @return Returns the function execution result status code. If the execution is successful, return OH_NNCORE_SUCCESS, otherwise return other types of error codes OH_NNCore_ReturnCode. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_SetTensorDescFormat(OH_NNCore_TensorDesc* tensorDesc, OH_NNCore_Format format); + +/** + * @brief Get the format information of the OH_NNCore_TensorDesc object. + * + * Call this interface to get the format information of the specified OH_NNCore_TensorDesc object. + * + * If tensorDesc or format is a null pointer, the interface will return an error code. + * + * @param tensorDesc Pointer to the OH_NNCore_TensorDesc object. + * @param format Return Tensor format information. + * @return Returns the function execution result status code. If the execution is successful, return OH_NNCORE_SUCCESS, otherwise return other types of error codes OH_NNCore_ReturnCode. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_GetTensorDescFormat(const OH_NNCore_TensorDesc* tensorDesc, OH_NNCore_Format* format); + +/** + * @brief Get the number of elements of the OH_NNCore_TensorDesc object. + * + * Call this interface to get the number of elements of the specified OH_NNCore_TensorDesc object. If you need to get the number of bytes, you can call the OH_NNCore_GetTensorDescByteSize interface to get it. + * + * If tensorDesc or elementNum is a null pointer, the interface will return an error code. + * + * @param tensorDesc Pointer to the OH_NNCore_TensorDesc object. + * @param elementNum Return Tensor number of elements. + * @return Returns the function execution result status code. If the execution is successful, return OH_NNCORE_SUCCESS, otherwise return other types of error codes OH_NNCore_ReturnCode. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_GetTensorDescElementNum(const OH_NNCore_TensorDesc* tensorDesc, size_t* elementNum); + +/** + * @brief Get the number of bytes of the OH_NNCore_TensorDesc object. + * + * Call this interface to get the number of bytes of the specified OH_NNCore_TensorDesc object. If you need to get the number of elements, you can call the OH_NNCore_GetTensorDescElementNum interface to get it. + * + * If tensorDesc or byteSize is a null pointer, the interface will return an error code. + * + * @param tensorDesc Pointer to the OH_NNCore_TensorDesc object. + * @param byteSize Return Tensor number of bytes. + * @return Returns the function execution result status code. If the execution is successful, return OH_NNCORE_SUCCESS, otherwise return other types of error codes OH_NNCore_ReturnCode. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_GetTensorDescByteSize(const OH_NNCore_TensorDesc* tensorDesc, size_t* byteSize); + +/** + * @brief Create an OH_NNCore_Tensor instance object. + * + * This interface creates an OH_NNCore_Tensor instance object and applies for the corresponding backend data memory at the same time. backendName represents the name of the selected backend, it can be a null pointer, if it is a null pointer, the default is to use the 0th backend. + * desc must be provided, if it is a null pointer, the interface returns an error code. This interface gets the number of bytes according to the OH_NNCore_GetTensorDescByteSize in desc, and creates a memory of the corresponding size. + * + * @param backendName Backend name, can be a null pointer, if it is a null pointer, the default is to use the 0th backend in the current backend list. + * @param desc Pointer to the OH_NNCore_TensorDesc object, save various Tensor description information. + * @return Pointer to the OH_NNCore_Tensor object. + * @since 11 + * @version 2.0 + */ +OH_NNCore_Tensor* OH_NNCore_CreateTensor(const char* backendName, OH_NNCore_TensorDesc* desc); + +/** + * @brief Create an OH_NNCore_Tensor instance object. + * + * This interface creates an OH_NNCore_Tensor instance object and applies for the corresponding backend data memory at the same time. backendName represents the name of the selected backend, it can be a null pointer, if it is a null pointer, the default is to use the 0th backend. + * desc must be provided, if it is a null pointer, the interface returns an error code. This interface creates a memory of the corresponding size according to the passed in parameter size. + * + * @param backendName Backend name, can be a null pointer, if it is a null pointer, the default is to use the 0th backend in the current backend list. + * @param desc Pointer to the OH_NNCore_TensorDesc object, save various Tensor description information. + * @param size The size of the data memory to be created. + * @return Pointer to the OH_NNCore_Tensor object. + * @since 11 + * @version 2.0 + */ +OH_NNCore_Tensor* OH_NNCore_CreateTensorWithSize(const char* backendName, + OH_NNCore_TensorDesc* desc, + size_t size); + +/** + * @brief Create an OH_NNCore_Tensor instance object. + * + * This interface creates an OH_NNCore_Tensor instance object and reuses the memory corresponding to the fd passed in by the user at the same time. backendName represents the name of the selected backend, it can be a null pointer, if it is a null pointer, the default is to use the 0th backend. + * desc must be provided, if it is a null pointer, the interface returns an error code. This interface will judge that the available memory (size-offset) of the user-passed fd must be greater than or equal to the number of bytes obtained in desc's OH_NNCore_GetTensorDescByteSize. + * This fd must be the memory created by the OH_NNCore_CreateTensor or OH_NNCore_CreateTensorWithSize interface before. + * + * @param backendName Backend name, can be a null pointer, if it is a null pointer, the default is to use the 0th backend in the current backend list. + * @param desc Pointer to the OH_NNCore_TensorDesc object, save various Tensor description information. + * @param fd Memory descriptor. + * @param size Memory size. + * @param offset Memory offset. + * @return Pointer to the OH_NNCore_Tensor object. + * @since 11 + * @version 2.0 + */ +OH_NNCore_Tensor* OH_NNCore_CreateTensorWithFd(const char* backendName, + OH_NNCore_TensorDesc* desc, + int fd, + size_t size, + size_t offset); + + +OH_NNCore_ReturnCode OH_NNCore_DestroyTensor(OH_NNCore_Tensor** tensor); + +OH_NNCore_TensorDesc* OH_NNCore_GetTensorDesc(const OH_NNCore_Tensor* tensor); + +void* OH_NNCore_GetDataBuffer(const OH_NNCore_Tensor* tensor); + +OH_NNCore_ReturnCode OH_NNCore_GetSize(const OH_NNCore_Tensor* tensor, size_t* size); + +OH_NNCore_ReturnCode OH_NNCore_GetFd(const OH_NNCore_Tensor* tensor, int* fd); + +OH_NNCore_ReturnCode OH_NNCore_GetOffset(const OH_NNCore_Tensor* tensor, size_t* offset); + +/** + * @brief Create an OH_NNCore_Executor instance object. + * + * This interface can create a model executor from the compiled object, and then call the OH_NNCore_ExecutorRunSync or OH_NNCore_ExecutorRunAsync interface to execute inference. + * If compiled is a null pointer, the OH_NNCore_Executor object cannot be created, and the interface returns a null pointer. + * + * After creating the OH_NNCore_Executor instance, if you no longer need to perform inference, call the OH_NNCore_DestroyExecutor interface to release the OH_NNCore_Executor object. + * + * @param compiled Pointer to the OH_NNCore_Compiled object. + * @return Pointer to the OH_NNCore_Executor object. + * @since 11 + * @version 2.0 + */ +OH_NNCore_Executor* OH_NNCore_ConstructExecutor(const OH_NNCore_Compiled* compiled); + +/** + * @brief Destroy the OH_NNCore_Executor instance object. + * + * After the inference is completed, when you no longer need to perform inference, call this interface to destroy the OH_NNCore_Executor instance object created by OH_NNCore_ConstructExecutor. + * If you do not call this interface to destroy the OH_NNCore_Executor instance object, it will cause a memory leak. + * + * If executor or *executor is a null pointer, the interface will return an error code. + * + * @param executor Second-level pointer to OH_NNCore_Executor. + * @return Returns the function execution result status code. If the execution is successful, return OH_NNCORE_SUCCESS, otherwise return other types of error codes OH_NNCore_ReturnCode. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_DestroyExecutor(OH_NNCore_Executor** executor); + +/** + * @brief + * + * If executor or onRunDone is a null pointer, the interface will return an error code. + * + * @param executor Pointer to the OH_NNCore_Executor object. + * @param onRunDone Pointer to the OH_NNCore_OnRunDone function. + * @return Returns the function execution result status code. If the execution is successful, return OH_NNCORE_SUCCESS, otherwise return other types of error codes OH_NNCore_ReturnCode. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_SetExecutorOnRunDone(OH_NNCore_Executor* executor, OH_NNCore_OnRunDone onRunDone); + +/** + * @brief + * + * If executor or onRunDone is a null pointer, the interface will return an error code. + * + * @param executor Pointer to the OH_NNCore_Executor object. + * @param onServiceDied Pointer to the OH_NNCore_OnServiceDied function. + * @return Returns the function execution result status code. If the execution is successful, return OH_NNCORE_SUCCESS, otherwise return other types of error codes OH_NNCore_ReturnCode. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_SetExecutorOnServiceDied(OH_NNCore_Executor* executor, + OH_NNCore_OnServiceDied onServiceDied); + +/** + * @brief Execute model synchronous inference + * + * Perform model synchronous inference according to the given input inputTensor, and the execution result is stored in the given output outputTensor. + * + * If executor is a null pointer, the interface will return an error code. + * + * @param executor Pointer to the OH_NNCore_Executor object. + * @param inputTensor Pointer array to the OH_NNCore_Tensor. + * @param inputSize Represents the length of the above inputTensor array. + * @param outputTensor Pointer array to the OH_NNCore_Tensor. + * @param outputSize Represents the length of the above outputTensor array. + * @return Returns the function execution result status code. If the execution is successful, return OH_NNCORE_SUCCESS, otherwise return other types of error codes OH_NNCore_ReturnCode. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_ExecutorRunSync(OH_NNCore_Executor* executor, + OH_NNCore_Tensor* inputTensor[], + size_t inputNum, + OH_NNCore_Tensor* outputTensor[], + size_t outputNum); + +/** + * @brief Execute model asynchronous inference + * + * Perform model asynchronous inference according to the given input inputTensor, and the execution result is stored in the given output outputTensor. + * + * If executor is a null pointer, the interface will return an error code. + * + * @param executor Pointer to the OH_NNCore_Executor object. + * @param inputTensor Pointer array to the OH_NNCore_Tensor. + * @param inputSize Represents the length of the above inputTensor array. + * @param outputTensor Pointer array to the OH_NNCore_Tensor. + * @param outputSize Represents the length of the above outputTensor array. + * @param timeout + * @param userData + * @return Returns the function execution result status code. If the execution is successful, return OH_NNCORE_SUCCESS, otherwise return other types of error codes OH_NNCore_ReturnCode. + * @since 11 + * @version 2.0 + */ + +OH_NNCore_ReturnCode OH_NNCore_ExecutorRunAsync(OH_NNCore_Executor* executor, + OH_NNCore_Tensor* inputTensor[], + size_t inputNum, + OH_NNCore_Tensor* outputTensor[], + size_t outputNum, + int32_t timeout, + void* userData); + +OH_NNCore_Options* OH_NNCore_CreateOptions(const char* backendName); + +OH_NNCore_ReturnCode OH_NNCore_DestroyOptions(OH_NNCore_Options** options); + +OH_NNCore_ReturnCode OH_NNCore_SetPriority(OH_NNCore_Options* options, OH_NNCore_Priority priority); + +OH_NNCore_ReturnCode OH_NNCore_SetPerformanceMode(OH_NNCore_Options* options, + OH_NNCore_PerformanceMode performanceMode); + +OH_NNCore_ReturnCode OH_NNCore_SetEnableFloat16(OH_NNCore_Options* options, bool enableFloat16); + +#ifdef __cplusplus +} +#endif // __cplusplus +#endif // NEURAL_NETWORK_CORE_API_H diff --git a/interfaces/kits/c/v2_0/en/neural_network_core_type.h b/interfaces/kits/c/v2_0/en/neural_network_core_type.h new file mode 100644 index 0000000000000000000000000000000000000000..672764749ea48081ff5845770b3520fcc2e91514 --- /dev/null +++ b/interfaces/kits/c/v2_0/en/neural_network_core_type.h @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_RUNTIME_CORE_TYPE_H +#define NEURAL_NETWORK_RUNTIME_CORE_TYPE_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct OH_NNCore_TensorDesc OH_NNCore_TensorDesc; +typedef struct OH_NNCore_Compilation OH_NNCore_Compilation; +typedef struct OH_NNCore_Compiled OH_NNCore_Compiled; +typedef struct OH_NNCore_Executor OH_NNCore_Executor; +typedef struct OH_NNCore_Options OH_NNCore_Options; +typedef struct OH_NNCore_Tensor OH_NNCore_Tensor; +typedef void (*OH_NNCore_OnRunDone)(void* OH_NNCore_ReturnCode, void* [], int32_t); +typedef void (*OH_NNCore_OnServiceDied)(void*); + +typedef enum { + /** The tensor arrange data in NCHW format. */ + OH_NNCORE_FORMAT_NCHW = 0, + /** The tensor arrange data in NHWC format. */ + OH_NNCORE_FORMAT_NHWC = 1, + /** The tensor arrange data in ND format. */ + OH_NNCORE_ND = 2, + /** The tensor does not have a specific layout type (such as scalar or vector).*/ + OH_NNCORE_FORMAT_NONE = 99 +} OH_NNCore_Format; + +typedef enum { + /** The operation is successful. */ + OH_NNCORE_SUCCESS = 0, + /** The operation failed. */ + OH_NNCORE_FAILED = 1, + /** Uninitilaized */ + OH_NNCORE_UNINITIALIZED = 2, + /** Invalid parameter. */ + OH_NNCORE_INVALID_PARAMETER = 3, + /** Timeout. */ + OH_NNCORE_TIMEOUT = 4, + /** Unsupported */ + OH_NNCORE_UNSUPPORTED = 5, + /** Memory Exception */ + OH_NNCORE_MEMORY_EXCEPTION = 6, + /** INVALID API */ + OH_NNCORE_INVALID_API = 7, + /** Invalid Pointer */ + OH_NNCORE_INVALID_POINTER = 8, + /** Calculate Exception */ + OH_NNCORE_CALC_EXCEPTION = 9, + /** Invalid File */ + OH_NNCORE_INVALID_FILE = 10, + /** Common Exception*/ + OH_NNCORE_COMM_EXCEPTION = 11, + /** Data Overflow */ + OH_NNCORE_DATA_OVERFLOW = 12, + /** Unavailable Backend */ + OH_NNCORE_UNAVAILABLE_BACKEND = 13, + /** Connect Exception */ + OH_NNCORE_CONNECT_EXCEPTION = 19, + /** Operation Forbidden */ + OH_NNCORE_OPERATION_FORBIDDEN = 20, + /** NULL Pointer */ + OH_NNCORE_NULL_PTR = 21, + /** Invalid Path */ + OH_NNCORE_INVALID_PATH = 22, +} OH_NNCore_ReturnCode; + +typedef enum { + /** uint8 */ + OH_NNCORE_UINT8 = 0, + /** float32 */ + OH_NNCORE_FLOAT32 = 1, + /** float16 */ + OH_NNCORE_FLOAT16 = 2, + /** int32 */ + OH_NNCORE_INT32 = 3, + /** int8 */ + OH_NNCORE_INT8 = 4, + /** int16 */ + OH_NNCORE_INT16 = 5, + /** bool */ + OH_NNCORE_BOOL = 6, + /** int64 */ + OH_NNCORE_INT64 = 7, + /** uint32 */ + OH_NNCORE_UINT32 = 8, + /** double */ + OH_NNCORE_DOUBLE = 9, + /** uint16 */ + OH_NNCORE_UINT16 = 10, + /** uint64 */ + OH_NNCORE_UINT64 = 11, + /** float64 */ + OH_NNCORE_FLOAT64 = 12, + /** Unknown type */ + OH_NNCORE_OTHER_TYPES = 99 +} OH_NNCore_DataType; + +typedef enum { + /** Unknown type */ + OH_NNCORE_UNKNOWN_BACKEND_STATUS = 0, + /** Available */ + OH_NNCORE_AVAILABLE = 1, + /** Busy */ + OH_NNCORE_BUSY = 2, + /** Offline */ + OH_NNCORE_OFFLINE = 3, +} OH_NNCore_BackendStatus; + +/** + * @brief Defines the hardware performance mode. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** No performance mode preference */ + OH_NNCORE_PERFORMANCE_NONE = 0, + /** Low power consumption mode*/ + OH_NNCORE_PERFORMANCE_LOW = 1, + /** Medium performance mode */ + OH_NNCORE_PERFORMANCE_MEDIUM = 2, + /** High performance mode */ + OH_NNCORE_PERFORMANCE_HIGH = 3, + /** Ultimate performance mode */ + OH_NNCORE_PERFORMANCE_EXTREME = 4 +} OH_NNCore_PerformanceMode; + +/** + * @brief Defines the model inference task priority. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** No priority preference */ + OH_NNCORE_PRIORITY_NONE = 0, + /** Low priority */ + OH_NNCORE_PRIORITY_LOW = 1, + /** Medium priority */ + OH_NNCORE_PRIORITY_MEDIUM = 2, + /** High priority */ + OH_NNCORE_PRIORITY_HIGH = 3 +} OH_NNCore_Priority; + +struct OH_NNCore_CompilationOptions { + bool isFp16; + OH_NNCore_PerformanceMode performanceMode; + OH_NNCore_Priority priority; +}; + +#ifdef __cplusplus +} +#endif +#endif // NEURAL_NETWORK_RUNTIME_CORE_TYPE_H diff --git a/interfaces/kits/c/v2_0/en/neural_network_runtime.h b/interfaces/kits/c/v2_0/en/neural_network_runtime.h new file mode 100644 index 0000000000000000000000000000000000000000..f25f27e9a37fcfa514c08b305695bff14eff1c5e --- /dev/null +++ b/interfaces/kits/c/v2_0/en/neural_network_runtime.h @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup NeuralNeworkRuntime + * @{ + * + * @brief Provides APIs of Neural Network Runtime for accelerating the model inference. + * + * @Syscap SystemCapability.Ai.NeuralNetworkRuntime + * @since 11 + * @version 2.0 + */ + +/** + * @file neural_network_runtime.h + * + * @brief Defines the Neural Network Runtime APIs. Use the Native APIs to build deep learning models. + * + * @library libneural_network_runtime.so + * @since 11 + * @version 2.0 + */ + +#ifndef NEURAL_NETWORK_RUNTIME_H +#define NEURAL_NETWORK_RUNTIME_H + +#include "neural_network_runtime_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Create a quantization parameter instance of the {@link OH_NNBackend_QuantParam} type. + * + * In quantization scenarios,call this interface to create a quantization parameter instance. Then, call + * {@link OH_NNBackend_SetQuantParamScales}, {@link OH_NNBackend_SetQuantParamZeroPoints} and + * {@link OH_NNBackend_SetQuantParamNumBits} to set quantization parameters. + * + * After a quantization parameter instance is used, you need to destroy it by calling + * {@link OH_NNBackend_DestroyQuantParam} to avoid memory leak. \n + * + * @return Returns the pointer to a {@link OH_NNBackend_Model} instance. + * @since 11 + * @version 2.0 + */ +OH_NNBackend_QuantParam* OH_NNBackend_CreateQuantParam(); + +/** + * @brief Release the instance of quantization parameter of {@link OH_NNBackend_QuantParam} type. + * + * The model instance created by calling {@link OH_NNBackend_CreateQuantParam} needs to be released by calling this method actively, otherwise it will cause memory leaks.\n + * + * If quantParam is a null pointer or *quantParam is a null pointer, this method only prints warning logs and does not execute release logic.\n + * + * @param quantParam A pointer to a pointer to an instance of {@link OH_NNBackend_QuantParam}. After the quantization parameter instance is destroyed, this method will actively set *quantParam to a null pointer. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_DestroyQuantParam(OH_NNBackend_QuantParam** quantParam); + +/** + * @brief Set the scale parameter in the quantization parameter + * + * Set the scale quantization parameter through the array parameter pointed to by scale, and quantNum is the length of the scale array. In the per-layer quantization scenario, quantNum is usually specified as 1, + * that is, all channels of a tensor share a set of quantization parameters; in the per-channel quantization scenario, quantNum is usually the same as the number of channels of the tensor, and each channel uses its own quantization parameters.\n + * + * @param quantParam A pointer to an instance of {@link OH_NNBackend_QuantParam}. + * @param scales A pointer to a double array. + * @param quantNum The length of the doubles array. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_SetQuantParamScales(OH_NNBackend_QuantParam* quantParam, + const double* scales, + size_t quantNum); + +/** + * @brief Set the zero point parameter in the quantization parameter + * + * Set the zero point quantization parameter through the array parameter pointed to by zeroPoints, and quantNum is the length of the zeroPoints array. In the per-layer quantization scenario, quantNum is usually specified as 1, + * that is, all channels of a tensor share a set of quantization parameters; in the per-channel quantization scenario, quantNum is usually the same as the number of channels of the tensor, and each channel uses its own quantization parameters.\n + * + * @param quantParam A pointer to an instance of {@link OH_NNBackend_QuantParam}. + * @param zeroPoints A pointer to an int32_t array. + * @param quantNum The length of the int32_t array. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_SetQuantParamZeroPoints(OH_NNBackend_QuantParam* quantParam, + const int32_t* zeroPoints, + size_t quantNum); + +/** + * @brief Set the number of quantization bits in the quantization parameter + * + * Set the number of quantization bits through the array parameter pointed to by numBits, and quantNum is the length of the numBits array. In the per-layer quantization scenario, quantNum is usually specified as 1, + * that is, all channels of a tensor share a set of quantization parameters; in the per-channel quantization scenario, quantNum is usually the same as the number of channels of the tensor, and each channel uses its own quantization parameters.\n + * + * Currently, Neural Network Runtime only supports 8-bit quantization. + * + * @param quantParam A pointer to an instance of {@link OH_NNBackend_QuantParam}. + * @param numBits A pointer to a uint32_t array. + * @param quantNum The length of the uint32_t array. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_SetQuantParamNumBits(OH_NNBackend_QuantParam* quantParam, + const uint32_t* numBits, + size_t quantNum); + +/** + * @brief Create an instance of type {@link OH_NNBackend_Model}, and use other interfaces provided by the OH_NNBackend module to complete the construction of the model instance. + * + * Before starting to construct the graph, call {@link OH_NNBackend_CreateModel} to create a model instance, according to the topology of the model, call + * {@link OH_NNBackend_AddTensorToModel}, {@link OH_NNBackend_AddOperationToModel}, + * {@link OH_NNBackend_SetModelTensorData}, {@link OH_NNBackend_SetModelTensorQuantParam}, and + * {@link OH_NNBackend_SetModelTensorType} and other methods to fill in the data nodes and operator nodes of the model; then call + * {@link OH_NNBackend_SpecifyModelInputsAndOutputs} to specify the input and output of the model; when the topology of the model is constructed, call + * {@link OH_NNBackend_BuildModel} to complete the construction of the model.\n + * + * After the model instance is used, call {@link OH_NNBackend_DestroyModel} to destroy the model instance to avoid memory leaks.\n + * + * @return Returns a pointer to an instance of {@link OH_NNBackend_Model}. + * @since 11 + * @version 2.0 + */ +OH_NNBackend_Model* OH_NNBackend_CreateModel(void); + +/** + * @brief Release the instance of the model. + * + * The model instance created by calling {@link OH_NNBackend_CreateModel} needs to be released by calling this method actively, otherwise it will cause memory leaks.\n + * + * If model is a null pointer or *model is a null pointer, this method only prints warning logs and does not execute release logic.\n + * + * @param model A pointer to a pointer to an instance of {@link OH_NNBackend_Model}. After the model instance is destroyed, this method will actively set *model to a null pointer. + * @since 11 + * @version 2.0 + */ +void OH_NNBackend_DestroyModel(OH_NNBackend_Model** model); + +/** + * @brief Add a tensor to the model instance + * + * The data nodes and operator parameters in the Neural Network Runtime model are all composed of the model's tensors. This method adds a tensor to the model instance. The order in which tensors are added is the index value of the tensor recorded in the model, {@link OH_NNBackend_SetModelTensorData}, + * {@link OH_NNBackend_SetModelTensorQuantParam}, {@link OH_NNBackend_SetModelTensorType}, {@link OH_NNBackend_AddOperationToModel}, and {@link OH_NNBackend_SpecifyModelInputsAndOutputs} + * methods will complete the corresponding functions according to this index value.\n + * + * Neural Network Runtime supports dynamic shape input and output. When adding data nodes with dynamic shapes, call {@link OH_NNCore_SetTensorDescShape} to set + * the dimensions of the tensor information that support dynamic changes to -1. For example: a 4-dimensional tensor, set the tensor shape to [1, -1, 2, 2], which means that its second dimension supports + * dynamic changes.\n + * + * @param model A pointer to an instance of {@link OH_NNBackend_Model}. + * @param tensorDesc A pointer to the {@link OH_NNCore_TensorDesc} tensor, which specifies the properties of the tensor added to the model instance. + * @return The result status of the function execution. Returns OH_NNCORE_SUCCESS if successful; returns a specific error code if failed, and the specific failure error code can be found in {@link OH_NNCore_ReturnCode}. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_AddTensorToModel(OH_NNBackend_Model* model, const OH_NNCore_TensorDesc* tensorDesc); + +/** + * @brief Set the value of the tensor + * + * For tensors with constant values (such as model weights), this method needs to be used to set the value during the graph construction phase. The index value of the tensor is determined by the order in which the tensor is added to the model, and the addition of the tensor refers to + * {@link OH_NNBackend_AddTensorToModel}.\n + * + * @param model A pointer to an instance of {@link OH_NNBackend_Model}. + * @param index The index value of the tensor. + * @param dataBuffer A pointer to the real data. + * @param length The length of the data buffer. + * @return The result status of the function execution. Returns OH_NNCORE_SUCCESS if successful; returns a specific error code if failed, and the specific failure error code can be found in {@link OH_NNCore_ReturnCode}. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_SetModelTensorData(OH_NNBackend_Model* model, + size_t index, + const void* dataBuffer, + size_t length); +/** + * @brief Set the quantization parameter of the tensor + * + * If you want to call the quantization inference capability of the acceleration chip, you need to set the quantization parameters using this method during the graph construction phase. The index value of the tensor is determined by the order in which the tensor is added to the model, and the addition of the tensor refers to + * {@link OH_NNBackend_AddTensorToModel}.\n + * + * @param model A pointer to an instance of {@link OH_NNBackend_Model}. + * @param index The index value of the tensor. + * @param param A pointer to the {@link OH_NNBackend_QuantParam} quantization parameter. + * @return The result status of the function execution. Returns OH_NNCORE_SUCCESS if successful; returns a specific error code if failed, and the specific failure error code can be found in {@link OH_NNCore_ReturnCode}. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_SetModelTensorQuantParam(OH_NNBackend_Model* model, + size_t index, + OH_NNBackend_QuantParam* param); + +/** + * @brief Set the type of the tensor + * + * The tensor added to the deep learning model needs to specify its type. For example: when the tensor is used as input or output in the model, the type is required to be {@link OH_NNCORE_TENSOR}; + * When the tensor is used as an operator parameter, it needs to be specified as a specific enumeration value, please refer to {@link OH_NNBackend_OperationType} for details. + * The index value of the tensor is determined by the order in which the tensor is added to the model, and the addition of the tensor refers to {@link OH_NNBackend_AddTensorToModel}.\n + * + * @param model A pointer to an instance of {@link OH_NNBackend_Model}. + * @param index The index value of the tensor. + * @param type The type of the tensor. + * @return The result status of the function execution. Returns OH_NNCORE_SUCCESS if successful; returns a specific error code if failed, and the specific failure error code can be found in {@link OH_NNCore_ReturnCode}. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_SetModelTensorType(OH_NNBackend_Model* model, + size_t index, + OH_NNBackend_TensorType type); + +/** + * @brief Add an operator to the model instance + * + * This method adds an operator to the model instance. The operator type is specified by `operationType`, and the parameters, inputs, and outputs of the operator are specified by `paramIndices`, `inputIndices`, and `outputIndices`. This method will verify the properties of the operator parameters and the number of inputs and outputs. These properties need to be set correctly when calling {@link OH_NNBackend_AddTensorToModel} to add tensors. Please refer to the detailed description of each operator in {@link OH_NNBackend_OperationType} for the expected parameters, inputs, and outputs of each operator.\n + * + * `paramIndices`, `inputIndices`, and `outputIndices` store the index values of the tensors, and each index value is determined by the order in which the tensor is added to the model. To correctly set and add operators, each index value of each tensor must be accurately set. Please refer to {@link OH_NNModel_AddTensor} for adding tensors.\n + * + * If additional parameters (parameters that are not required by the operator) are added when adding the operator, this method returns {@link OH_NNCORE_INVALID_PARAMETER}; if the operator parameters are not set, the operator sets the default parameters by default. Please refer to the detailed description of the relevant operator in {@link OH_NNBackend_OperationType} for the default values.\n + * + * @param model A pointer to an instance of {@link OH_NNBackend_Model}. + * @param operationType The operator type to be added, the value can be found in the enumeration values of {@link OH_NNBackend_OperationType}. + * @param paramIndices A pointer to the instance of OH_NNBackend_Array, which sets the parameters of the operator. The array elements pointed to by the pointer are required to be of type {@link OH_NNCORE_UINT32}, otherwise {@link OH_NNCORE_INVALID_PARAMETER} will be returned. + * @param inputIndices A pointer to the instance of OH_NNBackend_Array, which specifies the input of the operator. The array elements pointed to by the pointer are required to be of type {@link OH_NNCORE_UINT32}, otherwise {@link OH_NNCORE_INVALID_PARAMETER} will be returned. + * @param outputIndices A pointer to the instance of OH_NNBackend_Array, which sets the output of the operator. The array elements pointed to by the pointer are required to be of type {@link OH_NNCORE_UINT32}, otherwise {@link OH_NNCORE_INVALID_PARAMETER} will be returned. + * @return The result status of the function execution. Returns OH_NNCORE_SUCCESS if successful; returns a specific error code if failed, and the specific failure error code can be found in {@link OH_NNCore_ReturnCode}. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_AddOperationToModel(OH_NNBackend_Model* model, + OH_NNBackend_OperationType operationType, + const OH_NNBackend_Array* paramIndices, + const OH_NNBackend_Array* inputIndices, + const OH_NNBackend_Array* outputIndices); + +/** + * @brief Specify the input and output of the model + * + * The model instance needs to specify tensors as end-to-end inputs and outputs. The tensors set as inputs and outputs cannot use {@link OH_NNBackend_SetModelTensorData} to set numerical values, and need to call {@link OH_NNCore_GetDataBuffer} to set input and output data during the execution phase.\n + * + * The index value of the tensor is determined by the order in which the tensor is added to the model, and the addition of the tensor refers to {@link OH_NNBackend_AddTensorToModel}.\n + * + * Asynchronous setting of model input and output is not supported for now.\n + * + * @param model A pointer to an instance of {@link OH_NNBackend_Model}. + * @param inputIndices A pointer to the instance of OH_NNBackend_Array, which specifies the input of the operator. + * @param outputIndices A pointer to the instance of OH_NNBackend_Array, which sets the output of the operator. + * @return The result status of the function execution. Returns OH_NNCORE_SUCCESS if successful; returns a specific error code if failed, and the specific failure error code can be found in {@link OH_NNCore_ReturnCode}. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_SpecifyModelInputsAndOutputs(OH_NNBackend_Model* model, + const OH_NNBackend_Array* inputIndices, + const OH_NNBackend_Array* outputIndices); + +/** + * @brief Complete the construction of the model + * + * After the topology of the model is constructed, call this method to indicate that the construction is completed. After calling this method, no additional construction operations can be performed. Calling {@link OH_NNBackend_AddTensorToModel}, {@link OH_NNBackend_AddOperationToModel}, {@link OH_NNBackend_SetModelTensorData}, {@link OH_NNBackend_SetModelTensorQuantParam}, {@link OH_NNBackend_SetModelTensorType}, and {@link OH_NNBackend_SpecifyModelInputsAndOutputs} will return {@link OH_NNCORE_OPERATION_FORBIDDEN}.\n + * + * Before calling {@link OH_NNBackend_GetModelAvailableOperations} and {@link OH_NNCore_ConstructCompilationWithNNModel}, you must call this method to complete the construction.\n + * + * @param model A pointer to an instance of {@link OH_NNBackend_Model}. + * @return The result status of the function execution. Returns OH_NNCORE_SUCCESS if successful; returns a specific error code if failed, and the specific failure error code can be found in {@link OH_NNCore_ReturnCode}. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_BuildModel(OH_NNBackend_Model* model); + +/** + * @brief Query the support status of all operators in the model by a boolean sequence. + * + * Query the support status of each operator in the model instance by the underlying hardware, which is specified by `backendName`. The results will be represented by the array pointed to by `isSupported`. If the i-th operator is supported, then (*isSupported)[i] == true, otherwise false.\n + * + * After this method is executed successfully, `(*isSupported)` will point to a bool array that records the support status of the operator. The length of the array is equal to the number of operators in the model instance. The memory corresponding to the array is managed by Neural Network Runtime and will be automatically destroyed when the model instance is destroyed or this method is called again.\n + * + * @param model A pointer to an instance of {@link OH_NNModel}. + * @param backendName Specifies the name of the hardware to be queried. The device name can be obtained by calling {@link OH_NNCore_GetBackendNum} and {@link OH_NNCore_GetBackendName}. + * @param isSupported A pointer to a bool array. When calling this method, it is required that `(*isSupported)` is a null pointer, otherwise {@link OH_NNCORE_INVALID_PARAMETER} will be returned. + * @param opNum The number of operators in the model instance, corresponding to the length of the `(*isSupported)` array. + * @return The result status of the function execution. Returns OH_NNCORE_SUCCESS if successful; returns a specific error code if failed, and the specific failure error code can be found in {@link OH_NNCore_ReturnCode}. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_GetModelAvailableOperations(OH_NNBackend_Model* model, + const char* backendName, + const bool** isSupported, + uint32_t* opNum); + +/** + * @brief Set the cache version of the compiled model. + * + * On hardware that supports caching, the model can be saved as a cache file after being compiled at the hardware driver level, and the model can be read directly from the cache file during the next compilation to reduce the compilation time. This method accepts the version as a parameter, and according to the differences in the cache path and version, this method takes different actions:\n + * + * - There is no cache file in the directory specified by the cache path: + * Cache the compiled model to the directory and set the cache version to `version`.\n + * + * - There is a complete cache file in the directory specified by the cache path, and the version number == `version`: + * Read the cache file under the path and pass it to the underlying hardware to convert it into an executable model instance.\n + * + * - There is a complete cache file in the directory specified by the cache path, but the version number < `version`: + * The cache file under the path needs to be updated. After the model is compiled by the underlying hardware, overwrite the cache file under the path and update the version number to `version`.\n + * + * - There is a cache file in the directory specified by the cache path, but the version number > `version`: + * The version of the cache file under the path is higher than `version`, so the cache file is not read, and {@link OH_NNCORE_INVALID_PARAMETER} error code is returned at the same time.\n + * + * - The cache file under the directory specified by the cache path is incomplete or does not have access permission to the cache file: + * Return {@link OH_NNCORE_INVALID_PARAMETER} error code.\n + * + * - OH_NNCORE_INVALID_PATH + * Return {@link OH_NNCORE_INVALID_FILE} error code.\n + * + * @param compilation A pointer to an instance of {@link OH_NNCore_Options}. + * @param version The cache version. + * @return The result status of the function execution. Returns OH_NNCORE_SUCCESS if successful; returns a specific error code if failed, and the specific failure error code can be found in {@link OH_NNCore_ReturnCode}. + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_SetCacheVersion(OH_NNCore_Options* options, uint32_t version); + +#ifdef __cplusplus +} +#endif // __cplusplus +#endif // NEURAL_NETWORK_RUNTIME_H diff --git a/interfaces/kits/c/v2_0/en/neural_network_runtime_type.h b/interfaces/kits/c/v2_0/en/neural_network_runtime_type.h new file mode 100644 index 0000000000000000000000000000000000000000..c131e4dc93887bbbc19f5ff522f2938df21da15c --- /dev/null +++ b/interfaces/kits/c/v2_0/en/neural_network_runtime_type.h @@ -0,0 +1,1656 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup NeuralNeworkRuntime + * @{ + * + * @brief Provides APIs for accelerating the Neural Network Runtime model inference. + * + * @Syscap SystemCapability.Ai.NeuralNetworkRuntime + * @since 9 + * @version 1.0 + */ + +/** + * @file neural_network_runtime_type.h + * + * @brief Defines the structure and enumeration for Neural Network Runtime. + * + * @library libneural_network_runtime.so + * @since 9 + * @version 1.0 + */ + +#ifndef NEURAL_NETWORK_RUNTIME_TYPE_H +#define NEURAL_NETWORK_RUNTIME_TYPE_H + +#include "v1_0/neural_network_runtime_type_compat.h" +#include "v2_0/neural_network_core_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Defines the handles of models for Neural Network Runtime. + * + * @since 9 + * @version 1.0 + */ +typedef struct OH_NNBackend_Model OH_NNBackend_Model; +//TODO: OH_NNBackend_Model add tensor 备选 +typedef struct OH_NNBackend_Operand OH_NNBackend_Operand; +typedef struct OH_NNBackend_QuantParam OH_NNBackend_QuantParam; + +/** + * @brief Defines error codes for Neural Network Runtime. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** The operation is successful. */ + OH_NNBACKEND_SUCCESS = 0, + /** The operation failed. */ + OH_NNBACKEND_FAILED = 1, + /** Invalid parameter. */ + OH_NNBACKEND_INVALID_PARAMETER = 2, + /** Memory-related error, for example, insufficient memory, memory data copy failure, or memory application failure. */ + OH_NNBACKEND_MEMORY_ERROR = 3, + /** Invalid operation. */ + OH_NNBACKEND_OPERATION_FORBIDDEN = 4, + /** Null pointer exception */ + OH_NNBACKEND_NULL_PTR = 5, + /** Invalid file. */ + OH_NNBACKEND_INVALID_FILE = 6, + /** A hardware error occurs, for example, HDL service crash. */ + OH_NNBACKEND_UNAVALIDABLE_DEVICE = 7, + /** Invalid path. */ + OH_NNBACKEND_INVALID_PATH = 8 +} OH_NNBackend_ReturnCode; + +/** + * @brief Defines activation function types in the fusion operator for Neural Network Runtime. + * + * @since 9 + * @version 1.0 + */ +typedef enum : int8_t { + /** The fusion activation function is not specified. */ + OH_NNBACKEND_FUSED_NONE = 0, + /** Fusion relu activation function */ + OH_NNBACKEND_FUSED_RELU = 1, + /** Fusion relu6 activation function */ + OH_NNBACKEND_FUSED_RELU6 = 2 +} OH_NNBackend_FuseType; + +/** + * @brief Defines the layout type of tensor data. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** The tensor does not have a specific layout type (such as scalar or vector). */ + OH_NNBACKEND_FORMAT_NONE = 0, + /** The tensor arranges data in NCHW format.*/ + OH_NNBACKEND_FORMAT_NCHW = 1, + /** The tensor arranges data in NHWC format.*/ + OH_NNBACKEND_FORMAT_NHWC = 2 +} OH_NNBackend_Format; + +/** + * @brief Defines device types supported by Neural Network Runtime. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** Devices that are not CPU, GPU, or dedicated accelerator*/ + OH_NNBACKEND_OTHERS = 0, + /** CPU device */ + OH_NNBACKEND_CPU = 1, + /** GPU device */ + OH_NNBACKEND_GPU = 2, + /** Dedicated hardware accelerator */ + OH_NNBACKEND_ACCELERATOR = 3, +} OH_NNBackend_DeviceType; + +/** + * @brief Defines tensor data types supported by Neural Network Runtime. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** Unknown type */ + OH_NNBACKEND_UNKNOWN = 0, + /** bool */ + OH_NNBACKEND_BOOL = 1, + /** int8 */ + OH_NNBACKEND_INT8 = 2, + /** int16 */ + OH_NNBACKEND_INT16 = 3, + /** int32 */ + OH_NNBACKEND_INT32 = 4, + /** int64 */ + OH_NNBACKEND_INT64 = 5, + /** uint8 */ + OH_NNBACKEND_UINT8 = 6, + /** uint16 */ + OH_NNBACKEND_UINT16 = 7, + /** uint32 */ + OH_NNBACKEND_UINT32 = 8, + /** uint64 */ + OH_NNBACKEND_UINT64 = 9, + /** float16 */ + OH_NNBACKEND_FLOAT16 = 10, + /** float32 */ + OH_NNBACKEND_FLOAT32 = 11, + /** float64 */ + OH_NNBACKEND_FLOAT64 = 12 +} OH_NNBackend_DataType; + + +/** + * @brief Defines operator types supported by Neural Network Runtime. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** + * Returns the tensor of the sum of the elements corresponding to two input tensors. + * + * Inputs: + * + * * input1: first input tensor, of the Boolean or number type. + * * input2: second input tensor, whose data type must be the same as that of the first tensor. + * + * Parameters: + * + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: sum of input1 and input2. + * The data shape is the same as that of the input after broadcasting, + * and the data type is the same as that of the input with a higher precision. + */ + OH_NNBACKEND_OPS_ADD = 1, + + /** + * Apply 2D average pooling to the input tensor, which now must be in NHWC format. The int8 quantization input is supported. + * + * If the input contains the padMode parameter: + * + * Inputs: + * + * * input: tensor. + * + * Parameters: + * + * * kernelSize indicates the kernel size used to obtain the average value. It is an int array [kernel_height, kernel_width]. + * The first number indicates the kernel height, and the second number indicates the kernel width. + * * strides indicates the distance of kernel moving. The value is an int array [stride_height, stride_width]. + * The first number indicates the moving step in height, and the second number indicates the moving step in width. + * * padMode: padding mode, which is optional. The value is of the int type and can be 0 (same) or 1 (valid). + * The nearest neighbor value is used for padding. + * 0 (same): The height and width of the output are the same as those of the input. + * The total padding quantity is calculated horizontally and vertically and evenly distributed to the top, bottom, left, and right if possible. + * Otherwise, the last additional padding will be completed from the bottom and right. + * 1 (valid): The possible maximum height and width of the output will be returned in case of no padding. Excessive pixels will be discarded. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * If the input contains the padList parameter: + * + * Inputs: + * + * * input: tensor. + * + * Parameters: + * + * * kernelSize indicates the kernel size used to obtain the average value. It is an int array [kernel_height, kernel_width]. + * The first number indicates the kernel height, and the second number indicates the kernel width. + * * strides indicates the distance of kernel moving. The value is an int array [stride_height, stride_width]. + * The first number indicates the moving step in height, and the second number indicates the moving step in width. + * * padList: padding around input. It is an int array [top, bottom, left, right], and the nearest neighbor values are used for padding. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: average pooling result of the input. + */ + OH_NNBACKEND_OPS_AVG_POOL = 2, + + /** + * Batch normalization is performed on a tensor to scale and shift tensor elements, relieving potential covariate shift in a batch of data. + * + * Inputs: + * + * * input: n-dimensional tensor of shape [N, ..., C]. The nth dimension is the number of channels. + * * scale: 1D tensor of the scaling factor used to scale the first normalized tensor. + * * offset: 1D tensor used to move to the first normalized tensor. + * * mean: 1D tensor of the overall mean value. It is used only for inference. In case of training, this parameter must be left empty. + * * variance: 1D tensor used for the overall variance. It is used only for inference. In case of training, this parameter must be left empty. + * + * Parameters: + * + * * epsilon: fixed small additional value. + * + * Outputs: + * + * * output: n-dimensional output tensor whose shape and data type are the same as those of the input. + */ + OH_NNBACKEND_OPS_BATCH_NORM = 3, + + /** + * Divides the batch dimension of a 4D tensor into small blocks by block_shape, and interleaves these blocks back into the spatial dimension. + * + * Parameters: + * + * * input: input tensor. The dimension will be divided into small blocks, and these blocks will be interleaved into the spatial dimension. + * + * Outputs: + * + * * blockSize: size of each block to be interleaved into the spatial dimension. The value is an array [height_block, width_block]. + * * crops: elements truncated from the spatial dimension of the output. The value is a 2D array [[crop0_start, crop0_end], + * [crop1_start, crop1_end]] with the shape of (2, 2). + * + * + * Outputs: + * + * * output. Assume that the shape of input is (n,h,w,c) and the shape of output is (n',h',w',c'): + * n' = n / (block_shape[0] * block_shape[1]) + * h' = h * block_shape[0] - crops[0][0] - crops[0][1] + * w' = w * block_shape[1] - crops[1][0] - crops[1][1] + * c'= c + */ + OH_NNBACKEND_OPS_BATCH_TO_SPACE_ND = 4, + + /** + * Offsets the data in each dimension of the input tensor. + * + * Inputs: + * + * * input: input tensor, which can have two to five dimensions. + * * bias: offset of the number of input dimensions. + * + * Outputs: + * + * * output: sum of the input tensor and the bias in each dimension. + */ + OH_NNBACKEND_OPS_BIAS_ADD = 5, + + /** + * Converts the data type in the input tensor. + * + * Inputs: + * + * * input: input tensor. + * * type: converted data type. + * + * Outputs: + * + * * output: converted tensor. + */ + OH_NNBACKEND_OPS_CAST = 6, + + /** + * Connects tensors in a specified dimension. + * + * Inputs: + * + * * input: N input tensors. + * + * Parameters: + * + * * axis: dimension for connecting tensors. + * + * Outputs: + * + * * output: result of connecting N tensors along the axis. + */ + OH_NNBACKEND_OPS_CONCAT = 7, + + /** + * 2D convolutional layer. + * + * If the input contains the padMode parameter: + * + * Inputs: + * + * * input: input tensor. + * * weight: convolution weight in [outChannel, kernelHeight, kernelWidth, inChannel/group] format. + * The value of inChannel must be exactly divided by the value of group. + * + * * bias: bias of the convolution. It is an array with a length of [outChannel]. + * In quantization scenarios, the bias parameter does not require quantization parameters. + * The quantization version requires data input of the OH_NNBACKEND_INT32 type. + * The actual quantization parameters are determined by input and weight. + * + * Parameters: + * + * * stride: movement stride of the convolution kernel in height and width. It is an int array [strideHeight, strideWidth]. + * * dilation: dilation size of the convolution kernel in height and width. It is an int array [dilationHeight, dilationWidth]. + * The value must be greater than or equal to 1 and cannot exceed the height and width of input. + * + * * padMode: padding mode of input. The value is of the int type and can be 0 (same) or 1 (valid). + * 0 (same): The height and width of the output are the same as those of the input. + * The total padding quantity is calculated horizontally and vertically and evenly distributed to the top, bottom, left, and right if possible. + * Otherwise, the last additional padding will be completed from the bottom and right. + * + * 1 (valid): The possible maximum height and width of the output will be returned in case of no padding. The excessive pixels will be discarded. + * * group: number of groups in which the input is divided by in_channel. The value is of the int type. + * If group is 1, it is a conventional convolution. If group is greater than 1 and + * less than or equal to in_channel, it is a group convolution. + * * activationType is an integer constant which is contained in FuseType. The specified activation function is called before output. + * + * If the input contains the padList parameter: + * + * Inputs: + * + * * input: input tensor. + * * weight: convolution weight in [outChannel, kernelHeight, kernelWidth, inChannel/group] format. + * The value of inChannel must be exactly divided by the value of group. + * + * * bias: bias of the convolution. It is an array with a length of [outChannel]. + * In quantization scenarios, the bias parameter does not require quantization parameters. + * The quantization version requires data input of the OH_NNBACKEND_INT32 type. + * The actual quantization parameters are determined by input and weight. + * + * Parameters: + * + * * stride: movement stride of the convolution kernel in height and width. It is an int array [strideHeight, strideWidth]. + * * dilation: dilation size of the convolution kernel in height and width. It is an int array [dilationHeight, dilationWidth]. + * The value must be greater than or equal to 1 and cannot exceed the height and width of input. + * * padList: padding around input. It is an int array [top, bottom, left, right]. + * * group: number of groups in which the input is divided by in_channel. The value is of the int type. + * If group is 1, it is a conventional convolution. + * If group is in_channel, it is depthwiseConv2d. In this case, group==in_channel==out_channel. + * If group is greater than 1 and less than in_channel, it is a group convolution. In this case, out_channel==group. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: convolution computing result. + */ + OH_NNBACKEND_OPS_CONV2D = 8, + + /** + * 2D convolution transposition. + * + * If the input contains the padMode parameter: + * + * Inputs: + * + * * input: input tensor. + * * weight: convolution weight in [outChannel, kernelHeight, kernelWidth, inChannel/group] format. + * The value of inChannel must be exactly divided by the value of group. + * + * * bias: bias of the convolution. It is an array with a length of [outChannel]. + * In quantization scenarios, the bias parameter does not require quantization parameters. + * The quantization version requires data input of the OH_NNBACKEND_INT32 type. + * The actual quantization parameters are determined by input and weight. + * + * * stride: movement stride of the convolution kernel in height and width. It is an int array [strideHeight, strideWidth]. + * + * Parameters: + * + * * dilation: dilation size of the convolution kernel in height and width. It is an int array [dilationHeight, dilationWidth]. + * The value must be greater than or equal to 1 and cannot exceed the height and width of input. + * * padMode: padding mode of input. The value is of the int type and can be 0 (same) or 1 (valid). + * 0 (same): The height and width of the output are the same as those of the input. + * The total padding quantity is calculated horizontally and vertically and evenly distributed to the top, bottom, left, and right if possible. + * Otherwise, the last additional padding will be completed from the bottom and right. + * 1 (valid): The possible maximum height and width of the output will be returned in case of no padding. The excessive pixels will be discarded. + * * group: number of groups in which the input is divided by in_channel. The value is of the int type. + * If group is 1, it is a conventional convolution. If group is greater than 1 and + * less than or equal to in_channel, it is a group convolution. + * * outputPads: padding along the height and width of the output tensor. The value is an int or a tuple. + * It can be a single integer to specify the same value for all spatial dimensions. The amount of output + * padding along a dimension must be less than the stride along this dimension. + * + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * If the input contains the padList parameter: + * + * Inputs: + * + * * input: input tensor. + * * weight: convolution weight in [outChannel, kernelHeight, kernelWidth, inChannel/group] format. + * The value of inChannel must be exactly divided by the value of group. + * * bias: bias of the convolution. It is an array with a length of [outChannel]. + * In quantization scenarios, the bias parameter does not require quantization parameters. + * The quantization version requires data input of the OH_NNBACKEND_INT32 type. + * The actual quantization parameters are determined by input and weight. + * + * Parameters: + * + * * stride: movement stride of the convolution kernel in height and width. It is an int array [strideHeight, strideWidth]. + * * dilation: dilation size of the convolution kernel in height and width. It is an int array [dilationHeight, dilationWidth]. + * The value must be greater than or equal to 1 and cannot exceed the height and width of input. + * * padList: padding around input. It is an int array [top, bottom, left, right]. + * * group: number of groups in which the input is divided by in_channel. The value is of the int type. + * If group is 1, it is a conventional convolution. If group is greater than 1 + * and less than or equal to in_channel, it is a group convolution. + * * outputPads: padding along the height and width of the output tensor. The value is an int or a tuple. + * It can be a single integer to specify the same value for all spatial dimensions. The amount of output padding + * along a dimension must be less than the stride along this dimension. + * + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: computing result after convolution and transposition. + */ + OH_NNBACKEND_OPS_CONV2D_TRANSPOSE = 9, + + /** + * 2D depthwise separable convolution. + * + * If the input contains the padMode parameter: + * + * Inputs: + * + * * input: input tensor. + * * weight: convolution weight in [outChannel, kernelHeight, kernelWidth, 1] format. + * outChannel is equal to channelMultiplier multiplied by inChannel. + * * bias: bias of the convolution. It is an array with a length of [outChannel]. + * In quantization scenarios, the bias parameter does not require quantization parameters. + * The quantization version requires data input of the OH_NNBACKEND_INT32 type. + * The actual quantization parameters are determined by input and weight. + * + * Parameters: + * + * * stride: movement stride of the convolution kernel in height and width. It is an int array [strideHeight, strideWidth]. + * * dilation: dilation size of the convolution kernel in height and width. It is an int array [dilationHeight, dilationWidth]. + * The value must be greater than or equal to 1 and cannot exceed the height and width of input. + * * padMode: padding mode of input. The value is of the int type and can be 0 (same) or 1 (valid). + * 0 (same): The height and width of the output are the same as those of the input. + * The total padding quantity is calculated horizontally and vertically and evenly distributed to the top, bottom, left, and right if possible. + * Otherwise, the last additional padding will be completed from the bottom and right. + * + * 1 (valid): The possible maximum height and width of the output will be returned in case of no padding. The excessive pixels will be discarded. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * If the input contains the padList parameter: + * + * Inputs: + * + * * input: input tensor. + * * weight: convolution weight in [outChannel, kernelHeight, kernelWidth, 1] format. + * outChannel is equal to channelMultiplier multiplied by inChannel. + * * bias: bias of the convolution. It is an array with a length of [outChannel]. + * In quantization scenarios, the bias parameter does not require quantization parameters. + * The quantization version requires data input of the OH_NNBACKEND_INT32 type. + * The actual quantization parameters are determined by input and weight. + * + * Parameters: + * + * * stride: movement stride of the convolution kernel in height and width. It is an int array [strideHeight, strideWidth]. + * * dilation: dilation size of the convolution kernel in height and width. It is an int array [dilationHeight, dilationWidth]. + * The value must be greater than or equal to 1 and cannot exceed the height and width of input. + * * padList: padding around input. It is an int array [top, bottom, left, right]. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: convolution computing result. + */ + OH_NNBACKEND_OPS_DEPTHWISE_CONV2D_NATIVE = 10, + + /** + * Divides two input scalars or tensors. + * + * Inputs: + * + * * input1: first input, which is a number, a bool, or a tensor whose data type is number or Boolean. + * * input2: second input, which must meet the following requirements: + * If the first input is a tensor, the second input can be a real number, a Boolean value, or a tensor whose data type is real number or Boolean value. + * If the first input is a real number or Boolean value, the second input must be a tensor whose data type is real number or Boolean value. + * + * Parameters: + * + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: result of dividing input1 by input2. + */ + OH_NNBACKEND_OPS_DIV = 11, + + /** + * Sets parameters to perform product (dot product), sum (addition and subtraction), or max (larger value) on the input. + * + * Inputs: + * + * * input1: first input tensor. + * * input2: second input tensor. + * + * Parameters: + * + * * mode: operation mode. The value is an enumerated value. + * + * Outputs: + * + * * output: computing result, which has the same data type and shape of output and input1. + */ + OH_NNBACKEND_OPS_ELTWISE = 12, + + /** + * Adds an additional dimension to a tensor in the given dimension. + * + * Inputs: + * + * * input: input tensor. + * * axis: index of the dimension to be added. The value is of the int32_t type and must be a constant in the range [-dim-1, dim]. + * + * Outputs: + * + * * output: tensor after dimension expansion. + */ + OH_NNBACKEND_OPS_EXPAND_DIMS = 13, + + /** + * Creates a tensor of the specified dimensions and fills it with a scalar. + * + * Inputs: + * + * * value: scalar used to fill the tensor. + * * shape: dimensions of the tensor to be created. + * + * Outputs: + * + * * output: generated tensor, which has the same data type as value. The tensor shape is specified by the shape parameter. + */ + OH_NNBACKEND_OPS_FILL = 14, + + /** + * Full connection. The entire input is used as the feature map for feature extraction. + * + * Inputs: + * + * * input: full-connection input tensor. + * * weight: weight tensor for a full connection. + * * bias: full-connection bias. In quantization scenarios, no quantized parameter is required for this parameter. + * If quantization is required, the data must be of the OH_NNBACKEND_INT32 type. + * The actual quantization parameters are determined by input and weight. + * + * Parameters: + * + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: computed tensor. + * + * If the input contains the axis parameter: + * + * Inputs: + * + * * input: full-connection input tensor. + * * weight: weight tensor for a full connection. + * * bias: full-connection bias. In quantization scenarios, no quantized parameter is required for this parameter. + * If quantization is required, the data must be of the OH_NNBACKEND_INT32 type. The actual quantization parameters + * are determined by input and weight. + * + * Parameters: + * + * * axis: axis in which the full connection is applied. The specified axis and its following axes are + * converted into a 1D tensor for applying the full connection. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: computed tensor. + */ + OH_NNBACKEND_OPS_FULL_CONNECTION = 15, + + /** + * Returns the slice of the input tensor based on the specified index and axis. + * + * Inputs: + * + * * input: tensor to be sliced. + * * inputIndices: indices of the specified input on the axis. The value is an array of the int type + * and must be in the range [0,input.shape[axis]). + * * axis: axis on which input is sliced. The value is an array with one element of the int32_t type. + * + * Outputs: + * + * * output: sliced tensor. + */ + OH_NNBACKEND_OPS_GATHER = 16, + + /** + * Calculate the Hswish activation value of the input. + * + * Inputs: + * + * * An n-dimensional input tensor. + * + * Outputs: + * + * * output: n-dimensional Hswish activation value. The data type is the same as that of shape and input. + */ + OH_NNBACKEND_OPS_HSWISH = 17, + + /** + * For input1 and input2, calculate the result of input1[i]<=input2[i] for each pair of elements, + * where i is the index of each element in the input tensor. + * + * Inputs: + * + * * input1, which can be a real number, Boolean value, or tensor whose data type is real number or NN_BOOL. + * * input2, which can be a real number or a Boolean value if input1 is a tensor and must be a tensor + * with the data type of real number or NN_BOOL if input1 is not a tensor. + * + * Outputs: + * + * * A tensor of the data type NN_BOOL. When a quantization model is used, the quantization parameters of the output + * cannot be omitted. However, values of the quantization parameters do not affect the result. + */ + OH_NNBACKEND_OPS_LESS_EQUAL = 18, + + /** + * Calculate the inner product of input1 and input2. + * + * Inputs: + * + * * input1: n-dimensional input tensor. + * * input2: n-dimensional input tensor. + * + * Parameters: + * + * * TransposeX: Boolean value indicating whether to transpose input1. + * * TransposeY: Boolean value indicating whether to transpose input2. + * + * Outputs: + * + * * output: inner product obtained after calculation. In case of type!=NN_UNKNOWN, the output data type is + * determined by type. In case of type==NN_UNKNOWN, the output data type depends on the data type + * converted during computing of inputX and inputY. + * + */ + OH_NNBACKEND_OPS_MATMUL = 19, + + /** + * Calculates the maximum of input1 and input2 element-wise. The inputs of input1 and input2 + * comply with the implicit type conversion rules to make the data types consistent. * The inputs must be two tensors or one tensor and one scalar. + * When the inputs are two tensors, their data types cannot be both NN_BOOL. Their shapes can be broadcast to the same size. + * When the inputs are one tensor and one scalar, the scalar must be a constant. + * + * Inputs: + * + * * input1: n-dimensional input tensor of the real number or NN_BOOL type. + * * input2: n-dimensional input tensor of the real number or NN_BOOL type. + * + * Outputs: + * + * * output: n-dimensional output tensor. The shape and data type of + * output are the same as those of the two inputs with a higher precision. + */ + OH_NNBACKEND_OPS_MAXIMUM = 20, + + /** + * Applies 2D maximum pooling to the input tensor. + * + * If the input contains the padMode parameter: + * + * Inputs: + * + * * input: tensor. + * + * Parameters: + * + * * kernelSize: kernel size used to obtain the maximum. It is an int array [kernel_height, kernel_width]. + * The first number indicates the kernel height, and the second number indicates the kernel width. + * * strides indicates the distance of kernel moving. The value is an int array [stride_height, stride_width]. + * The first number indicates the moving step in height, and the second number indicates the moving step in width. + * * padMode: padding mode, which is optional. The value is of the int type and can be 0 (same) + * or 1 (valid). The nearest neighbor value is used for padding. + * 0 (same): The height and width of the output are the same as those of the input. + * The total padding quantity is calculated horizontally and vertically and evenly distributed to the top, bottom, left, and right if possible. + * Otherwise, the last additional padding will be completed from the bottom and right. + * 1 (valid): The possible maximum height and width of the output will be returned in case of no padding. The excessive pixels will be discarded. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * If the input contains the padList parameter: + * + * Inputs: + * + * * input: tensor. + * + * Parameters: + * + * * kernelSize: kernel size used to obtain the maximum. It is an int array [kernel_height, kernel_width]. + * The first number indicates the kernel height, and the second number indicates the kernel width. + * * strides indicates the distance of kernel moving. The value is an int array [stride_height, stride_width]. + * The first number indicates the moving step in height, and the second number indicates the moving step in width. + * * padList: padding around input. It is an int array [top, bottom, left, right], + * and the nearest neighbor values are used for padding. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: tensor obtained after maximum pooling is applied to the input. + */ + OH_NNBACKEND_OPS_MAX_POOL = 21, + + /** + * Multiplies elements in the same positions of inputX and inputY to obtain the output. + * If inputX and inputY have different shapes, expand them to the same shape + * through broadcast and then perform multiplication. + * + * Inputs: + * + * * input1: n-dimensional tensor. + * * input2: n-dimensional tensor. + * + * Parameters: + * + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * Product of each element of input1 and input2. + */ + OH_NNBACKEND_OPS_MUL = 22, + + /** + * Generates a one-hot tensor based on the positions specified by indices. The positions specified by indices + * are determined by on_value, and other positions are determined by off_value. + * + * Inputs: + * + * * indices: n-dimensional tensor. Each element in indices determines the position of + * on_value in each one-hot vector. + * * depth: integer scalar that determines the depth of the one-hot vector. The value of depth + * must be greater than 0. + * * on_value: scalar that specifies a valid value in the one-hot vector. + * * off_value: scalar that specifies the values of other posistions in the one-hot vector except the valid value. + * + * Parameters: + * + * * axis: integer scalar that specifies the dimension for inserting the one-hot. Assume that the shape + * of indices is [N, C], and the value of depth is D. + * When axis is 0, the shape of the output is [D, N, C]. + * When axis is -1, the shape of the output is [N, C, D]. + * When axis is 1, the shape of the output is [N, D, C]. + * + * Outputs: + * + * * output: (n+1)-dimensional tensor if indices is an n-dimensional tensor. + * The output shape is determined by indices and axis. + */ + OH_NNBACKEND_OPS_ONE_HOT = 23, + + /** + * Pads inputX in the specified dimensions. + * + * Inputs: + * + * * inputX: n-dimensional tensor in [BatchSize, ...] format. + * * paddings: 2D tensor that specifies the length to pad in each dimension. The shape is [n, 2]. + * For example, paddings[i][0] indicates the number of paddings to be added preceding inputX in the ith dimension. + * paddings[i][1] indicates the number of paddings to be added following inputX in the ith dimension. + * + * Parameters: + * + * * padValues: value to be added to the pad operation. The value is a constant with the same data type as inputX. + * + * Outputs: + * + * * output: n-dimensional tensor after padding, with the same dimensions and data type as inputX. + * The shape is determined by inputX and paddings. + * output.shape[i] = input.shape[i] + paddings[i][0]+paddings[i][1] + */ + OH_NNBACKEND_OPS_PAD = 24, + + /** + * Calculates the y power of each element in input. The inputs must be two tensors or one tensor and one scalar. + * When the inputs are two tensors, their data types cannot be both NN_BOOL, and their shapes must be the same. + * When the inputs are one tensor and one scalar, the scalar must be a constant. + * + * Inputs: + * + * * input: real number, Boolean value, or tensor whose data type is real number or NN_BOOL. + * * y: real number, Boolean value, or tensor whose data type is real number or NN_BOOL. + * + * Outputs: + * + * * output: tensor, whose shape is determined by the shape of input and y after broadcasting. + */ + OH_NNBACKEND_OPS_POW = 25, + + /** + * Scales a tensor. + * + * Inputs: + * + * * input: n-dimensional tensor. + * * scale: scaling tensor. + * * bias: bias tensor. + * + * Parameters: + * + * * axis: dimensions to be scaled. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: scaled n-dimensional tensor, whose data type is the same as that of input and + * shape is determined by axis. + */ + OH_NNBACKEND_OPS_SCALE = 26, + + /** + * Calculates the shape of the input tensor. + * + * Inputs: + * + * * input: n-dimensional tensor. + * + * Outputs: + * + * * output: integer array representing the dimensions of the input tensor. + */ + OH_NNBACKEND_OPS_SHAPE = 27, + + /** + * Applies the sigmoid operation to the input tensor. + * + * Inputs: + * + * * input: n-dimensional tensor. + * + * Outputs: + * + * * output: result of the sigmoid operation. It is an n-dimensional tensor + * with the same data type and shape as input. + */ + OH_NNBACKEND_OPS_SIGMOID = 28, + + /** + * Slices a tensor of the specified size from the input in each dimension. + * + * Inputs: + * + * * input: n-dimensional input tensor. + * * begin: start of the slice, which is an array of integers greater than or equal to 0. + * * size: slice length, which is an array of integers greater than or equal to 0. + * Assume that a dimension is i and 1<=size[i]<=input.shape[i]-begin[i]. + * + * Outputs: + * + * * output: n-dimensional tensor obtained by slicing. + * The TensorType, shape, and size of the output are the same as those of the input. + */ + OH_NNBACKEND_OPS_SLICE = 29, + + /** + * Applies the softmax operation to the input tensor. + * + * Inputs: + * + * * input: n-dimensional input tensor. + * + * Parameters: + * + * * axis: dimension in which the softmax operation is performed. + * The value is of the int64 type. It is an integer in the range [-n, n). + * + * Outputs: + * + * * output: result of the softmax operation. It is an n-dimensional tensor with + * the same data type and shape as input. + */ + OH_NNBACKEND_OPS_SOFTMAX = 30, + + /** + * Divides a 4D tensor into small blocks and combines these blocks in the original batch. + * The number of blocks is blockShape[0] multiplied by blockShape[1]. + * + * Inputs: + * + * * input: 4D tensor. + * + * Parameters: + * + * * blockShape: a pair of integers. Each of them is greater than or equal to 1. + * * paddings: a pair of arrays. Each of them consists of two integers. The four integers that form paddings + * must be greater than or equal to 0. paddings[0][0] and paddings[0][1] + * specify the number of paddings in the third dimension, and paddings[1][0] and paddings[1][1] + * specify the number of paddings in the fourth dimension. + * + * Outputs: + * + * * output: 4D tensor with the same data type as input. The shape is determined by input, + * blockShape, and paddings. Assume that the input shape is [n,c,h,w], then: + * output.shape[0] = n * blockShape[0] * blockShape[1] + * output.shape[1] = c + * output.shape[2] = (h + paddings[0][0] + paddings[0][1]) / blockShape[0] + * output.shape[3] = (w + paddings[1][0] + paddings[1][1]) / blockShape[1] + * (h + paddings[0][0] + paddings[0][1]) and (w + paddings[1][0] + paddings[1][1]) is exactly divisible by + * (h + paddings[0][0] + paddings[0][1]) and (w + paddings[1][0] + paddings[1][1]). + * + */ + OH_NNBACKEND_OPS_SPACE_TO_BATCH_ND = 31, + + /** + * Splits the input into multiple tensors along the axis dimension. The number of tensors is specified by outputNum. + * + * Inputs: + * + * * input: n-dimensional tensor. + * + * Parameters: + * + * * outputNum: number of output tensors. The data type is long. + * * size_splits: size of each tensor split from the input. The value is a 1D tensor of the int type. + * If size_splits is empty, the input will be evenly split into tensors of the same size. In this case, + * input.shape[axis] can be exactly divisible by outputNum. + * If size_splits is not empty, the sum of all its elements must be equal to input.shape[axis]. + * * axis: splitting dimension of the int type. + * + * Outputs: + * + * * outputs: array of n-dimensional tensors, with the same data type and dimensions. + * The data type of each tensor is the same as that of input. + */ + OH_NNBACKEND_OPS_SPLIT = 32, + + /** + * Calculates the square root of a tensor. + * + * Inputs: + * + * * input: n-dimensional tensor. + * + * Outputs: + * + * * output: square root of the input. It is an n-dimensional tensor with the same data type and shape as input. + */ + OH_NNBACKEND_OPS_SQRT = 33, + + /** + * Calculates the square of the difference between two tensors. The SquaredDifference operator supports tensor and tensor subtraction. + * If two tensors have different TensorTypes, the Sub operator converts the low-precision tensor to a high-precision one. + * If two tensors have different shapes, the two tensors can be extended to tensors with the same shape through broadcast. + * + * Inputs: + * + * * input1: minuend, which is a tensor of the NN_FLOAT16, NN_FLOAT32, NN_INT32, or NN_BOOL type. + * * input2: subtrahend, which is a tensor of the NN_FLOAT16, NN_FLOAT32, NN_INT32, or NN_BOOL type. + * + * Outputs: + * + * * output: square of the difference between two inputs. The output shape is determined + * byinput1 and input2. If they have the same shape, the output tensor has the same shape as them. + * If they have different shapes, perform the broadcast operation on input1 and input2 and perform subtraction. + * TensorType of the output is the same as that of the input tensor with higher precision. + */ + OH_NNBACKEND_OPS_SQUARED_DIFFERENCE = 34, + + /** + * Removes the dimension with a length of 1 from the specified axis. The int8 quantization input is supported. + * Assume that the input shape is [2, 1, 1, 2, 2] and axis is [0,1], the output shape is [2, 1, 2, 2], + * which means the dimension whose length is 0 between dimensions 0 and dimension 1 is removed. + * + * Inputs: + * + * * input: n-dimensional tensor. + * + * Parameters: + * + * * axis: dimension to be removed. The value is of int64_t type and can be an integer in the range [-n, n) or an array. + * + * Outputs: + * + * * output: output tensor. + */ + OH_NNBACKEND_OPS_SQUEEZE = 35, + + /** + * Stacks multiple tensors along the specified axis. If each tensor has n dimensions before stacking, + * the output tensor will have n+1 dimensions. + * + * Inputs: + * + * * input: input for stacking, which can contain multiple n-dimensional tensors. + * Each of them must have the same shape and type. + * + * Parameters: + * + * * axis: dimension for tensor stacking, which is an integer. The value range is [-(n+1),(n+1)), + * which means a negative number is allowed. + * + * Outputs: + * + * * output: stacking result of the input along the axis dimension. The value is an n+1-dimensional tensor + * and has the same TensorType as the input. + */ + OH_NNBACKEND_OPS_STACK = 36, + + /** + * Slices a tensor with the specified stride. + * + * Inputs: + * + * * input: n-dimensional input tensor. + * * begin: start of slicing, which is a 1D tensor. The length of begin is n. + * begin[i] specifies the start of slicing in the ith dimension. + * * end: end of slicing, which is a 1D tensor. The length of end is n. + * end[i] specifies the end of slicing in the ith dimension. + * * strides: slicing stride, which is a 1D tensor. The length of strides is n. + * strides[i] specifies the stride at which the tensor is sliced in the ith dimension. + * + * Parameters: + * + * * beginMask: an integer used to mask begin. beginMask is represented in binary code. + * In case of binary(beginMask)[i]==1, for the ith dimension, elements are sliced from the first element + * at strides[i] until the end[i]-1 element. + * + * * endMask: an integer used to mask end. endMask is represented in binary code. + * In case of binary(endMask)[i]==1, elements are sliced from the element at the begin[i] position + * in the ith dimension until the tensor boundary at strides[i]. + * + * * ellipsisMask: integer used to mask begin and end. ellipsisMask is represented in binary code. + * In case of binary(ellipsisMask)[i]==1, elements are sliced from the first element at strides[i] in the ith dimension + * until the tensor boundary. Only one bit of binary(ellipsisMask) can be a non-zero value. + * + * * newAxisMask: new dimension, which is an integer. newAxisMask is represented in binary code. + * In case of binary(newAxisMask)[i]==1, a new dimension whose length is 1 is inserted into the ith dimension. + * * shrinkAxisMask: shrinking dimension, which is an integer. * shrinkAxisMask is represented in binary code. + * In the case of binary(shrinkAxisMask)[i]==1, all elements in the ith dimension will be discarded, + * and the length of the ith dimension is shrunk to 1. + * + * Outputs: + * + * * A tensor, with the same data type as input. The number of dimensions of the output tensor is rank(input[0])+1. + */ + OH_NNBACKEND_OPS_STRIDED_SLICE = 37, + + /** + * Calculates the difference between two tensors. + * + * Inputs: + * + * * input1: minuend, which is a tensor. + * * input2: subtrahend, which is a tensor. + * + * Parameters: + * + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: difference between the two tensors. The output shape is determined byinput1 and input2. + * If they have the same shape, the output tensor has the same shape as them. + * If they have different shapes, perform the broadcast operation on input1 and input2 and perform subtraction. + * TensorType of the output is the same as that of the input tensor with higher precision. + */ + OH_NNBACKEND_OPS_SUB = 38, + + /** + * Computes hyperbolic tangent of the input tensor. + * + * Inputs: + * + * * input: n-dimensional tensor. + * + * Outputs: + * + * * output: hyperbolic tangent of the input. The TensorType and tensor shape are the same as those of the input. + */ + OH_NNBACKEND_OPS_TANH = 39, + + /** + * Copies a tensor the specified times. + * + * Inputs: + * * input: n-dimensional tensor. + * * multiples: number of times that the input tensor is copied in each dimension. The value is a 1D tensor. + * The length m is not less than the number of dimensions, that is, n. + * + * Outputs: + * * An m-dimensional tensor whose TensorType is the same as that of the input. If input and + * multiples have the same length, input and output have the same number of dimensions. + * If the length of multiples is greater than n, 1 is used to fill the input dimension, + * and then the input is copied in each dimension the specified times to obtain the m-dimensional tensor. + */ + OH_NNBACKEND_OPS_TILE = 40, + + /** + * Transposes data of input 0 based on permutation. + * + * Inputs: + * + * * input: n-dimensional tensor to be transposed. + * * permutation: The value is a 1D tensor whose length is the same as the number of dimensions of input 0. + * + * Outputs: + * + * * output: n-dimensional tensor. TensorType of output 0 is the same as that of input 0, + * and the output shape is determined by the shape and permutation of input 0. + */ + OH_NNBACKEND_OPS_TRANSPOSE = 41, + + /** + * Calculates the average value in the specified dimension. If keepDims is set to false, the number of dimensions + * is reduced for the input; if keepDims is set to true, the number of dimensions is retained. + * + * Inputs: + * + * * input: n-dimensional input tensor, where n is less than 8. + * * axis: dimension used to calculate the average value. The value is a 1D tensor. The value range of each element in axis is [–n, n). + * + * Parameters: + * + * * keepDims: indicates whether to retain the dimension. The value is a Boolean value. + * + * Outputs: + * + * * output: m-dimensional output tensor whose data type is the same as that of the input. If keepDims is + * false, m==n. If keepDims is true, minput: 4D input tensor. Each element in the input cannot be less than 0. The input layout must be [batchSize, height, width, channels]. + * + * Parameters: + * + * * newHeight: resized height of the 4D tensor. + * * newWidth: resized width of the 4D tensor. + * * preserveAspectRatio: indicates whether to maintain the height/width ratio of input after resizing. + * * coordinateTransformMode: coordinate transformation method used by the resize operation. The value is an int32 integer. + * Currently, the following methods are supported: + * * excludeOutside: an int64 floating point number. When its value is 1, the sampling weight of the part that + * exceeds the boundary of input is set to 0, and other weights are normalized. + * + * Outputs: + * + * * output: n-dimensional tensor, with the same shape and data type as input. + */ + OH_NNBACKEND_OPS_RESIZE_BILINEAR = 43, + + /** + * Calculates the reciprocal of the square root of a tensor. + * + * Inputs: + * + * * input: n-dimensional tensor, where n is less than 8. Each element of the tensor cannot be less than 0. + * + * Outputs: + * + * * output: n-dimensional tensor, with the same shape and data type as input. + */ + OH_NNBACKEND_OPS_RSQRT = 44, + + /** + * Reshapes a tensor. + * + * Inputs: + * + * * input: n-dimensional input tensor. + * * InputShape: shape of the output tensor. The value is a 1D constant tensor. + * + * Outputs: + * + * * output: tensor whose data type is the same as that of input and shape is determined by InputShape. + */ + OH_NNBACKEND_OPS_RESHAPE = 45, + + /** + * Calculates the PReLU activation value of input and weight. + * + * Inputs: + * + * * input: n-dimensional tensor. If n is greater than or equal to 2, inputX must be [BatchSize, ..., Channels]. + * The second dimension is the number of channels. + * * weight: 1D tensor. The length of weight must be 1 or equal to the number of channels. If the length of weight is 1, + * all channels share the same weight. + * If the length of weight is equal to the number of channels, each channel exclusively has a weight. + * If n is less than 2 for inputX, the weight length must be 1. + * + * Outputs: + * + * * output: PReLU activation value of x, with the same shape and data type as inputX. + */ + OH_NNBACKEND_OPS_PRELU = 46, + + /** + * Calculates the Relu activation value of input. + * + * Inputs: + * + * * input: n-dimensional input tensor. + * + * Outputs: + * + * * output: n-dimensional tensor, with the same data type and shape as the input tensor. + */ + OH_NNBACKEND_OPS_RELU = 47, + + /** + * Calculates the Relu6 activation value of the input, that is, calculate min(max(x, 0), 6) for each element x in the input. + * + * Inputs: + * + * * input: n-dimensional input tensor. + * + * Outputs: + * + * * output: n-dimensional Relu6 tensor, with the same data type and shape as the input tensor. + */ + OH_NNBACKEND_OPS_RELU6 = 48, + + /** + * Applies layer normalization for a tensor from the specified axis. + * + * Inputs: + * + * * input: n-dimensional input tensor. + * * gamma: m-dimensional tensor. The dimensions of gamma must be the same as + * the shape of the part of the input tensor to normalize. + * * beta: m-dimensional tensor with the same shape as gamma. + * + * Parameters: + * + * * beginAxis is an NN_INT32 scalar that specifies the axis from which normalization starts. The value range is [1, rank(input)). + * * epsilon is a scalar of NN_FLOAT32. It is a tiny amount in the normalization formula. The common value is 1e-7. + * + * Outputs: + * + * * output: n-dimensional tensor, with the same data type and shape as the input tensor. + */ + OH_NNBACKEND_OPS_LAYER_NORM = 49, + + /** + * Calculates the accumulated value for a tensor along the specified dimension. + * + * Inputs: + * + * * input: n-dimensional input tensor, where n is less than 8. + * * axis: dimension used to calculate the product. The value is a 1D tensor. The value range of each element in axis is [–n, n). + * + * Parameters: + * + * * keepDims: indicates whether to retain the dimension. The value is a Boolean value. + * When its value is true, the number of output dimensions is the same as that of the input. + * When its value is false, the number of output dimensions is reduced. + * + * Outputs: + * + * * output: m-dimensional output tensor whose data type is the same as that of the input. + * If keepDims is false, m==n. If keepDims is true, mkeepDims is set to false, + * the number of dimensions is reduced for the input; if keepDims is set to true, the number of dimensions is retained. + * + * Inputs: + * + * * A n-dimensional input tensor, where n is less than 8. + * * A 1D tensor specifying the dimension used to operate the logical OR. The value range of each element in axis is [–n, n). + * + * Parameters: + * + * * keepDims: indicates whether to retain the dimension. The value is a Boolean value. + * + * Outputs: + * * output: m-dimensional output tensor whose data type is the same as that of the input. + * If keepDims is false, m==n. If keepDims is true, minput: n-dimensional tensor. + * + * Parameters: + * + * * src_t: data type of the input. + * * dst_t: data type of the output. + * + * Outputs: + * + * * output: n-dimensional tensor. The data type is determined by input2. + * The output shape is the same as the input shape. + */ + OH_NNBACKEND_OPS_QUANT_DTYPE_CAST = 52, + + /** + * Obtains the values and indices of the largest k entries in the last dimension. + * + * Inputs: + * + * * input: n-dimensional tensor. + * * input k: first k records of data and their indices. + * + * Parameters: + * + * * sorted: order of sorting. The value true means descending and false means ascending. + * + * Outputs: + * + * * output0: largest k elements in each slice of the last dimension. + * * output1: index of the value in the last dimension of the input. + */ + OH_NNBACKEND_OPS_TOP_K = 53, + + /** + * Returns the index of the maximum tensor value across axes. + * + * Inputs: + * + * * input: n-dimensional tensor (N, ∗), where ∗ means any number of additional dimensions. + * + * Parameters: + * + * * axis: dimension for calculating the index of the maximum. + * * keep_dims: indicates whether to maintain the input tensor dimension. The value is a Boolean value. + * + * Outputs: + * * output: index of the maximum input tensor on the axis. The value is a tensor. + */ + OH_NNBACKEND_OPS_ARG_MAX = 54, + + /** + * Adds a dimension based on the value of axis. + * + * Inputs: + * * input: n-dimensional tensor. + * + * Parameters: + * + * * axis: dimension to be added. The value of axis can be an integer or an array of integers. + * The value range of the integer is [-n, n). + * + * Outputs: + * * output: output tensor. + */ + OH_NNBACKEND_OPS_UNSQUEEZE = 55, + + /** + * Gaussian error linear unit activation function. The int quantization input is not supported. output=0.5∗input∗(1+tanh(input/2)) + * + * Inputs: + * * An n-dimensional input tensor. + * + * Outputs: + * * output: n-dimensional tensor, with the same data type and shape as the input tensor. + */ + OH_NNBACKEND_OPS_GELU = 56, +} OH_NNBackend_OperationType; + +/** + * @brief Enumerates the tensor data types. + * + * Tensors are usually used to set the input, output, and operator parameters of a model. When a tensor is used + * as the input or output of a model (or operator), set the tensor type to {@link OH_NNBACKEND_TENSOR}. + * When the tensor is used as an operator parameter, select an enumerated value other than {@link OH_NNBACKEND_TENSOR} as the tensor type. + * Assume that the pad parameter of the {@link OH_NNBACKEND_OPS_CONV2D} operator is being set. + * You need to set the type attribute of the {@link OH_NNBACKEND_Tensor} instance to {@link OH_NNBACKEND_CONV2D_PAD}. + * The settings of other operator parameters are similar. The enumerated values are named + * in the format OH_NNBACKEND_{Operator name}_{Attribute name}. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** This enumerated value is used when the tensor is used as the input or output of a model (or operator). */ + OH_NNBACKEND_TENSOR = 0, + + /** This enumerated value is used when the tensor is used as the activationType parameter of the Add operator. */ + OH_NNBACKEND_ADD_ACTIVATIONTYPE = 1, + + /** This enumerated value is used when the tensor is used as the kernel_size parameter of the AvgPool operator. */ + OH_NNBACKEND_AVG_POOL_KERNEL_SIZE = 2, + /** This enumerated value is used when the tensor is used as the stride parameter of the AvgPool operator. */ + OH_NNBACKEND_AVG_POOL_STRIDE = 3, + /** This enumerated value is used when the tensor is used as the pad_mode parameter of the AvgPool operator. */ + OH_NNBACKEND_AVG_POOL_PAD_MODE = 4, + /** This enumerated value is used when the tensor is used as the pad parameter of the AvgPool operator. */ + OH_NNBACKEND_AVG_POOL_PAD = 5, + /** This enumerated value is used when the tensor is used as the activation_type parameter of the AvgPool operator. */ + OH_NNBACKEND_AVG_POOL_ACTIVATION_TYPE = 6, + + /** This enumerated value is used when the tensor is used as the eosilon parameter of the BatchNorm operator. */ + OH_NNBACKEND_BATCH_NORM_EPSILON = 7, + + /** This enumerated value is used when the tensor is used as the blockSize parameter of the BatchToSpaceND operator. */ + OH_NNBACKEND_BATCH_TO_SPACE_ND_BLOCKSIZE = 8, + /** This enumerated value is used when the tensor is used as the crops parameter of the BatchToSpaceND operator. */ + OH_NNBACKEND_BATCH_TO_SPACE_ND_CROPS = 9, + + /** This enumerated value is used when the tensor is used as the axis parameter of the Concat operator. */ + OH_NNBACKEND_CONCAT_AXIS = 10, + + /** This enumerated value is used when the tensor is used as the strides parameter of the Conv2D operator. */ + OH_NNBACKEND_CONV2D_STRIDES = 11, + /** This enumerated value is used when the tensor is used as the pad parameter of the Conv2D operator. */ + OH_NNBACKEND_CONV2D_PAD = 12, + /** This enumerated value is used when the tensor is used as the dilation parameter of the Conv2D operator. */ + OH_NNBACKEND_CONV2D_DILATION = 13, + /** This enumerated value is used when the tensor is used as the padMode parameter of the Conv2D operator. */ + OH_NNBACKEND_CONV2D_PAD_MODE = 14, + /** This enumerated value is used when the tensor is used as the activationType parameter of the Conv2D operator. */ + OH_NNBACKEND_CONV2D_ACTIVATION_TYPE = 15, + /** This enumerated value is used when the tensor is used as the group parameter of the Conv2D operator. */ + OH_NNBACKEND_CONV2D_GROUP = 16, + + /** This enumerated value is used when the tensor is used as the strides parameter of the Conv2DTranspose operator. */ + OH_NNBACKEND_CONV2D_TRANSPOSE_STRIDES = 17, + /** This enumerated value is used when the tensor is used as the pad parameter of the Conv2DTranspose operator. */ + OH_NNBACKEND_CONV2D_TRANSPOSE_PAD = 18, + /** This enumerated value is used when the tensor is used as the dilation parameter of the Conv2DTranspose operator. */ + OH_NNBACKEND_CONV2D_TRANSPOSE_DILATION = 19, + /** This enumerated value is used when the tensor is used as the outputPaddings parameter of the Conv2DTranspose operator. */ + OH_NNBACKEND_CONV2D_TRANSPOSE_OUTPUT_PADDINGS = 20, + /** This enumerated value is used when the tensor is used as the padMode parameter of the Conv2DTranspose operator. */ + OH_NNBACKEND_CONV2D_TRANSPOSE_PAD_MODE = 21, + /** This enumerated value is used when the tensor is used as the activationType parameter of the Conv2DTranspose operator. */ + OH_NNBACKEND_CONV2D_TRANSPOSE_ACTIVATION_TYPE = 22, + /** This enumerated value is used when the tensor is used as the group parameter of the Conv2DTranspose operator. */ + OH_NNBACKEND_CONV2D_TRANSPOSE_GROUP = 23, + + /** This enumerated value is used when the tensor is used as the strides parameter of the DepthwiseConv2dNative operator. */ + OH_NNBACKEND_DEPTHWISE_CONV2D_NATIVE_STRIDES = 24, + /** This enumerated value is used when the tensor is used as the pad parameter of the DepthwiseConv2dNative operator. */ + OH_NNBACKEND_DEPTHWISE_CONV2D_NATIVE_PAD = 25, + /** This enumerated value is used when the tensor is used as the dilation parameter of the DepthwiseConv2dNative operator. */ + OH_NNBACKEND_DEPTHWISE_CONV2D_NATIVE_DILATION = 26, + /** This enumerated value is used when the tensor is used as the padMode parameter of the DepthwiseConv2dNative operator. */ + OH_NNBACKEND_DEPTHWISE_CONV2D_NATIVE_PAD_MODE = 27, + /** This enumerated value is used when the tensor is used as the activationType parameter of the DepthwiseConv2dNative operator. */ + OH_NNBACKEND_DEPTHWISE_CONV2D_NATIVE_ACTIVATION_TYPE = 28, + + /** This enumerated value is used when the tensor is used as the activationType parameter of the Div operator. */ + OH_NNBACKEND_DIV_ACTIVATIONTYPE = 29, + + /** This enumerated value is used when the tensor is used as the mode parameter of the Eltwise operator. */ + OH_NNBACKEND_ELTWISE_MODE = 30, + + /** This enumerated value is used when the tensor is used as the axis parameter of the FullConnection operator. */ + OH_NNBACKEND_FULL_CONNECTION_AXIS = 31, + /** This enumerated value is used when the tensor is used as the activationType parameter of the FullConnection operator. */ + OH_NNBACKEND_FULL_CONNECTION_ACTIVATIONTYPE = 32, + + /** This enumerated value is used when the tensor is used as the transposeA parameter of the Matmul operator. */ + OH_NNBACKEND_MATMUL_TRANSPOSE_A = 33, + /** This enumerated value is used when the tensor is used as the transposeB parameter of the Matmul operator. */ + OH_NNBACKEND_MATMUL_TRANSPOSE_B = 34, + /** This enumerated value is used when the tensor is used as the activationType parameter of the Matmul operator. */ + OH_NNBACKEND_MATMUL_ACTIVATION_TYPE = 35, + + /** This enumerated value is used when the tensor is used as the kernel_size parameter of the MaxPool operator. */ + OH_NNBACKEND_MAX_POOL_KERNEL_SIZE = 36, + /** This enumerated value is used when the tensor is used as the stride parameter of the MaxPool operator. */ + OH_NNBACKEND_MAX_POOL_STRIDE = 37, + /** This enumerated value is used when the tensor is used as the pad_mode parameter of the MaxPool operator. */ + OH_NNBACKEND_MAX_POOL_PAD_MODE = 38, + /** This enumerated value is used when the tensor is used as the pad parameter of the MaxPool operator. */ + OH_NNBACKEND_MAX_POOL_PAD = 39, + /** This enumerated value is used when the tensor is used as the activation_type parameter of the MaxPool operator. */ + OH_NNBACKEND_MAX_POOL_ACTIVATION_TYPE = 40, + + /** This enumerated value is used when the tensor is used as the activationType parameter of the Mul operator. */ + OH_NNBACKEND_MUL_ACTIVATION_TYPE = 41, + + /** This enumerated value is used when the tensor is used as the axis parameter of the OneHot operator. */ + OH_NNBACKEND_ONE_HOT_AXIS = 42, + + /** This enumerated value is used when the tensor is used as the constant_value parameter of the Pad operator. */ + OH_NNBACKEND_PAD_CONSTANT_VALUE = 43, + + /** This enumerated value is used when the tensor is used as the activationType parameter of the Scale operator. */ + OH_NNBACKEND_SCALE_ACTIVATIONTYPE = 44, + /** This enumerated value is used when the tensor is used as the axis parameter of the Scale operator. */ + OH_NNBACKEND_SCALE_AXIS = 45, + + /** This enumerated value is used when the tensor is used as the axis parameter of the Softmax operator. */ + OH_NNBACKEND_SOFTMAX_AXIS = 46, + + /** This enumerated value is used when the tensor is used as the BlockShape parameter of the SpaceToBatchND operator. */ + OH_NNBACKEND_SPACE_TO_BATCH_ND_BLOCK_SHAPE = 47, + /** This enumerated value is used when the tensor is used as the Paddings parameter of the SpaceToBatchND operator. */ + OH_NNBACKEND_SPACE_TO_BATCH_ND_PADDINGS = 48, + + /** This enumerated value is used when the tensor is used as the Axis parameter of the Split operator. */ + OH_NNBACKEND_SPLIT_AXIS = 49, + /** This enumerated value is used when the tensor is used as the OutputNum parameter of the Split operator. */ + OH_NNBACKEND_SPLIT_OUTPUT_NUM = 50, + /** This enumerated value is used when the tensor is used as the SizeSplits parameter of the Split operator. */ + OH_NNBACKEND_SPLIT_SIZE_SPLITS = 51, + + /** This enumerated value is used when the tensor is used as the Axis parameter of the Squeeze operator. */ + OH_NNBACKEND_SQUEEZE_AXIS = 52, + + /** This enumerated value is used when the tensor is used as the Axis parameter of the Stack operator. */ + OH_NNBACKEND_STACK_AXIS = 53, + + /** This enumerated value is used when the tensor is used as the BeginMask parameter of the StridedSlice operator. */ + OH_NNBACKEND_STRIDED_SLICE_BEGIN_MASK = 54, + /** This enumerated value is used when the tensor is used as the EndMask parameter of the StridedSlice operator. */ + OH_NNBACKEND_STRIDED_SLICE_END_MASK = 55, + /** This enumerated value is used when the tensor is used as the EllipsisMask parameter of the StridedSlice operator. */ + OH_NNBACKEND_STRIDED_SLICE_ELLIPSIS_MASK = 56, + /** This enumerated value is used when the tensor is used as the NewAxisMask parameter of the StridedSlice operator. */ + OH_NNBACKEND_STRIDED_SLICE_NEW_AXIS_MASK = 57, + /** This enumerated value is used when the tensor is used as the ShrinkAxisMask parameter of the StridedSlice operator. */ + OH_NNBACKEND_STRIDED_SLICE_SHRINK_AXIS_MASK = 58, + + /** This enumerated value is used when the tensor is used as the ActivationType parameter of the Sub operator. */ + OH_NNBACKEND_SUB_ACTIVATIONTYPE = 59, + + /** This enumerated value is used when the tensor is used as the keep_dims parameter of the ReduceMean operator. */ + OH_NNBACKEND_REDUCE_MEAN_KEEP_DIMS = 60, + + /** This enumerated value is used when the tensor is used as the new_height parameter of the ResizeBilinear operator. */ + OH_NNBACKEND_RESIZE_BILINEAR_NEW_HEIGHT = 61, + /** This enumerated value is used when the tensor is used as the new_width parameter of the ResizeBilinear operator. */ + OH_NNBACKEND_RESIZE_BILINEAR_NEW_WIDTH = 62, + /** This enumerated value is used when the tensor is used as the preserve_aspect_ratio parameter of the ResizeBilinear operator. */ + OH_NNBACKEND_RESIZE_BILINEAR_PRESERVE_ASPECT_RATIO = 63, + /** This enumerated value is used when the tensor is used as the coordinate_transform_mode parameter of the ResizeBilinear operator. */ + OH_NNBACKEND_RESIZE_BILINEAR_COORDINATE_TRANSFORM_MODE = 64, + /** This enumerated value is used when the tensor is used as the exclude_outside parameter of the ResizeBilinear operator. */ + OH_NNBACKEND_RESIZE_BILINEAR_EXCLUDE_OUTSIDE = 65, + + /** This enumerated value is used when the tensor is used as the beginNormAxis parameter of the LayerNorm operator. */ + OH_NNBACKEND_LAYER_NORM_BEGIN_NORM_AXIS = 66, + /** This enumerated value is used when the tensor is used as the epsilon parameter of the LayerNorm operator. */ + OH_NNBACKEND_LAYER_NORM_EPSILON = 67, + /** This enumerated value is used when the tensor is used as the beginParamsAxis parameter of the LayerNorm operator. */ + OH_NNBACKEND_LAYER_NORM_BEGIN_PARAM_AXIS = 68, + /** This enumerated value is used when the tensor is used as the elementwiseAffine parameter of the LayerNorm operator. */ + OH_NNBACKEND_LAYER_NORM_ELEMENTWISE_AFFINE = 69, + + /** This enumerated value is used when the tensor is used as the keep_dims parameter of the ReduceProd operator. */ + OH_NNBACKEND_REDUCE_PROD_KEEP_DIMS = 70, + + /** This enumerated value is used when the tensor is used as the keep_dims parameter of the ReduceAll operator. */ + OH_NNBACKEND_REDUCE_ALL_KEEP_DIMS = 71, + + /** This enumerated value is used when the tensor is used as the src_t parameter of the QuantDTypeCast operator. */ + OH_NNBACKEND_QUANT_DTYPE_CAST_SRC_T = 72, + /** This enumerated value is used when the tensor is used as the dst_t parameter of the QuantDTypeCast operator. */ + OH_NNBACKEND_QUANT_DTYPE_CAST_DST_T = 73, + + /** This enumerated value is used when the tensor is used as the Sorted parameter of the Topk operator. */ + OH_NNBACKEND_TOP_K_SORTED = 74, + + /** This enumerated value is used when the tensor is used as the axis parameter of the ArgMax operator. */ + OH_NNBACKEND_ARG_MAX_AXIS = 75, + /** This enumerated value is used when the tensor is used as the keepDims parameter of the ArgMax operator. */ + OH_NNBACKEND_ARG_MAX_KEEPDIMS = 76, + + /** This enumerated value is used when the tensor is used as the Axis parameter of the Unsqueeze operator. */ + OH_NNBACKEND_UNSQUEEZE_AXIS = 77, +} OH_NNBackend_TensorType; + +/** + * @brief This structure is used to store a 32-bit unsigned integer array. + * + * @since 9 + * @version 2.0 + */ +typedef struct OH_NNBackend_Array { + /** Pointer to the unsigned integer array */ + void* data; + /** Array length */ + size_t length; + /** Data type of the array*/ + OH_NNCore_DataType datatype; +} OH_NNBackend_Array; + + +typedef struct OH_NNBackend_Memory OH_NNBackend_Memory; + +#ifdef __cplusplus +} +#endif // __cplusplus + +/** @} */ +#endif // NEURAL_NETWORK_RUNTIME_TYPE_H diff --git a/interfaces/kits/c/v2_0/neural_network_core.h b/interfaces/kits/c/v2_0/neural_network_core.h new file mode 100644 index 0000000000000000000000000000000000000000..28acc8dc44daff4b76494c8b39265c095c8445ff --- /dev/null +++ b/interfaces/kits/c/v2_0/neural_network_core.h @@ -0,0 +1,571 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_CORE_API_H +#define NEURAL_NETWORK_CORE_API_H + +#include "neural_network_core_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Compilation APIs +OH_NNCore_ReturnCode OH_NNCore_GetBackendNum(size_t* backendNum); + +OH_NNCore_ReturnCode OH_NNCore_GetBackendName(size_t index, const char** backendName); + +OH_NNCore_Compilation* OH_NNCore_ConstructCompilationWithNNModel(const void* model); + +OH_NNCore_Compilation* OH_NNCore_ConstructCompilationWithOfflineModel(const char* filePath); + +OH_NNCore_Compilation* OH_NNCore_ConstructCompilationWithOfflineBuffer(const void* modelData, size_t modelSize); + +/** + * @brief 执行模型编译 + * + * 该接口用于将已经构建好的{@link OH_NNCore_Compilation}实例编译成{@link OH_NNCore_Compiled}实例,编译所需要的设备和 + * 编译选项可以通过backend和options进行设置。 + * + * 当创建好{@link OH_NNCore_Compiled}实例后, 如不需要再进行编译,可以调用{@link OH_NNCore_DestroyCompilation}接口释放 + * {@link OH_NNCore_Compilation}对象。 + * + * @param compilation 指向{@link OH_NNCore_Compiliation}实例的指针。 + * @param backendName z设备名称 + * @param options 指向{@link OH_NNCore_Options}实例的指针。 + * @return 指向{@link OH_NNCore_Compiled}的指针。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_Compiled* OH_NNCore_BuildCompilation(OH_NNCore_Compilation* compilation, + const char* backendName, + OH_NNCore_Options* options); + +OH_NNCore_ReturnCode OH_NNCore_DestroyCompilation(OH_NNCore_Compilation** compilation); + +// Compiled APIs +/** + * @brief 将编译好的模型缓存保存到文件中 + * + * 在支持缓存的硬件上,模型在硬件驱动层编译后可以保存为缓存文件,下次编译时直接从缓存文件读取模型,减少重新编译的耗时。\n + * + * @param compiled 指向{@link OH_NNCore_Compiled}实例的指针。 + * @param filePath 保存模型缓存的目录。 + * @return 函数执行的结果状态。执行成功返回OH_NNCOER_SUCCESS;失败返回具体错误码,具体失败错误码可参考{@link OH_NNCore_ReturnCode}。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_SaveCompiledToFile(const OH_NNCore_Compiled* compiled, const char* filePath); + +/** + * @brief 从缓存文件中加载模型缓存 + * + * 在支持缓存的硬件上,可以加载之前调用{@link OH_NNCore_SaveCompiledToFile}保存的模型缓存,减少重新编译的耗时。\n + * + * @param filePath 保存模型缓存的目录 + * @param backendName 指定使用的硬件名称 + * @param options 指向{@link OH_NNCore_Options}实例的指针 + * @param compiled 指向{@link OH_NNCore_Compiled}实例的二级指针,要求传入的(*compiled)为空指针,否则返回{@link OH_NNCORE_INVALID_PARAMETER} + * @return 函数执行的结果状态。执行成功返回OH_NNCOER_SUCCESS;失败返回具体错误码,具体失败错误码可参考{@link OH_NNCore_ReturnCode}。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_RestoreCompiledFromFile(const char* filePath, + const char* backendName, + const OH_NNCore_Options* options, + OH_NNCore_Compiled** compiled); + +/** + * @brief 将编译好的模型缓存保存到缓冲区 + * + * 在支持缓存的硬件上,模型在硬件驱动层编译后可以保存到指定的缓冲区,下次编译时直接加载模型缓存,减少重新编译的耗时。\n + * + * @param compiled 指向{@link OH_NNCore_Compiled}实例的指针。 + * @param buffer 指向缓冲区的指针 + * @param length 缓存区大小 + * @param modelSize 模型缓存大小 + * @return 函数执行的结果状态。执行成功返回OH_NNCOER_SUCCESS;失败返回具体错误码,具体失败错误码可参考{@link OH_NNCore_ReturnCode}。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_SaveCompiledToBuffer(const OH_NNCore_Compiled* compiled, + const void* buffer, + size_t length, + size_t* modelSize); + +/** + * @brief 从缓冲区中加载模型缓存 + * + * 在支持缓存的硬件上,可以加载之前调用{@link OH_NNCore_SaveCompiledToBuffer}保存的模型缓存,减少重新编译的耗时。\n + * + * @param buffer 指向缓冲区的指针 + * @param modelSize 模型缓存大小 + * @param backendName 指定使用的硬件名称 + * @param options 指向{@link OH_NNCore_Options}实例的指针 + * @param compiled 指向{@link OH_NNCore_Compiled}实例的二级指针,要求传入的(*compiled)为空指针,否则返回{@link OH_NNCORE_INVALID_PARAMETER} + * @return 函数执行的结果状态。执行成功返回OH_NNCOER_SUCCESS;失败返回具体错误码,具体失败错误码可参考{@link OH_NNCore_ReturnCode}。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_RestoreCompiledFromBuffer(const void* buffer, + size_t modelSize, + const char* backendName, + const OH_NNCore_Options* options, + OH_NNCore_Compiled** compiled); + +/** + * @brief 获取已编译模型的输入张量个数 + * + * 在完成模型的编译后,可以调用本接口获取输入张量的数量,并结合{@link OH_NNCore_CreateCompiledInputDesc},获取指定输入张量描述符。\n + * + * @param compiled 指向{@link OH_NNCore_Compiled}实例的指针。 + * @param inputNum 输入张量的数量 + * @return 函数执行的结果状态。执行成功返回OH_NNCOER_SUCCESS;失败返回具体错误码,具体失败错误码可参考{@link OH_NNCore_ReturnCode}。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_GetCompiledInputNum(const OH_NNCore_Compiled* compiled, size_t* inputNum); + +/** + * @brief 创建已编译模型的输入张量描述符 + * + * 在完成模型的编译后,可以调用本接口创建由index指定的输入张量描述符。通过本接口创建的{@link OH_NNCore_Compiled}实例 + * 需要调用{@link OH_NNCore_DestroyTensorDesc}销毁。\n + * + * @param compiled 指向{@link OH_NNCore_Compiled}实例的指针 + * @param inputNum 输入张量的数量 + * @return 函数执行的结果状态。执行成功返回OH_NNCOER_SUCCESS;失败返回具体错误码,具体失败错误码可参考{@link OH_NNCore_ReturnCode}。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_CreateCompiledInputDesc(const OH_NNCore_Compiled* compiled, + size_t index, + OH_NNCore_TensorDesc** tensorDesc); + +/** + * @brief 获取已编译模型的输出张量个数 + * + * 在完成模型的编译后,可以调用本接口获取输出张量的数量,并结合{@link OH_NNCore_CreateCompiledOutputDesc},获取指定输出张量描述符。\n + * + * @param compiled 指向{@link OH_NNCore_Compiled}实例的指针。 + * @param inputNum 输入张量的数量 + * @return 函数执行的结果状态。执行成功返回OH_NNCOER_SUCCESS;失败返回具体错误码,具体失败错误码可参考{@link OH_NNCore_ReturnCode}。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_GetCompiledOutputNum(const OH_NNCore_Compiled* compiled, size_t* outputNum); + +/** + * @brief 创建已编译模型的输出张量描述符 + * + * 在完成模型的编译后,可以调用本接口创建由index指定的输出张量描述符。通过本接口创建的{@link OH_NNCore_Compiled}实例 + * 需要调用{@link OH_NNCore_DestroyTensorDesc}销毁。\n + * + * @param compiled 指向{@link OH_NNCore_Compiled}实例的指针 + * @param inputNum 输出张量的数量 + * @return 函数执行的结果状态。执行成功返回OH_NNCOER_SUCCESS;失败返回具体错误码,具体失败错误码可参考{@link OH_NNCore_ReturnCode}。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_CreateCompiledOutputDesc(const OH_NNCore_Compiled* compiled, + size_t index, + OH_NNCore_TensorDesc** tensorDesc); + +/** + * @brief 释放已编译模型实例。 + * + * 调用{@link OH_NNCore_BuildCompilation}、{@link OH_NNCore_RestoreCompiledFromFile}或{@link OH_NNCore_RestoreCompiledFromBuffer} + * 创建的{@link OH_NNCore_Compiled}实例需要调用本方法主动释放,否则将造成内存泄漏。\n + * + * 如果compiled为空指针或者*compiled为空指针,本方法只打印warning日志,不执行释放逻辑。\n + * + * @param compiled 指向{@link OH_NNCore_Compiled}实例的二级指针。模型实例销毁后,本方法将*compiled主动设置为空指针。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_DestroyCompiled(OH_NNCore_Compiled** compiled); + +/** + * @brief 创建OH_NNCore_TensorDesc实例对象。 + * + * 该接口创建一个OH_NNCore_TensorDesc对象,用于描述各种Tensor信息,包括name/dataType/shape/format等信息。 + * 有了OH_NNCore_TensorDesc实例对象后,可以进一步调用OH_NNCore_CreateTensor创建Tensor实例对象,得到Tensor内存。 + * + * @return 指向OH_NNCore_TensorDesc对象的指针。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_TensorDesc* OH_NNCore_CreateTensorDesc(); + +/** + * @brief 释放OH_NNCore_TensorDesc实例对象。 + * + * 当创建好OH_NNCore_TensorDesc实例后, 如不需要再使用,调用本接口释放OH_NNCore_TensorDesc对象,否则会造成内存泄漏。 + * + * 如果tensorDesc或者*tensorDesc为空指针,接口会返回错误码。 + * + * @param tensorDesc 指向OH_NNCore_TensorDesc对象的二级指针。 + * @return 返回函数执行结果状态码。如果执行成功,返回OH_NNCORE_SUCCESS,否则返回其它类型错误码OH_NNCore_ReturnCode。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_DestroyTensorDesc(OH_NNCore_TensorDesc** tensorDesc); + +/** + * @brief 设置OH_NNCore_TensorDesc对象名字。 + * + * 当创建好OH_NNCore_TensorDesc实例后, 调用本接口给OH_NNCore_TensorDesc对象设置Tensor名字。 + * + * 如果tensorDesc或者name为空指针,接口会返回错误码。 + * + * @param tensorDesc 指向OH_NNCore_TensorDesc对象的指针。 + * @param name Tensor名字。 + * @return 返回函数执行结果状态码。如果执行成功,返回OH_NNCORE_SUCCESS,否则返回其它类型错误码OH_NNCore_ReturnCode。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_SetTensorDescName(OH_NNCore_TensorDesc* tensorDesc, const char* name); + +/** + * @brief 获取OH_NNCore_TensorDesc对象名字。 + * + * 调用本接口可获取指定OH_NNCore_TensorDesc对象的名字。 + * + * 如果tensorDesc或者name为空指针,接口会返回错误码。作为出参,*name必须为空指针,否则接口会返回错误码。 + * + * @param tensorDesc 指向OH_NNCore_TensorDesc对象的指针。 + * @param name 返回Tensor名字。 + * @return 返回函数执行结果状态码。如果执行成功,返回OH_NNCORE_SUCCESS,否则返回其它类型错误码OH_NNCore_ReturnCode。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_GetTensorDescName(const OH_NNCore_TensorDesc* tensorDesc, const char** name); + +/** + * @brief 设置OH_NNCore_TensorDesc对象数据类型。 + * + * 当创建好OH_NNCore_TensorDesc实例后, 调用本接口给OH_NNCore_TensorDesc对象设置数据类型。 + * + * 如果tensorDesc为空指针,接口会返回错误码。 + * + * @param tensorDesc 指向OH_NNCore_TensorDesc对象的指针。 + * @param dataType Tensor数据类型。 + * @return 返回函数执行结果状态码。如果执行成功,返回OH_NNCORE_SUCCESS,否则返回其它类型错误码OH_NNCore_ReturnCode。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_SetTensorDescDataType(OH_NNCore_TensorDesc* tensorDesc, OH_NNCore_DataType dataType); + +/** + * @brief 获取OH_NNCore_TensorDesc对象数据类型。 + * + * 调用本接口可获取指定OH_NNCore_TensorDesc对象的数据类型。 + * + * 如果tensorDesc或者dataType为空指针,接口会返回错误码。 + * + * @param tensorDesc 指向OH_NNCore_TensorDesc对象的指针。 + * @param dataType 返回Tensor数据类型。 + * @return 返回函数执行结果状态码。如果执行成功,返回OH_NNCORE_SUCCESS,否则返回其它类型错误码OH_NNCore_ReturnCode。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_GetTensorDescDataType(const OH_NNCore_TensorDesc* tensorDesc, + OH_NNCore_DataType* dataType); + +/** + * @brief 设置OH_NNCore_TensorDesc对象shape信息。 + * + * 当创建好OH_NNCore_TensorDesc实例后, 调用本接口给OH_NNCore_TensorDesc对象设置shape信息。 + * + * 如果tensorDesc或者shape为空指针,或者shapeNum为0,接口会返回错误码。 + * + * @param tensorDesc 指向OH_NNCore_TensorDesc对象的指针。 + * @param shape 指向shape信息的数组指针。 + * @param shapeNum 上述shape数组的长度。 + * @return 返回函数执行结果状态码。如果执行成功,返回OH_NNCORE_SUCCESS,否则返回其它类型错误码OH_NNCore_ReturnCode。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_SetTensorDescShape(OH_NNCore_TensorDesc* tensorDesc, + const int32_t* shape, + size_t shapeNum); + +/** + * @brief 获取OH_NNCore_TensorDesc对象shape信息。 + * + * 调用本接口可获取指定OH_NNCore_TensorDesc对象的shape信息。 + * + * 如果tensorDesc,shape或者shapeNum为空指针,接口会返回错误码。作为出参,*shape必须是空指针,否则接口会返回错误码。 + * + * @param tensorDesc 指向OH_NNCore_TensorDesc对象的指针。 + * @param shape 返回Tensor shape数组信息。 + * @param shapeNum 返回Tensor shape数组长度。 + * @return 返回函数执行结果状态码。如果执行成功,返回OH_NNCORE_SUCCESS,否则返回其它类型错误码OH_NNCore_ReturnCode。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_GetTensorDescShape(const OH_NNCore_TensorDesc* tensorDesc, + int32_t** shape, + size_t* shapeNum); + +/** + * @brief 设置OH_NNCore_TensorDesc对象格式信息。 + * + * 当创建好OH_NNCore_TensorDesc实例后, 调用本接口给OH_NNCore_TensorDesc对象设置格式信息。 + * + * 如果tensorDesc为空指针,接口会返回错误码。 + * + * @param tensorDesc 指向OH_NNCore_TensorDesc对象的指针。 + * @param format Tensor格式信息。 + * @return 返回函数执行结果状态码。如果执行成功,返回OH_NNCORE_SUCCESS,否则返回其它类型错误码OH_NNCore_ReturnCode。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_SetTensorDescFormat(OH_NNCore_TensorDesc* tensorDesc, OH_NNCore_Format format); + +/** + * @brief 获取OH_NNCore_TensorDesc对象格式信息。 + * + * 调用本接口可获取指定OH_NNCore_TensorDesc对象的格式信息。 + * + * 如果tensorDesc或者format为空指针,接口会返回错误码。 + * + * @param tensorDesc 指向OH_NNCore_TensorDesc对象的指针。 + * @param format 返回Tensor格式信息。 + * @return 返回函数执行结果状态码。如果执行成功,返回OH_NNCORE_SUCCESS,否则返回其它类型错误码OH_NNCore_ReturnCode。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_GetTensorDescFormat(const OH_NNCore_TensorDesc* tensorDesc, OH_NNCore_Format* format); + +/** + * @brief 获取OH_NNCore_TensorDesc对象元素个数。 + * + * 调用本接口可获取指定OH_NNCore_TensorDesc对象的元素个数。如需获取字节数,可调用OH_NNCore_GetTensorDescByteSize接口获取。 + * + * 如果tensorDesc或者elementNum为空指针,接口会返回错误码。 + * + * @param tensorDesc 指向OH_NNCore_TensorDesc对象的指针。 + * @param elementNum 返回Tensor元素个数。 + * @return 返回函数执行结果状态码。如果执行成功,返回OH_NNCORE_SUCCESS,否则返回其它类型错误码OH_NNCore_ReturnCode。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_GetTensorDescElementNum(const OH_NNCore_TensorDesc* tensorDesc, size_t* elementNum); + +/** + * @brief 获取OH_NNCore_TensorDesc对象字节数。 + * + * 调用本接口可获取指定OH_NNCore_TensorDesc对象的字节数。如需获取元素个数,可调用OH_NNCore_GetTensorDescElementNum接口获取。 + * + * 如果tensorDesc或者byteSize为空指针,接口会返回错误码。 + * + * @param tensorDesc 指向OH_NNCore_TensorDesc对象的指针。 + * @param byteSize 返回Tensor字节数。 + * @return 返回函数执行结果状态码。如果执行成功,返回OH_NNCORE_SUCCESS,否则返回其它类型错误码OH_NNCore_ReturnCode。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_GetTensorDescByteSize(const OH_NNCore_TensorDesc* tensorDesc, size_t* byteSize); + +/** + * @brief 创建OH_NNCore_Tensor实例对象。 + * + * 该接口创建一个OH_NNCore_Tensor实例对象,同时申请对应后端的数据内存。backendName表示所选择的后端名称,可以为空指针,如果为空指针,默认使用第0个后端。 + * desc必须提供,如果为空指针,接口返回错误码。该接口根据desc中的OH_NNCore_GetTensorDescByteSize获取字节数,并创建对应大小的内存。 + * + * @param backendName 后端名称,可以为空指针,如果为空指针,默认使用当前后端列表中的第0个后端。 + * @param desc 指向OH_NNCore_TensorDesc对象的指针,保存各种Tensor描述信息。 + * @return 指向OH_NNCore_Tensor对象的指针。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_Tensor* OH_NNCore_CreateTensor(const char* backendName, OH_NNCore_TensorDesc* desc); + +/** + * @brief 创建OH_NNCore_Tensor实例对象。 + * + * 该接口创建一个OH_NNCore_Tensor实例对象,同时申请对应后端的数据内存。backendName表示所选择的后端名称,可以为空指针,如果为空指针,默认使用第0个后端。 + * desc必须提供,如果为空指针,接口返回错误码。该接口根据传入的参数size创建对应大小的内存。 + * + * @param backendName 后端名称,可以为空指针,如果为空指针,默认使用当前后端列表中的第0个后端。 + * @param desc 指向OH_NNCore_TensorDesc对象的指针,保存各种Tensor描述信息。 + * @param size 需要创建的数据内存大小。 + * @return 指向OH_NNCore_Tensor对象的指针。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_Tensor* OH_NNCore_CreateTensorWithSize(const char* backendName, + OH_NNCore_TensorDesc* desc, + size_t size); + +/** + * @brief 创建OH_NNCore_Tensor实例对象。 + * + * 该接口创建一个OH_NNCore_Tensor实例对象,同时复用用户传入的fd对应的内存。backendName表示所选择的后端名称,可以为空指针,如果为空指针,默认使用第0个后端。 + * desc必须提供,如果为空指针,接口返回错误码。该接口会判断用户传入的fd可用内存(size-offset)必须大于等于desc中的OH_NNCore_GetTensorDescByteSize获取字节数。 + * 该fd必须是之前通过OH_NNCore_CreateTensor或OH_NNCore_CreateTensorWithSize接口创建的内存。 + * + * @param backendName 后端名称,可以为空指针,如果为空指针,默认使用当前后端列表中的第0个后端。 + * @param desc 指向OH_NNCore_TensorDesc对象的指针,保存各种Tensor描述信息。 + * @param fd 内存描述符。 + * @param size 内存大小。 + * @param offset 内存偏移。 + * @return 指向OH_NNCore_Tensor对象的指针。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_Tensor* OH_NNCore_CreateTensorWithFd(const char* backendName, + OH_NNCore_TensorDesc* desc, + int fd, + size_t size, + size_t offset); + +OH_NNCore_ReturnCode OH_NNCore_DestroyTensor(OH_NNCore_Tensor** tensor); + +OH_NNCore_TensorDesc* OH_NNCore_GetTensorDesc(const OH_NNCore_Tensor* tensor); + +void* OH_NNCore_GetDataBuffer(const OH_NNCore_Tensor* tensor); + +OH_NNCore_ReturnCode OH_NNCore_GetSize(const OH_NNCore_Tensor* tensor, size_t* size); + +OH_NNCore_ReturnCode OH_NNCore_GetFd(const OH_NNCore_Tensor* tensor, int* fd); + +OH_NNCore_ReturnCode OH_NNCore_GetOffset(const OH_NNCore_Tensor* tensor, size_t* offset); + +/** + * @brief 创建OH_NNCore_Executor实例对象。 + * + * 该接口可以从compiled对象中创建出模型执行器,然后调用OH_NNCore_ExecutorRunSync或者OH_NNCore_ExecutorRunAsync接口执行推理。 + * 如果compiled是空指针,则无法创建OH_NNCore_Executor对象,接口返回空指针。 + * + * 当创建好OH_NNCore_Executor实例后, 如不需要再执行推理,调用OH_NNCore_DestroyExecutor接口释放OH_NNCore_Executor对象。 + * + * @param compiled 指向OH_NNCore_Compiled对象的指针。 + * @return 指向OH_NNCore_Executor对象的指针。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_Executor* OH_NNCore_ConstructExecutor(const OH_NNCore_Compiled* compiled); + +/** + * @brief 销毁OH_NNCore_Executor实例对象。 + * + * 当推理完成后,不需要再执行推理时,调用该接口销毁OH_NNCore_ConstructExecutor创建的OH_NNCore_Executor实例对象。 + * 如果不调用该接口销毁OH_NNCore_Executor实例对象,会造成内存泄漏。 + * + * 如果executor或*executor是空指针, 接口会返回错误码。 + * + * @param executor 指向OH_NNCore_Executor的二级指针。 + * @return 返回函数执行结果状态码。如果执行成功,返回OH_NNCORE_SUCCESS,否则返回其它类型错误码OH_NNCore_ReturnCode。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_DestroyExecutor(OH_NNCore_Executor** executor); + +/** + * @brief + * + * + * + * 如果executor或者onRunDone是空指针, 接口会返回错误码。 + * + * @param executor 指向OH_NNCore_Executor对象的指针。 + * @param onRunDone 指向OH_NNCore_OnRunDone的函数指针。 + * @return 返回函数执行结果状态码。如果执行成功,返回OH_NNCORE_SUCCESS,否则返回其它类型错误码OH_NNCore_ReturnCode。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_SetExecutorOnRunDone(OH_NNCore_Executor* executor, OH_NNCore_OnRunDone onRunDone); + +/** + * @brief + * + * + * + * 如果executor或者onRunDone是空指针, 接口会返回错误码。 + * + * @param executor 指向OH_NNCore_Executor对象的指针。 + * @param onServiceDied 指向OH_NNCore_OnServiceDied的函数指针。 + * @return 返回函数执行结果状态码。如果执行成功,返回OH_NNCORE_SUCCESS,否则返回其它类型错误码OH_NNCore_ReturnCode。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_SetExecutorOnServiceDied(OH_NNCore_Executor* executor, + OH_NNCore_OnServiceDied onServiceDied); + +/** + * @brief 执行模型同步推理 + * + * 根据给定的输入inputTensor执行模型同步推理,执行结果存放在给定的输出outputTensor中。 + * + * 如果executor是空指针, 接口会返回错误码。 + * + * @param executor 指向OH_NNCore_Executor对象的指针。 + * @param inputTensor 指向OH_NNCore_Tensor的指针数组。 + * @param inputSize 表示上面inputTensor数组长度。 + * @param outputTensor 指向OH_NNCore_Tensor的指针数组。 + * @param outputSize 表示上面outputTensor数组长度。 + * @return 返回函数执行结果状态码。如果执行成功,返回OH_NNCORE_SUCCESS,否则返回其它类型错误码OH_NNCore_ReturnCode。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_ExecutorRunSync(OH_NNCore_Executor* executor, + OH_NNCore_Tensor* inputTensor[], + size_t inputNum, + OH_NNCore_Tensor* outputTensor[], + size_t outputNum); + +/** + * @brief 执行模型异步推理 + * + * 根据给定的输入inputTensor执行模型异步推理,执行结果存放在给定的输出outputTensor中。 + * + * 如果executor是空指针, 接口会返回错误码。 + * + * @param executor 指向OH_NNCore_Executor对象的指针。 + * @param inputTensor 指向OH_NNCore_Tensor的指针数组。 + * @param inputSize 表示上面inputTensor数组长度。 + * @param outputTensor 指向OH_NNCore_Tensor的指针数组。 + * @param outputSize 表示上面outputTensor数组长度。 + * @param timeout + * @param userData + * @return 返回函数执行结果状态码。如果执行成功,返回OH_NNCORE_SUCCESS,否则返回其它类型错误码OH_NNCore_ReturnCode。 + * @since 11 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNCore_ExecutorRunAsync(OH_NNCore_Executor* executor, + OH_NNCore_Tensor* inputTensor[], + size_t inputNum, + OH_NNCore_Tensor* outputTensor[], + size_t outputNum, + int32_t timeout, + void* userData); + +OH_NNCore_Options* OH_NNCore_CreateOptions(const char* backendName); + +OH_NNCore_ReturnCode OH_NNCore_DestroyOptions(OH_NNCore_Options** options); + +OH_NNCore_ReturnCode OH_NNCore_SetPriority(OH_NNCore_Options* options, OH_NNCore_Priority priority); + +OH_NNCore_ReturnCode OH_NNCore_SetPerformanceMode(OH_NNCore_Options* options, + OH_NNCore_PerformanceMode performanceMode); + +OH_NNCore_ReturnCode OH_NNCore_SetEnableFloat16(OH_NNCore_Options* options, bool enableFloat16); + +#ifdef __cplusplus +} +#endif // __cplusplus +#endif // NEURAL_NETWORK_CORE_API_H diff --git a/interfaces/kits/c/v2_0/neural_network_core_type.h b/interfaces/kits/c/v2_0/neural_network_core_type.h new file mode 100644 index 0000000000000000000000000000000000000000..672764749ea48081ff5845770b3520fcc2e91514 --- /dev/null +++ b/interfaces/kits/c/v2_0/neural_network_core_type.h @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NEURAL_NETWORK_RUNTIME_CORE_TYPE_H +#define NEURAL_NETWORK_RUNTIME_CORE_TYPE_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct OH_NNCore_TensorDesc OH_NNCore_TensorDesc; +typedef struct OH_NNCore_Compilation OH_NNCore_Compilation; +typedef struct OH_NNCore_Compiled OH_NNCore_Compiled; +typedef struct OH_NNCore_Executor OH_NNCore_Executor; +typedef struct OH_NNCore_Options OH_NNCore_Options; +typedef struct OH_NNCore_Tensor OH_NNCore_Tensor; +typedef void (*OH_NNCore_OnRunDone)(void* OH_NNCore_ReturnCode, void* [], int32_t); +typedef void (*OH_NNCore_OnServiceDied)(void*); + +typedef enum { + /** The tensor arrange data in NCHW format. */ + OH_NNCORE_FORMAT_NCHW = 0, + /** The tensor arrange data in NHWC format. */ + OH_NNCORE_FORMAT_NHWC = 1, + /** The tensor arrange data in ND format. */ + OH_NNCORE_ND = 2, + /** The tensor does not have a specific layout type (such as scalar or vector).*/ + OH_NNCORE_FORMAT_NONE = 99 +} OH_NNCore_Format; + +typedef enum { + /** The operation is successful. */ + OH_NNCORE_SUCCESS = 0, + /** The operation failed. */ + OH_NNCORE_FAILED = 1, + /** Uninitilaized */ + OH_NNCORE_UNINITIALIZED = 2, + /** Invalid parameter. */ + OH_NNCORE_INVALID_PARAMETER = 3, + /** Timeout. */ + OH_NNCORE_TIMEOUT = 4, + /** Unsupported */ + OH_NNCORE_UNSUPPORTED = 5, + /** Memory Exception */ + OH_NNCORE_MEMORY_EXCEPTION = 6, + /** INVALID API */ + OH_NNCORE_INVALID_API = 7, + /** Invalid Pointer */ + OH_NNCORE_INVALID_POINTER = 8, + /** Calculate Exception */ + OH_NNCORE_CALC_EXCEPTION = 9, + /** Invalid File */ + OH_NNCORE_INVALID_FILE = 10, + /** Common Exception*/ + OH_NNCORE_COMM_EXCEPTION = 11, + /** Data Overflow */ + OH_NNCORE_DATA_OVERFLOW = 12, + /** Unavailable Backend */ + OH_NNCORE_UNAVAILABLE_BACKEND = 13, + /** Connect Exception */ + OH_NNCORE_CONNECT_EXCEPTION = 19, + /** Operation Forbidden */ + OH_NNCORE_OPERATION_FORBIDDEN = 20, + /** NULL Pointer */ + OH_NNCORE_NULL_PTR = 21, + /** Invalid Path */ + OH_NNCORE_INVALID_PATH = 22, +} OH_NNCore_ReturnCode; + +typedef enum { + /** uint8 */ + OH_NNCORE_UINT8 = 0, + /** float32 */ + OH_NNCORE_FLOAT32 = 1, + /** float16 */ + OH_NNCORE_FLOAT16 = 2, + /** int32 */ + OH_NNCORE_INT32 = 3, + /** int8 */ + OH_NNCORE_INT8 = 4, + /** int16 */ + OH_NNCORE_INT16 = 5, + /** bool */ + OH_NNCORE_BOOL = 6, + /** int64 */ + OH_NNCORE_INT64 = 7, + /** uint32 */ + OH_NNCORE_UINT32 = 8, + /** double */ + OH_NNCORE_DOUBLE = 9, + /** uint16 */ + OH_NNCORE_UINT16 = 10, + /** uint64 */ + OH_NNCORE_UINT64 = 11, + /** float64 */ + OH_NNCORE_FLOAT64 = 12, + /** Unknown type */ + OH_NNCORE_OTHER_TYPES = 99 +} OH_NNCore_DataType; + +typedef enum { + /** Unknown type */ + OH_NNCORE_UNKNOWN_BACKEND_STATUS = 0, + /** Available */ + OH_NNCORE_AVAILABLE = 1, + /** Busy */ + OH_NNCORE_BUSY = 2, + /** Offline */ + OH_NNCORE_OFFLINE = 3, +} OH_NNCore_BackendStatus; + +/** + * @brief Defines the hardware performance mode. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** No performance mode preference */ + OH_NNCORE_PERFORMANCE_NONE = 0, + /** Low power consumption mode*/ + OH_NNCORE_PERFORMANCE_LOW = 1, + /** Medium performance mode */ + OH_NNCORE_PERFORMANCE_MEDIUM = 2, + /** High performance mode */ + OH_NNCORE_PERFORMANCE_HIGH = 3, + /** Ultimate performance mode */ + OH_NNCORE_PERFORMANCE_EXTREME = 4 +} OH_NNCore_PerformanceMode; + +/** + * @brief Defines the model inference task priority. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** No priority preference */ + OH_NNCORE_PRIORITY_NONE = 0, + /** Low priority */ + OH_NNCORE_PRIORITY_LOW = 1, + /** Medium priority */ + OH_NNCORE_PRIORITY_MEDIUM = 2, + /** High priority */ + OH_NNCORE_PRIORITY_HIGH = 3 +} OH_NNCore_Priority; + +struct OH_NNCore_CompilationOptions { + bool isFp16; + OH_NNCore_PerformanceMode performanceMode; + OH_NNCore_Priority priority; +}; + +#ifdef __cplusplus +} +#endif +#endif // NEURAL_NETWORK_RUNTIME_CORE_TYPE_H diff --git a/interfaces/kits/c/v2_0/neural_network_runtime.h b/interfaces/kits/c/v2_0/neural_network_runtime.h new file mode 100644 index 0000000000000000000000000000000000000000..c72444f21b595a2f5d247508b2163153d7842d2b --- /dev/null +++ b/interfaces/kits/c/v2_0/neural_network_runtime.h @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup NeuralNeworkRuntime + * @{ + * + * @brief 提供Neural Network Runtime加速模型推理的相关接口。 + * + * @Syscap SystemCapability.Ai.NeuralNetworkRuntime + * @since 9 + * @version 2.0 + */ + +/** + * @file neural_network_runtime.h + * + * @brief Neural Network Backend模块的接口定义,通过调用以下接口,完成深度学习模型的构造。 + * + * @library libneural_network_runtime.so + * @since 9 + * @version 2.0 + */ + +#ifndef NEURAL_NETWORK_RUNTIME_H +#define NEURAL_NETWORK_RUNTIME_H + +#include "neural_network_runtime_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief 创建{@link OH_NNBackend_QuantParam}类型的量化参数实例。 + * + * 在需要使用量化张量的场景下,先调用本接口创建量化参数实例。然后调用{@link OH_NNBackend_SetQuantParamScales}、 + * {@link OH_NNBackend_SetQuantParamZeroPoints}和{@link OH_NNBackend_SetQuantParamNumBits}设置量化参数。 + * + * 量化参数实例使用完毕后,需要调用{@link OH_NNBackend_DestroyQuantParam}销毁模型实例,避免内存泄漏。\n + * + * @return 返回一个指向{@link OH_NNBackend_Model}实例的指针。 + * @since 9 + * @version 2.0 + */ +OH_NNBackend_QuantParam* OH_NNBackend_CreateQuantParam(); + +/** + * @brief 释放{@link OH_NNBackend_QuantParam}类型的量化参数实例。 + * + * 调用{@link OH_NNBackend_CreateQuantParam}创建的模型实例需要调用本方法主动释放,否则将造成内存泄漏。\n + * + * 如果quantParam为空指针或者*quantParam为空指针,本方法只打印warning日志,不执行释放逻辑。\n + * + * @param quantParam 指向{@link OH_NNBackend_QuantParam}实例的二级指针。量化参数实例销毁后,本方法将*quantParam主动设置为空指针。 + * @since 9 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_DestroyQuantParam(OH_NNBackend_QuantParam** quantParam); + +/** + * @brief 设置量化参数中的scale参数 + * + * 通过scale指向的数组参数设置scale量化参数,quantNum为scale数组的长度。在per-layer量化的场景下,quantNum通常指定为1, + * 即一个tensor所有通道共享一套量化参数;在per-channel量化场景下,quantNum通常和tensor通道数一致,每个通道使用自己的量化参数。\n + * + * @param quantParam 指向{@link OH_NNBackend_QuantParam}实例的指针。 + * @param scales 指向double数组的指针。 + * @param quantNum doubles数组的长度。 + * @since 9 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_SetQuantParamScales(OH_NNBackend_QuantParam* quantParam, + const double* scales, + size_t quantNum); + +/** + * @brief 设置量化参数中的zero point参数 + * + * 通过zeroPoints指向的数组参数设置zero point量化参数,quantNum为zeroPoints数组的长度。在per-layer量化的场景下,quantNum通常指定为1, + * 即一个tensor所有通道共享一套量化参数;在per-channel量化场景下,quantNum通常和tensor通道数一致,每个通道使用自己的量化参数。\n + * + * @param quantParam 指向{@link OH_NNBackend_QuantParam}实例的指针。 + * @param zeroPoints 指向int32_t数组的指针。 + * @param quantNum int32_t数组的长度。 + * @since 9 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_SetQuantParamZeroPoints(OH_NNBackend_QuantParam* quantParam, + const int32_t* zeroPoints, + size_t quantNum); + +/** + * @brief 设置量化参数中的量化比特位数 + * + * 通过numBits指向的数组参数设置量化的比特位数,quantNum为numBits数组的长度。在per-layer量化的场景下,quantNum通常指定为1, + * 即一个tensor所有通道共享一套量化参数;在per-channel量化场景下,quantNum通常和tensor通道数一致,每个通道使用自己的量化参数。\n + * + * 目前Neural Network Runtime仅支持8位量化。 + * + * @param quantParam 指向{@link OH_NNBackend_QuantParam}实例的指针。 + * @param numBits 指向uint32_t数组的指针。 + * @param quantNum uint32_t数组的长度。 + * @since 9 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_SetQuantParamNumBits(OH_NNBackend_QuantParam* quantParam, + const uint32_t* numBits, + size_t quantNum); + +/** + * @brief 创建{@link OH_NNBackend_Model}类型的模型实例,搭配OH_NNBackend模块提供的其他接口,完成模型实例的构造。 + * + * 在开始构图前,先调用{@link OH_NNBackend_CreateModel}创建模型实例,根据模型的拓扑结构,调用 + * {@link OH_NNBackend_AddTensorToModel}、{@link OH_NNBackend_AddOperationToModel}、 + * {@link OH_NNBackend_SetModelTensorData}、{@link OH_NNBackend_SetModelTensorQuantParam}和 + * {@link OH_NNBackend_SetModelTensorType}等方法,填充模型的数据节点和算子节点;然后调用 + * {@link OH_NNBackend_SpecifyModelInputsAndOutputs}指定模型的输入和输出;当构造完模型的拓扑结构,调用 + * {@link OH_NNBackend_BuildModel}完成模型的构建。\n + * + * 模型实例使用完毕后,需要调用{@link OH_NNBackend_DestroyModel}销毁模型实例,避免内存泄漏。\n + * + * @return 返回一个指向{@link OH_NNBackend_Model}实例的指针。 + * @since 9 + * @version 2.0 + */ +OH_NNBackend_Model* OH_NNBackend_CreateModel(void); + +/** + * @brief 释放模型实例。 + * + * 调用{@link OH_NNBackend_CreateModel}创建的模型实例需要调用本方法主动释放,否则将造成内存泄漏。\n + * + * 如果model为空指针或者*model为空指针,本方法只打印warning日志,不执行释放逻辑。\n + * + * @param model 指向{@link OH_NNBackend_Model}实例的二级指针。模型实例销毁后,本方法将*model主动设置为空指针。 + * @since 9 + * @version 2.0 + */ +void OH_NNBackend_DestroyModel(OH_NNBackend_Model** model); + +/** + * @brief 向模型实例中添加张量 + * + * Neural Network Runtime模型中的数据节点和算子参数均由模型的张量构成。本方法向model实 + * 例中添加张量。张量添加的顺序是模型中记录张量的索引值,{@link OH_NNBackend_SetModelTensorData}、 + * {@link OH_NNBackend_SetModelTensorQuantParam}、{@link OH_NNBackend_SetModelTensorType}、 + * {@link OH_NNBackend_AddOperationToModel}和{@link OH_NNBackend_SpecifyModelInputsAndOutputs} + * 方法将根据该索引值完成相应的功能。\n + * + * Neural Network Runtime支持动态形状输入和输出。在添加动态形状的数据节点时,需要调用{@link OH_NNCore_SetTensorDescShape},将 + * 张量维度信息中支持动态变化的维度设置为-1。例如:一个4维张量,将张量形状设置为[1, -1, 2, 2],表示其第二个维度支持 + * 动态变化。\n + * + * @param model 指向{@link OH_NNBackend_Model}实例的指针。 + * @param tensor {@link OH_NNCore_TensorDesc}张量的指针,tensor指定了添加到模型实例中张量的属性。 + * @return 函数执行的结果状态。执行成功返回OH_NNCORE_SUCCESS;失败返回具体错误码,具体失败错误码可参考{@link OH_NNCore_ReturnCode}。 + * @since 9 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_AddTensorToModel(OH_NNBackend_Model* model, const OH_NNCore_TensorDesc* tensorDesc); + +/** + * @brief 设置张量的数值 + * + * 对于具有常量值的张量(如模型的权重),需要在构图阶段使用本方法设置数值。张量的索引值根据张量添加进模型的顺序决定,张量的添加参考 + * {@link OH_NNBackend_AddTensorToModel}。\n + * + * @param model 指向{@link OH_NNBackend_Model}实例的指针。 + * @param index 张量的索引值。 + * @param dataBuffer 指向真实数据的指针。 + * @param length 数据缓冲区的长度。 + * @return 函数执行的结果状态。执行成功返回OH_NNCORE_SUCCESS;失败返回具体错误码,具体失败错误码可参考{@link OH_NNCore_ReturnCode}。 + * @since 9 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_SetModelTensorData(OH_NNBackend_Model* model, + size_t index, + const void* dataBuffer, + size_t length); + +/** + * @brief 设置张量的量化参数 + * + * 如果想调用加速芯片的量化推理能力,则需要在构图阶段使用本方法设置量化参数。张量的索引值根据张量添加进模型的顺序决定,张量的添加参考 + * {@link OH_NNBackend_AddTensorToModel}。\n + * + * @param model 指向{@link OH_NNBackend_Model}实例的指针。 + * @param index 张量的索引值。 + * @param param 指向{@link OH_NNBackend_QuantParam}量化参数的指针。 + * @return 函数执行的结果状态。执行成功返回OH_NNCORE_SUCCESS;失败返回具体错误码,具体失败错误码可参考{@link OH_NNCore_ReturnCode}。 + * @since 9 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_SetModelTensorQuantParam(OH_NNBackend_Model* model, + size_t index, + OH_NNBackend_QuantParam* param); + +/** + * @brief 设置张量的类型 + * + * 添加到深度学习模型中的张量需要指定其类型,例如:当张量用作模型中的输入、输出时,则要求type置为{@link OH_NNCORE_TENSOR}; + * 当张量用作算子参数时,则需要指定为具体的枚举值,具体参考{@link OH_NNBackend_OperationType}。 + * 张量的索引值根据张量添加进模型的顺序决定,张量的添加参考{@link OH_NNBackend_AddTensorToModel}。\n + * + * @param model 指向{@link OH_NNBackend_Model}实例的指针。 + * @param index 张量的索引值。 + * @param type 张量的类型。 + * @return 函数执行的结果状态。执行成功返回OH_NNCORE_SUCCESS;失败返回具体错误码,具体失败错误码可参考{@link OH_NNCore_ReturnCode}。 + * @since 9 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_SetModelTensorType(OH_NNBackend_Model* model, + size_t index, + OH_NNBackend_TensorType type); + +/** + * @brief 向模型实例中添加算子 + * + * 本方法向模型实例中添加算子,算子类型由operationType指定,算子的参数、输入和输出由paramIndices、inputIndices和 + * outputIndices指定。本方法将对算子参数的属性和输入输出的数量进行校验,这些属性需要在调用 + * {@link OH_NNBackend_AddTensorToModel}添加张量的时候正确设置。每个算子期望的参数、输入和输出属性请参考 + * {@link OH_NNBackend_OperationType}中,每个算子的详细描述。\n + * + * paramIndices、inputIndices和outputIndices中存储的是张量的索引值,每个索引值根据张量添加进模型的顺序决定,正确 + * 设置并添加算子要求准确设置每个张量的索引值。张量的添加参考{@link OH_NNModel_AddTensor}。\n + * + * 如果添加算子时,添加了额外的参数(非算子需要的参数),本方法返回{@link OH_NNCORE_INVALID_PARAMETER};如果没有设置算子参数, + * 则算子按默认值设置缺省的参数,默认值请参考{@link OH_NNBackend_OperationType}中,相关算子的详细描述。\n + * + * @param model 指向{@link OH_NNBackend_Model}实例的指针。 + * @param op 指定添加的算子类型,取值请参考{@link OH_NNBackend_OperationType}的枚举值。 + * @param paramIndices OH_NNBackend_Array实例的指针,设置算子的参数,指针指向的数组元素要求是{@link OH_NNCORE_UINT32}类型,否则会返回{@link OH_NNCORE_INVALID_PARAMETER}。 + * @param inputIndices OH_NNBackend_Array实例的指针,指定算子的输入,指针指向的数组元素要求是{@link OH_NNCORE_UINT32}类型,否则会返回{@link OH_NNCORE_INVALID_PARAMETER}。 + * @param outputIndices OH_NNBackend_Array实例的指针,设置算子的输出,指针指向的数组元素要求是{@link OH_NNCORE_UINT32}类型,否则会返回{@link OH_NNCORE_INVALID_PARAMETER}。 + * @return 函数执行的结果状态。执行成功返回OH_NNCORE_SUCCESS;失败返回具体错误码,具体失败错误码可参考{@link OH_NNCore_ReturnCode}。 + * @since 9 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_AddOperationToModel(OH_NNBackend_Model* model, + OH_NNBackend_OperationType operationType, + const OH_NNBackend_Array* paramIndices, + const OH_NNBackend_Array* inputIndices, + const OH_NNBackend_Array* outputIndices); + +/** + * @brief 指定模型的输入输出 + * + * 模型实例需要指定张量作为端到端的输入和输出,设置为输入和输出的张量不能使用{@link OH_NNBackend_SetModelTensorData}设置 + * 数值,需要在执行阶段调用{@link OH_NNCore_GetDataBuffer}的方法设置输入、输出数据。\n + * + * 张量的索引值根据张量添加进模型的顺序决定,张量的添加参考{@link OH_NNBackend_AddTensorToModel}。\n + * + * 暂时不支持异步设置模型输入输出。\n + * + * @param model 指向{@link OH_NNBackend_Model}实例的指针。 + * @param inputIndices OH_NNBackend_Array实例的指针,指定算子的输入。 + * @param outputIndices OH_NNBackend_Array实例的指针,指定算子的输出。 + * @return 函数执行的结果状态。执行成功返回OH_NNCOER_SUCCESS;失败返回具体错误码,具体失败错误码可参考{@link OH_NNCore_ReturnCode}。 + * @since 9 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_SpecifyModelInputsAndOutputs(OH_NNBackend_Model* model, + const OH_NNBackend_Array* inputIndices, + const OH_NNBackend_Array* outputIndices); + +/** + * @brief 完成模型构图 + * + * 完成模型拓扑结构的搭建后,调用本方法指示构图已完成。在调用本方法后,无法进行额外的构图操作,调用 + * {@link OH_NNBackend_AddTensorToModel}、{@link OH_NNBackend_AddOperationToModel}、 + * {@link OH_NNBackend_SetModelTensorData}、{@link OH_NNBackend_SetModelTensorQuantParam}、{@link OH_NNBackend_SetModelTensorType} + * 和{@link OH_NNBackend_SpecifyModelInputsAndOutputs}将返回 + * {@link OH_NNCORE_OPERATION_FORBIDDEN}。\n + * + * 在调用{@link OH_NNBackend_GetModelAvailableOperations}和{@link OH_NNCore_ConstructCompilationWithNNModel} + * 之前,必须先调用本方法完成构图。\n + * + * @param model 指向{@link OH_NNBackend_Model}实例的指针。 + * @return 函数执行的结果状态。执行成功返回OH_NNCORE_SUCCESS;失败返回具体错误码,具体失败错误码可参考{@link OH_NNCore_ReturnCode}。 + * @since 9 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_BuildModel(OH_NNBackend_Model* model); + +/** + * @brief 查询硬件对模型内所有算子的支持情况,通过布尔值序列指示支持情况。 + * + * 查询底层硬件对模型实例内每个算子的支持情况,硬件由backendName指定,结果将通过isSupported指向的数组表示。如果支持第i个算子,则 + * (*isSupported)[i] == true,否则为 false。\n + * + * 本方法成功执行后,(*isSupported)将指向记录算子支持情况的bool数组,数组长度和模型实例的算子数量相等。该数组对应的内存由 + * Neural Network Runtime管理,在模型实例销毁或再次调用本方法后自动销毁。\n + * + * @param model 指向{@link OH_NNModel}实例的指针。 + * @param backendName 指定查询的硬件名称,通过调用{@link OH_NNCore_GetBackendNum}和{@link OH_NNCore_GetBackendName}获取设备名称。 + * @param isSupported 指向bool数组的指针。调用本方法时,要求(*isSupported)为空指针,否则返回 + * {@link OH_NNCORE_INVALID_PARAMETER}。 + * @param opNum 模型实例中算子的数量,对应(*isSupported)数组的长度。 + * @return 函数执行的结果状态。执行成功返回OH_NNCOER_SUCCESS;失败返回具体错误码,具体失败错误码可参考{@link OH_NNCore_ReturnCode}。 + * @since 9 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_GetModelAvailableOperations(OH_NNBackend_Model* model, + const char* backendName, + const bool** isSupported, + uint32_t* opNum); + +/** + * @brief 设置编译后的模型缓存版本。 + * + * 在支持缓存的硬件上,模型在硬件驱动层编译后可以保存为缓存文件,下次编译时直接从缓存文件读取模型,减少重新编译的耗时。本方法接受版本作为参数,根据缓存 + * 路径中和版本的不同情况,本方法采取不同的行为:\n + * + * - 缓存路径指定的目录下没有缓存文件: + * 将编译后的模型缓存到目录下,设置缓存版本等于version。\n + * + * - 缓存路径指定的目录下存在完整的缓存文件,且版本号 == version: + * 读取路径下的缓存文件,传递到底层硬件中转换为可以执行的模型实例。\n + * + * - 缓存路径指定的目录下存在完整的缓存文件,但版本号 < version: + * 路径下的缓存文件需要更新,模型在底层硬件完成编译后,覆写路径下的缓存文件,将版本号更新为version。\n + * + * - 缓存路径指定的目录下存在完整的缓存文件,但版本号 > version: + * 路径下的缓存文件版本高于version,不读取缓存文件,同时返回{@link OH_NNCORE_INVALID_PARAMETER}错误码。\n + * + * - 缓存路径指定的目录下的缓存文件不完整或没有缓存文件的访问权限: + * 返回{@link OH_NNCORE_INVALID_PARAMETER}错误码。\n + * + * - OH_NNCORE_INVALID_PATH + * 返回{@link OH_NNCORE_INVALID_FILE}错误码。\n + * + * @param compilation 指向{@link OH_NNCore_Options}实例的指针。 + * @param version 缓存版本。 + * @return 函数执行的结果状态。执行成功返回OH_NNCORE_SUCCESS;失败返回具体错误码,具体失败错误码可参考{@link OH_NNCore_ReturnCode}。 + * @since 9 + * @version 2.0 + */ +OH_NNCore_ReturnCode OH_NNBackend_SetCacheVersion(OH_NNCore_Options* options, uint32_t version); + +#ifdef __cplusplus +} +#endif // __cplusplus +#endif // NEURAL_NETWORK_RUNTIME_H diff --git a/interfaces/kits/c/v2_0/neural_network_runtime_type.h b/interfaces/kits/c/v2_0/neural_network_runtime_type.h new file mode 100644 index 0000000000000000000000000000000000000000..c131e4dc93887bbbc19f5ff522f2938df21da15c --- /dev/null +++ b/interfaces/kits/c/v2_0/neural_network_runtime_type.h @@ -0,0 +1,1656 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup NeuralNeworkRuntime + * @{ + * + * @brief Provides APIs for accelerating the Neural Network Runtime model inference. + * + * @Syscap SystemCapability.Ai.NeuralNetworkRuntime + * @since 9 + * @version 1.0 + */ + +/** + * @file neural_network_runtime_type.h + * + * @brief Defines the structure and enumeration for Neural Network Runtime. + * + * @library libneural_network_runtime.so + * @since 9 + * @version 1.0 + */ + +#ifndef NEURAL_NETWORK_RUNTIME_TYPE_H +#define NEURAL_NETWORK_RUNTIME_TYPE_H + +#include "v1_0/neural_network_runtime_type_compat.h" +#include "v2_0/neural_network_core_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Defines the handles of models for Neural Network Runtime. + * + * @since 9 + * @version 1.0 + */ +typedef struct OH_NNBackend_Model OH_NNBackend_Model; +//TODO: OH_NNBackend_Model add tensor 备选 +typedef struct OH_NNBackend_Operand OH_NNBackend_Operand; +typedef struct OH_NNBackend_QuantParam OH_NNBackend_QuantParam; + +/** + * @brief Defines error codes for Neural Network Runtime. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** The operation is successful. */ + OH_NNBACKEND_SUCCESS = 0, + /** The operation failed. */ + OH_NNBACKEND_FAILED = 1, + /** Invalid parameter. */ + OH_NNBACKEND_INVALID_PARAMETER = 2, + /** Memory-related error, for example, insufficient memory, memory data copy failure, or memory application failure. */ + OH_NNBACKEND_MEMORY_ERROR = 3, + /** Invalid operation. */ + OH_NNBACKEND_OPERATION_FORBIDDEN = 4, + /** Null pointer exception */ + OH_NNBACKEND_NULL_PTR = 5, + /** Invalid file. */ + OH_NNBACKEND_INVALID_FILE = 6, + /** A hardware error occurs, for example, HDL service crash. */ + OH_NNBACKEND_UNAVALIDABLE_DEVICE = 7, + /** Invalid path. */ + OH_NNBACKEND_INVALID_PATH = 8 +} OH_NNBackend_ReturnCode; + +/** + * @brief Defines activation function types in the fusion operator for Neural Network Runtime. + * + * @since 9 + * @version 1.0 + */ +typedef enum : int8_t { + /** The fusion activation function is not specified. */ + OH_NNBACKEND_FUSED_NONE = 0, + /** Fusion relu activation function */ + OH_NNBACKEND_FUSED_RELU = 1, + /** Fusion relu6 activation function */ + OH_NNBACKEND_FUSED_RELU6 = 2 +} OH_NNBackend_FuseType; + +/** + * @brief Defines the layout type of tensor data. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** The tensor does not have a specific layout type (such as scalar or vector). */ + OH_NNBACKEND_FORMAT_NONE = 0, + /** The tensor arranges data in NCHW format.*/ + OH_NNBACKEND_FORMAT_NCHW = 1, + /** The tensor arranges data in NHWC format.*/ + OH_NNBACKEND_FORMAT_NHWC = 2 +} OH_NNBackend_Format; + +/** + * @brief Defines device types supported by Neural Network Runtime. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** Devices that are not CPU, GPU, or dedicated accelerator*/ + OH_NNBACKEND_OTHERS = 0, + /** CPU device */ + OH_NNBACKEND_CPU = 1, + /** GPU device */ + OH_NNBACKEND_GPU = 2, + /** Dedicated hardware accelerator */ + OH_NNBACKEND_ACCELERATOR = 3, +} OH_NNBackend_DeviceType; + +/** + * @brief Defines tensor data types supported by Neural Network Runtime. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** Unknown type */ + OH_NNBACKEND_UNKNOWN = 0, + /** bool */ + OH_NNBACKEND_BOOL = 1, + /** int8 */ + OH_NNBACKEND_INT8 = 2, + /** int16 */ + OH_NNBACKEND_INT16 = 3, + /** int32 */ + OH_NNBACKEND_INT32 = 4, + /** int64 */ + OH_NNBACKEND_INT64 = 5, + /** uint8 */ + OH_NNBACKEND_UINT8 = 6, + /** uint16 */ + OH_NNBACKEND_UINT16 = 7, + /** uint32 */ + OH_NNBACKEND_UINT32 = 8, + /** uint64 */ + OH_NNBACKEND_UINT64 = 9, + /** float16 */ + OH_NNBACKEND_FLOAT16 = 10, + /** float32 */ + OH_NNBACKEND_FLOAT32 = 11, + /** float64 */ + OH_NNBACKEND_FLOAT64 = 12 +} OH_NNBackend_DataType; + + +/** + * @brief Defines operator types supported by Neural Network Runtime. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** + * Returns the tensor of the sum of the elements corresponding to two input tensors. + * + * Inputs: + * + * * input1: first input tensor, of the Boolean or number type. + * * input2: second input tensor, whose data type must be the same as that of the first tensor. + * + * Parameters: + * + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: sum of input1 and input2. + * The data shape is the same as that of the input after broadcasting, + * and the data type is the same as that of the input with a higher precision. + */ + OH_NNBACKEND_OPS_ADD = 1, + + /** + * Apply 2D average pooling to the input tensor, which now must be in NHWC format. The int8 quantization input is supported. + * + * If the input contains the padMode parameter: + * + * Inputs: + * + * * input: tensor. + * + * Parameters: + * + * * kernelSize indicates the kernel size used to obtain the average value. It is an int array [kernel_height, kernel_width]. + * The first number indicates the kernel height, and the second number indicates the kernel width. + * * strides indicates the distance of kernel moving. The value is an int array [stride_height, stride_width]. + * The first number indicates the moving step in height, and the second number indicates the moving step in width. + * * padMode: padding mode, which is optional. The value is of the int type and can be 0 (same) or 1 (valid). + * The nearest neighbor value is used for padding. + * 0 (same): The height and width of the output are the same as those of the input. + * The total padding quantity is calculated horizontally and vertically and evenly distributed to the top, bottom, left, and right if possible. + * Otherwise, the last additional padding will be completed from the bottom and right. + * 1 (valid): The possible maximum height and width of the output will be returned in case of no padding. Excessive pixels will be discarded. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * If the input contains the padList parameter: + * + * Inputs: + * + * * input: tensor. + * + * Parameters: + * + * * kernelSize indicates the kernel size used to obtain the average value. It is an int array [kernel_height, kernel_width]. + * The first number indicates the kernel height, and the second number indicates the kernel width. + * * strides indicates the distance of kernel moving. The value is an int array [stride_height, stride_width]. + * The first number indicates the moving step in height, and the second number indicates the moving step in width. + * * padList: padding around input. It is an int array [top, bottom, left, right], and the nearest neighbor values are used for padding. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: average pooling result of the input. + */ + OH_NNBACKEND_OPS_AVG_POOL = 2, + + /** + * Batch normalization is performed on a tensor to scale and shift tensor elements, relieving potential covariate shift in a batch of data. + * + * Inputs: + * + * * input: n-dimensional tensor of shape [N, ..., C]. The nth dimension is the number of channels. + * * scale: 1D tensor of the scaling factor used to scale the first normalized tensor. + * * offset: 1D tensor used to move to the first normalized tensor. + * * mean: 1D tensor of the overall mean value. It is used only for inference. In case of training, this parameter must be left empty. + * * variance: 1D tensor used for the overall variance. It is used only for inference. In case of training, this parameter must be left empty. + * + * Parameters: + * + * * epsilon: fixed small additional value. + * + * Outputs: + * + * * output: n-dimensional output tensor whose shape and data type are the same as those of the input. + */ + OH_NNBACKEND_OPS_BATCH_NORM = 3, + + /** + * Divides the batch dimension of a 4D tensor into small blocks by block_shape, and interleaves these blocks back into the spatial dimension. + * + * Parameters: + * + * * input: input tensor. The dimension will be divided into small blocks, and these blocks will be interleaved into the spatial dimension. + * + * Outputs: + * + * * blockSize: size of each block to be interleaved into the spatial dimension. The value is an array [height_block, width_block]. + * * crops: elements truncated from the spatial dimension of the output. The value is a 2D array [[crop0_start, crop0_end], + * [crop1_start, crop1_end]] with the shape of (2, 2). + * + * + * Outputs: + * + * * output. Assume that the shape of input is (n,h,w,c) and the shape of output is (n',h',w',c'): + * n' = n / (block_shape[0] * block_shape[1]) + * h' = h * block_shape[0] - crops[0][0] - crops[0][1] + * w' = w * block_shape[1] - crops[1][0] - crops[1][1] + * c'= c + */ + OH_NNBACKEND_OPS_BATCH_TO_SPACE_ND = 4, + + /** + * Offsets the data in each dimension of the input tensor. + * + * Inputs: + * + * * input: input tensor, which can have two to five dimensions. + * * bias: offset of the number of input dimensions. + * + * Outputs: + * + * * output: sum of the input tensor and the bias in each dimension. + */ + OH_NNBACKEND_OPS_BIAS_ADD = 5, + + /** + * Converts the data type in the input tensor. + * + * Inputs: + * + * * input: input tensor. + * * type: converted data type. + * + * Outputs: + * + * * output: converted tensor. + */ + OH_NNBACKEND_OPS_CAST = 6, + + /** + * Connects tensors in a specified dimension. + * + * Inputs: + * + * * input: N input tensors. + * + * Parameters: + * + * * axis: dimension for connecting tensors. + * + * Outputs: + * + * * output: result of connecting N tensors along the axis. + */ + OH_NNBACKEND_OPS_CONCAT = 7, + + /** + * 2D convolutional layer. + * + * If the input contains the padMode parameter: + * + * Inputs: + * + * * input: input tensor. + * * weight: convolution weight in [outChannel, kernelHeight, kernelWidth, inChannel/group] format. + * The value of inChannel must be exactly divided by the value of group. + * + * * bias: bias of the convolution. It is an array with a length of [outChannel]. + * In quantization scenarios, the bias parameter does not require quantization parameters. + * The quantization version requires data input of the OH_NNBACKEND_INT32 type. + * The actual quantization parameters are determined by input and weight. + * + * Parameters: + * + * * stride: movement stride of the convolution kernel in height and width. It is an int array [strideHeight, strideWidth]. + * * dilation: dilation size of the convolution kernel in height and width. It is an int array [dilationHeight, dilationWidth]. + * The value must be greater than or equal to 1 and cannot exceed the height and width of input. + * + * * padMode: padding mode of input. The value is of the int type and can be 0 (same) or 1 (valid). + * 0 (same): The height and width of the output are the same as those of the input. + * The total padding quantity is calculated horizontally and vertically and evenly distributed to the top, bottom, left, and right if possible. + * Otherwise, the last additional padding will be completed from the bottom and right. + * + * 1 (valid): The possible maximum height and width of the output will be returned in case of no padding. The excessive pixels will be discarded. + * * group: number of groups in which the input is divided by in_channel. The value is of the int type. + * If group is 1, it is a conventional convolution. If group is greater than 1 and + * less than or equal to in_channel, it is a group convolution. + * * activationType is an integer constant which is contained in FuseType. The specified activation function is called before output. + * + * If the input contains the padList parameter: + * + * Inputs: + * + * * input: input tensor. + * * weight: convolution weight in [outChannel, kernelHeight, kernelWidth, inChannel/group] format. + * The value of inChannel must be exactly divided by the value of group. + * + * * bias: bias of the convolution. It is an array with a length of [outChannel]. + * In quantization scenarios, the bias parameter does not require quantization parameters. + * The quantization version requires data input of the OH_NNBACKEND_INT32 type. + * The actual quantization parameters are determined by input and weight. + * + * Parameters: + * + * * stride: movement stride of the convolution kernel in height and width. It is an int array [strideHeight, strideWidth]. + * * dilation: dilation size of the convolution kernel in height and width. It is an int array [dilationHeight, dilationWidth]. + * The value must be greater than or equal to 1 and cannot exceed the height and width of input. + * * padList: padding around input. It is an int array [top, bottom, left, right]. + * * group: number of groups in which the input is divided by in_channel. The value is of the int type. + * If group is 1, it is a conventional convolution. + * If group is in_channel, it is depthwiseConv2d. In this case, group==in_channel==out_channel. + * If group is greater than 1 and less than in_channel, it is a group convolution. In this case, out_channel==group. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: convolution computing result. + */ + OH_NNBACKEND_OPS_CONV2D = 8, + + /** + * 2D convolution transposition. + * + * If the input contains the padMode parameter: + * + * Inputs: + * + * * input: input tensor. + * * weight: convolution weight in [outChannel, kernelHeight, kernelWidth, inChannel/group] format. + * The value of inChannel must be exactly divided by the value of group. + * + * * bias: bias of the convolution. It is an array with a length of [outChannel]. + * In quantization scenarios, the bias parameter does not require quantization parameters. + * The quantization version requires data input of the OH_NNBACKEND_INT32 type. + * The actual quantization parameters are determined by input and weight. + * + * * stride: movement stride of the convolution kernel in height and width. It is an int array [strideHeight, strideWidth]. + * + * Parameters: + * + * * dilation: dilation size of the convolution kernel in height and width. It is an int array [dilationHeight, dilationWidth]. + * The value must be greater than or equal to 1 and cannot exceed the height and width of input. + * * padMode: padding mode of input. The value is of the int type and can be 0 (same) or 1 (valid). + * 0 (same): The height and width of the output are the same as those of the input. + * The total padding quantity is calculated horizontally and vertically and evenly distributed to the top, bottom, left, and right if possible. + * Otherwise, the last additional padding will be completed from the bottom and right. + * 1 (valid): The possible maximum height and width of the output will be returned in case of no padding. The excessive pixels will be discarded. + * * group: number of groups in which the input is divided by in_channel. The value is of the int type. + * If group is 1, it is a conventional convolution. If group is greater than 1 and + * less than or equal to in_channel, it is a group convolution. + * * outputPads: padding along the height and width of the output tensor. The value is an int or a tuple. + * It can be a single integer to specify the same value for all spatial dimensions. The amount of output + * padding along a dimension must be less than the stride along this dimension. + * + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * If the input contains the padList parameter: + * + * Inputs: + * + * * input: input tensor. + * * weight: convolution weight in [outChannel, kernelHeight, kernelWidth, inChannel/group] format. + * The value of inChannel must be exactly divided by the value of group. + * * bias: bias of the convolution. It is an array with a length of [outChannel]. + * In quantization scenarios, the bias parameter does not require quantization parameters. + * The quantization version requires data input of the OH_NNBACKEND_INT32 type. + * The actual quantization parameters are determined by input and weight. + * + * Parameters: + * + * * stride: movement stride of the convolution kernel in height and width. It is an int array [strideHeight, strideWidth]. + * * dilation: dilation size of the convolution kernel in height and width. It is an int array [dilationHeight, dilationWidth]. + * The value must be greater than or equal to 1 and cannot exceed the height and width of input. + * * padList: padding around input. It is an int array [top, bottom, left, right]. + * * group: number of groups in which the input is divided by in_channel. The value is of the int type. + * If group is 1, it is a conventional convolution. If group is greater than 1 + * and less than or equal to in_channel, it is a group convolution. + * * outputPads: padding along the height and width of the output tensor. The value is an int or a tuple. + * It can be a single integer to specify the same value for all spatial dimensions. The amount of output padding + * along a dimension must be less than the stride along this dimension. + * + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: computing result after convolution and transposition. + */ + OH_NNBACKEND_OPS_CONV2D_TRANSPOSE = 9, + + /** + * 2D depthwise separable convolution. + * + * If the input contains the padMode parameter: + * + * Inputs: + * + * * input: input tensor. + * * weight: convolution weight in [outChannel, kernelHeight, kernelWidth, 1] format. + * outChannel is equal to channelMultiplier multiplied by inChannel. + * * bias: bias of the convolution. It is an array with a length of [outChannel]. + * In quantization scenarios, the bias parameter does not require quantization parameters. + * The quantization version requires data input of the OH_NNBACKEND_INT32 type. + * The actual quantization parameters are determined by input and weight. + * + * Parameters: + * + * * stride: movement stride of the convolution kernel in height and width. It is an int array [strideHeight, strideWidth]. + * * dilation: dilation size of the convolution kernel in height and width. It is an int array [dilationHeight, dilationWidth]. + * The value must be greater than or equal to 1 and cannot exceed the height and width of input. + * * padMode: padding mode of input. The value is of the int type and can be 0 (same) or 1 (valid). + * 0 (same): The height and width of the output are the same as those of the input. + * The total padding quantity is calculated horizontally and vertically and evenly distributed to the top, bottom, left, and right if possible. + * Otherwise, the last additional padding will be completed from the bottom and right. + * + * 1 (valid): The possible maximum height and width of the output will be returned in case of no padding. The excessive pixels will be discarded. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * If the input contains the padList parameter: + * + * Inputs: + * + * * input: input tensor. + * * weight: convolution weight in [outChannel, kernelHeight, kernelWidth, 1] format. + * outChannel is equal to channelMultiplier multiplied by inChannel. + * * bias: bias of the convolution. It is an array with a length of [outChannel]. + * In quantization scenarios, the bias parameter does not require quantization parameters. + * The quantization version requires data input of the OH_NNBACKEND_INT32 type. + * The actual quantization parameters are determined by input and weight. + * + * Parameters: + * + * * stride: movement stride of the convolution kernel in height and width. It is an int array [strideHeight, strideWidth]. + * * dilation: dilation size of the convolution kernel in height and width. It is an int array [dilationHeight, dilationWidth]. + * The value must be greater than or equal to 1 and cannot exceed the height and width of input. + * * padList: padding around input. It is an int array [top, bottom, left, right]. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: convolution computing result. + */ + OH_NNBACKEND_OPS_DEPTHWISE_CONV2D_NATIVE = 10, + + /** + * Divides two input scalars or tensors. + * + * Inputs: + * + * * input1: first input, which is a number, a bool, or a tensor whose data type is number or Boolean. + * * input2: second input, which must meet the following requirements: + * If the first input is a tensor, the second input can be a real number, a Boolean value, or a tensor whose data type is real number or Boolean value. + * If the first input is a real number or Boolean value, the second input must be a tensor whose data type is real number or Boolean value. + * + * Parameters: + * + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: result of dividing input1 by input2. + */ + OH_NNBACKEND_OPS_DIV = 11, + + /** + * Sets parameters to perform product (dot product), sum (addition and subtraction), or max (larger value) on the input. + * + * Inputs: + * + * * input1: first input tensor. + * * input2: second input tensor. + * + * Parameters: + * + * * mode: operation mode. The value is an enumerated value. + * + * Outputs: + * + * * output: computing result, which has the same data type and shape of output and input1. + */ + OH_NNBACKEND_OPS_ELTWISE = 12, + + /** + * Adds an additional dimension to a tensor in the given dimension. + * + * Inputs: + * + * * input: input tensor. + * * axis: index of the dimension to be added. The value is of the int32_t type and must be a constant in the range [-dim-1, dim]. + * + * Outputs: + * + * * output: tensor after dimension expansion. + */ + OH_NNBACKEND_OPS_EXPAND_DIMS = 13, + + /** + * Creates a tensor of the specified dimensions and fills it with a scalar. + * + * Inputs: + * + * * value: scalar used to fill the tensor. + * * shape: dimensions of the tensor to be created. + * + * Outputs: + * + * * output: generated tensor, which has the same data type as value. The tensor shape is specified by the shape parameter. + */ + OH_NNBACKEND_OPS_FILL = 14, + + /** + * Full connection. The entire input is used as the feature map for feature extraction. + * + * Inputs: + * + * * input: full-connection input tensor. + * * weight: weight tensor for a full connection. + * * bias: full-connection bias. In quantization scenarios, no quantized parameter is required for this parameter. + * If quantization is required, the data must be of the OH_NNBACKEND_INT32 type. + * The actual quantization parameters are determined by input and weight. + * + * Parameters: + * + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: computed tensor. + * + * If the input contains the axis parameter: + * + * Inputs: + * + * * input: full-connection input tensor. + * * weight: weight tensor for a full connection. + * * bias: full-connection bias. In quantization scenarios, no quantized parameter is required for this parameter. + * If quantization is required, the data must be of the OH_NNBACKEND_INT32 type. The actual quantization parameters + * are determined by input and weight. + * + * Parameters: + * + * * axis: axis in which the full connection is applied. The specified axis and its following axes are + * converted into a 1D tensor for applying the full connection. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: computed tensor. + */ + OH_NNBACKEND_OPS_FULL_CONNECTION = 15, + + /** + * Returns the slice of the input tensor based on the specified index and axis. + * + * Inputs: + * + * * input: tensor to be sliced. + * * inputIndices: indices of the specified input on the axis. The value is an array of the int type + * and must be in the range [0,input.shape[axis]). + * * axis: axis on which input is sliced. The value is an array with one element of the int32_t type. + * + * Outputs: + * + * * output: sliced tensor. + */ + OH_NNBACKEND_OPS_GATHER = 16, + + /** + * Calculate the Hswish activation value of the input. + * + * Inputs: + * + * * An n-dimensional input tensor. + * + * Outputs: + * + * * output: n-dimensional Hswish activation value. The data type is the same as that of shape and input. + */ + OH_NNBACKEND_OPS_HSWISH = 17, + + /** + * For input1 and input2, calculate the result of input1[i]<=input2[i] for each pair of elements, + * where i is the index of each element in the input tensor. + * + * Inputs: + * + * * input1, which can be a real number, Boolean value, or tensor whose data type is real number or NN_BOOL. + * * input2, which can be a real number or a Boolean value if input1 is a tensor and must be a tensor + * with the data type of real number or NN_BOOL if input1 is not a tensor. + * + * Outputs: + * + * * A tensor of the data type NN_BOOL. When a quantization model is used, the quantization parameters of the output + * cannot be omitted. However, values of the quantization parameters do not affect the result. + */ + OH_NNBACKEND_OPS_LESS_EQUAL = 18, + + /** + * Calculate the inner product of input1 and input2. + * + * Inputs: + * + * * input1: n-dimensional input tensor. + * * input2: n-dimensional input tensor. + * + * Parameters: + * + * * TransposeX: Boolean value indicating whether to transpose input1. + * * TransposeY: Boolean value indicating whether to transpose input2. + * + * Outputs: + * + * * output: inner product obtained after calculation. In case of type!=NN_UNKNOWN, the output data type is + * determined by type. In case of type==NN_UNKNOWN, the output data type depends on the data type + * converted during computing of inputX and inputY. + * + */ + OH_NNBACKEND_OPS_MATMUL = 19, + + /** + * Calculates the maximum of input1 and input2 element-wise. The inputs of input1 and input2 + * comply with the implicit type conversion rules to make the data types consistent. * The inputs must be two tensors or one tensor and one scalar. + * When the inputs are two tensors, their data types cannot be both NN_BOOL. Their shapes can be broadcast to the same size. + * When the inputs are one tensor and one scalar, the scalar must be a constant. + * + * Inputs: + * + * * input1: n-dimensional input tensor of the real number or NN_BOOL type. + * * input2: n-dimensional input tensor of the real number or NN_BOOL type. + * + * Outputs: + * + * * output: n-dimensional output tensor. The shape and data type of + * output are the same as those of the two inputs with a higher precision. + */ + OH_NNBACKEND_OPS_MAXIMUM = 20, + + /** + * Applies 2D maximum pooling to the input tensor. + * + * If the input contains the padMode parameter: + * + * Inputs: + * + * * input: tensor. + * + * Parameters: + * + * * kernelSize: kernel size used to obtain the maximum. It is an int array [kernel_height, kernel_width]. + * The first number indicates the kernel height, and the second number indicates the kernel width. + * * strides indicates the distance of kernel moving. The value is an int array [stride_height, stride_width]. + * The first number indicates the moving step in height, and the second number indicates the moving step in width. + * * padMode: padding mode, which is optional. The value is of the int type and can be 0 (same) + * or 1 (valid). The nearest neighbor value is used for padding. + * 0 (same): The height and width of the output are the same as those of the input. + * The total padding quantity is calculated horizontally and vertically and evenly distributed to the top, bottom, left, and right if possible. + * Otherwise, the last additional padding will be completed from the bottom and right. + * 1 (valid): The possible maximum height and width of the output will be returned in case of no padding. The excessive pixels will be discarded. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * If the input contains the padList parameter: + * + * Inputs: + * + * * input: tensor. + * + * Parameters: + * + * * kernelSize: kernel size used to obtain the maximum. It is an int array [kernel_height, kernel_width]. + * The first number indicates the kernel height, and the second number indicates the kernel width. + * * strides indicates the distance of kernel moving. The value is an int array [stride_height, stride_width]. + * The first number indicates the moving step in height, and the second number indicates the moving step in width. + * * padList: padding around input. It is an int array [top, bottom, left, right], + * and the nearest neighbor values are used for padding. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: tensor obtained after maximum pooling is applied to the input. + */ + OH_NNBACKEND_OPS_MAX_POOL = 21, + + /** + * Multiplies elements in the same positions of inputX and inputY to obtain the output. + * If inputX and inputY have different shapes, expand them to the same shape + * through broadcast and then perform multiplication. + * + * Inputs: + * + * * input1: n-dimensional tensor. + * * input2: n-dimensional tensor. + * + * Parameters: + * + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * Product of each element of input1 and input2. + */ + OH_NNBACKEND_OPS_MUL = 22, + + /** + * Generates a one-hot tensor based on the positions specified by indices. The positions specified by indices + * are determined by on_value, and other positions are determined by off_value. + * + * Inputs: + * + * * indices: n-dimensional tensor. Each element in indices determines the position of + * on_value in each one-hot vector. + * * depth: integer scalar that determines the depth of the one-hot vector. The value of depth + * must be greater than 0. + * * on_value: scalar that specifies a valid value in the one-hot vector. + * * off_value: scalar that specifies the values of other posistions in the one-hot vector except the valid value. + * + * Parameters: + * + * * axis: integer scalar that specifies the dimension for inserting the one-hot. Assume that the shape + * of indices is [N, C], and the value of depth is D. + * When axis is 0, the shape of the output is [D, N, C]. + * When axis is -1, the shape of the output is [N, C, D]. + * When axis is 1, the shape of the output is [N, D, C]. + * + * Outputs: + * + * * output: (n+1)-dimensional tensor if indices is an n-dimensional tensor. + * The output shape is determined by indices and axis. + */ + OH_NNBACKEND_OPS_ONE_HOT = 23, + + /** + * Pads inputX in the specified dimensions. + * + * Inputs: + * + * * inputX: n-dimensional tensor in [BatchSize, ...] format. + * * paddings: 2D tensor that specifies the length to pad in each dimension. The shape is [n, 2]. + * For example, paddings[i][0] indicates the number of paddings to be added preceding inputX in the ith dimension. + * paddings[i][1] indicates the number of paddings to be added following inputX in the ith dimension. + * + * Parameters: + * + * * padValues: value to be added to the pad operation. The value is a constant with the same data type as inputX. + * + * Outputs: + * + * * output: n-dimensional tensor after padding, with the same dimensions and data type as inputX. + * The shape is determined by inputX and paddings. + * output.shape[i] = input.shape[i] + paddings[i][0]+paddings[i][1] + */ + OH_NNBACKEND_OPS_PAD = 24, + + /** + * Calculates the y power of each element in input. The inputs must be two tensors or one tensor and one scalar. + * When the inputs are two tensors, their data types cannot be both NN_BOOL, and their shapes must be the same. + * When the inputs are one tensor and one scalar, the scalar must be a constant. + * + * Inputs: + * + * * input: real number, Boolean value, or tensor whose data type is real number or NN_BOOL. + * * y: real number, Boolean value, or tensor whose data type is real number or NN_BOOL. + * + * Outputs: + * + * * output: tensor, whose shape is determined by the shape of input and y after broadcasting. + */ + OH_NNBACKEND_OPS_POW = 25, + + /** + * Scales a tensor. + * + * Inputs: + * + * * input: n-dimensional tensor. + * * scale: scaling tensor. + * * bias: bias tensor. + * + * Parameters: + * + * * axis: dimensions to be scaled. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: scaled n-dimensional tensor, whose data type is the same as that of input and + * shape is determined by axis. + */ + OH_NNBACKEND_OPS_SCALE = 26, + + /** + * Calculates the shape of the input tensor. + * + * Inputs: + * + * * input: n-dimensional tensor. + * + * Outputs: + * + * * output: integer array representing the dimensions of the input tensor. + */ + OH_NNBACKEND_OPS_SHAPE = 27, + + /** + * Applies the sigmoid operation to the input tensor. + * + * Inputs: + * + * * input: n-dimensional tensor. + * + * Outputs: + * + * * output: result of the sigmoid operation. It is an n-dimensional tensor + * with the same data type and shape as input. + */ + OH_NNBACKEND_OPS_SIGMOID = 28, + + /** + * Slices a tensor of the specified size from the input in each dimension. + * + * Inputs: + * + * * input: n-dimensional input tensor. + * * begin: start of the slice, which is an array of integers greater than or equal to 0. + * * size: slice length, which is an array of integers greater than or equal to 0. + * Assume that a dimension is i and 1<=size[i]<=input.shape[i]-begin[i]. + * + * Outputs: + * + * * output: n-dimensional tensor obtained by slicing. + * The TensorType, shape, and size of the output are the same as those of the input. + */ + OH_NNBACKEND_OPS_SLICE = 29, + + /** + * Applies the softmax operation to the input tensor. + * + * Inputs: + * + * * input: n-dimensional input tensor. + * + * Parameters: + * + * * axis: dimension in which the softmax operation is performed. + * The value is of the int64 type. It is an integer in the range [-n, n). + * + * Outputs: + * + * * output: result of the softmax operation. It is an n-dimensional tensor with + * the same data type and shape as input. + */ + OH_NNBACKEND_OPS_SOFTMAX = 30, + + /** + * Divides a 4D tensor into small blocks and combines these blocks in the original batch. + * The number of blocks is blockShape[0] multiplied by blockShape[1]. + * + * Inputs: + * + * * input: 4D tensor. + * + * Parameters: + * + * * blockShape: a pair of integers. Each of them is greater than or equal to 1. + * * paddings: a pair of arrays. Each of them consists of two integers. The four integers that form paddings + * must be greater than or equal to 0. paddings[0][0] and paddings[0][1] + * specify the number of paddings in the third dimension, and paddings[1][0] and paddings[1][1] + * specify the number of paddings in the fourth dimension. + * + * Outputs: + * + * * output: 4D tensor with the same data type as input. The shape is determined by input, + * blockShape, and paddings. Assume that the input shape is [n,c,h,w], then: + * output.shape[0] = n * blockShape[0] * blockShape[1] + * output.shape[1] = c + * output.shape[2] = (h + paddings[0][0] + paddings[0][1]) / blockShape[0] + * output.shape[3] = (w + paddings[1][0] + paddings[1][1]) / blockShape[1] + * (h + paddings[0][0] + paddings[0][1]) and (w + paddings[1][0] + paddings[1][1]) is exactly divisible by + * (h + paddings[0][0] + paddings[0][1]) and (w + paddings[1][0] + paddings[1][1]). + * + */ + OH_NNBACKEND_OPS_SPACE_TO_BATCH_ND = 31, + + /** + * Splits the input into multiple tensors along the axis dimension. The number of tensors is specified by outputNum. + * + * Inputs: + * + * * input: n-dimensional tensor. + * + * Parameters: + * + * * outputNum: number of output tensors. The data type is long. + * * size_splits: size of each tensor split from the input. The value is a 1D tensor of the int type. + * If size_splits is empty, the input will be evenly split into tensors of the same size. In this case, + * input.shape[axis] can be exactly divisible by outputNum. + * If size_splits is not empty, the sum of all its elements must be equal to input.shape[axis]. + * * axis: splitting dimension of the int type. + * + * Outputs: + * + * * outputs: array of n-dimensional tensors, with the same data type and dimensions. + * The data type of each tensor is the same as that of input. + */ + OH_NNBACKEND_OPS_SPLIT = 32, + + /** + * Calculates the square root of a tensor. + * + * Inputs: + * + * * input: n-dimensional tensor. + * + * Outputs: + * + * * output: square root of the input. It is an n-dimensional tensor with the same data type and shape as input. + */ + OH_NNBACKEND_OPS_SQRT = 33, + + /** + * Calculates the square of the difference between two tensors. The SquaredDifference operator supports tensor and tensor subtraction. + * If two tensors have different TensorTypes, the Sub operator converts the low-precision tensor to a high-precision one. + * If two tensors have different shapes, the two tensors can be extended to tensors with the same shape through broadcast. + * + * Inputs: + * + * * input1: minuend, which is a tensor of the NN_FLOAT16, NN_FLOAT32, NN_INT32, or NN_BOOL type. + * * input2: subtrahend, which is a tensor of the NN_FLOAT16, NN_FLOAT32, NN_INT32, or NN_BOOL type. + * + * Outputs: + * + * * output: square of the difference between two inputs. The output shape is determined + * byinput1 and input2. If they have the same shape, the output tensor has the same shape as them. + * If they have different shapes, perform the broadcast operation on input1 and input2 and perform subtraction. + * TensorType of the output is the same as that of the input tensor with higher precision. + */ + OH_NNBACKEND_OPS_SQUARED_DIFFERENCE = 34, + + /** + * Removes the dimension with a length of 1 from the specified axis. The int8 quantization input is supported. + * Assume that the input shape is [2, 1, 1, 2, 2] and axis is [0,1], the output shape is [2, 1, 2, 2], + * which means the dimension whose length is 0 between dimensions 0 and dimension 1 is removed. + * + * Inputs: + * + * * input: n-dimensional tensor. + * + * Parameters: + * + * * axis: dimension to be removed. The value is of int64_t type and can be an integer in the range [-n, n) or an array. + * + * Outputs: + * + * * output: output tensor. + */ + OH_NNBACKEND_OPS_SQUEEZE = 35, + + /** + * Stacks multiple tensors along the specified axis. If each tensor has n dimensions before stacking, + * the output tensor will have n+1 dimensions. + * + * Inputs: + * + * * input: input for stacking, which can contain multiple n-dimensional tensors. + * Each of them must have the same shape and type. + * + * Parameters: + * + * * axis: dimension for tensor stacking, which is an integer. The value range is [-(n+1),(n+1)), + * which means a negative number is allowed. + * + * Outputs: + * + * * output: stacking result of the input along the axis dimension. The value is an n+1-dimensional tensor + * and has the same TensorType as the input. + */ + OH_NNBACKEND_OPS_STACK = 36, + + /** + * Slices a tensor with the specified stride. + * + * Inputs: + * + * * input: n-dimensional input tensor. + * * begin: start of slicing, which is a 1D tensor. The length of begin is n. + * begin[i] specifies the start of slicing in the ith dimension. + * * end: end of slicing, which is a 1D tensor. The length of end is n. + * end[i] specifies the end of slicing in the ith dimension. + * * strides: slicing stride, which is a 1D tensor. The length of strides is n. + * strides[i] specifies the stride at which the tensor is sliced in the ith dimension. + * + * Parameters: + * + * * beginMask: an integer used to mask begin. beginMask is represented in binary code. + * In case of binary(beginMask)[i]==1, for the ith dimension, elements are sliced from the first element + * at strides[i] until the end[i]-1 element. + * + * * endMask: an integer used to mask end. endMask is represented in binary code. + * In case of binary(endMask)[i]==1, elements are sliced from the element at the begin[i] position + * in the ith dimension until the tensor boundary at strides[i]. + * + * * ellipsisMask: integer used to mask begin and end. ellipsisMask is represented in binary code. + * In case of binary(ellipsisMask)[i]==1, elements are sliced from the first element at strides[i] in the ith dimension + * until the tensor boundary. Only one bit of binary(ellipsisMask) can be a non-zero value. + * + * * newAxisMask: new dimension, which is an integer. newAxisMask is represented in binary code. + * In case of binary(newAxisMask)[i]==1, a new dimension whose length is 1 is inserted into the ith dimension. + * * shrinkAxisMask: shrinking dimension, which is an integer. * shrinkAxisMask is represented in binary code. + * In the case of binary(shrinkAxisMask)[i]==1, all elements in the ith dimension will be discarded, + * and the length of the ith dimension is shrunk to 1. + * + * Outputs: + * + * * A tensor, with the same data type as input. The number of dimensions of the output tensor is rank(input[0])+1. + */ + OH_NNBACKEND_OPS_STRIDED_SLICE = 37, + + /** + * Calculates the difference between two tensors. + * + * Inputs: + * + * * input1: minuend, which is a tensor. + * * input2: subtrahend, which is a tensor. + * + * Parameters: + * + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: difference between the two tensors. The output shape is determined byinput1 and input2. + * If they have the same shape, the output tensor has the same shape as them. + * If they have different shapes, perform the broadcast operation on input1 and input2 and perform subtraction. + * TensorType of the output is the same as that of the input tensor with higher precision. + */ + OH_NNBACKEND_OPS_SUB = 38, + + /** + * Computes hyperbolic tangent of the input tensor. + * + * Inputs: + * + * * input: n-dimensional tensor. + * + * Outputs: + * + * * output: hyperbolic tangent of the input. The TensorType and tensor shape are the same as those of the input. + */ + OH_NNBACKEND_OPS_TANH = 39, + + /** + * Copies a tensor the specified times. + * + * Inputs: + * * input: n-dimensional tensor. + * * multiples: number of times that the input tensor is copied in each dimension. The value is a 1D tensor. + * The length m is not less than the number of dimensions, that is, n. + * + * Outputs: + * * An m-dimensional tensor whose TensorType is the same as that of the input. If input and + * multiples have the same length, input and output have the same number of dimensions. + * If the length of multiples is greater than n, 1 is used to fill the input dimension, + * and then the input is copied in each dimension the specified times to obtain the m-dimensional tensor. + */ + OH_NNBACKEND_OPS_TILE = 40, + + /** + * Transposes data of input 0 based on permutation. + * + * Inputs: + * + * * input: n-dimensional tensor to be transposed. + * * permutation: The value is a 1D tensor whose length is the same as the number of dimensions of input 0. + * + * Outputs: + * + * * output: n-dimensional tensor. TensorType of output 0 is the same as that of input 0, + * and the output shape is determined by the shape and permutation of input 0. + */ + OH_NNBACKEND_OPS_TRANSPOSE = 41, + + /** + * Calculates the average value in the specified dimension. If keepDims is set to false, the number of dimensions + * is reduced for the input; if keepDims is set to true, the number of dimensions is retained. + * + * Inputs: + * + * * input: n-dimensional input tensor, where n is less than 8. + * * axis: dimension used to calculate the average value. The value is a 1D tensor. The value range of each element in axis is [–n, n). + * + * Parameters: + * + * * keepDims: indicates whether to retain the dimension. The value is a Boolean value. + * + * Outputs: + * + * * output: m-dimensional output tensor whose data type is the same as that of the input. If keepDims is + * false, m==n. If keepDims is true, minput: 4D input tensor. Each element in the input cannot be less than 0. The input layout must be [batchSize, height, width, channels]. + * + * Parameters: + * + * * newHeight: resized height of the 4D tensor. + * * newWidth: resized width of the 4D tensor. + * * preserveAspectRatio: indicates whether to maintain the height/width ratio of input after resizing. + * * coordinateTransformMode: coordinate transformation method used by the resize operation. The value is an int32 integer. + * Currently, the following methods are supported: + * * excludeOutside: an int64 floating point number. When its value is 1, the sampling weight of the part that + * exceeds the boundary of input is set to 0, and other weights are normalized. + * + * Outputs: + * + * * output: n-dimensional tensor, with the same shape and data type as input. + */ + OH_NNBACKEND_OPS_RESIZE_BILINEAR = 43, + + /** + * Calculates the reciprocal of the square root of a tensor. + * + * Inputs: + * + * * input: n-dimensional tensor, where n is less than 8. Each element of the tensor cannot be less than 0. + * + * Outputs: + * + * * output: n-dimensional tensor, with the same shape and data type as input. + */ + OH_NNBACKEND_OPS_RSQRT = 44, + + /** + * Reshapes a tensor. + * + * Inputs: + * + * * input: n-dimensional input tensor. + * * InputShape: shape of the output tensor. The value is a 1D constant tensor. + * + * Outputs: + * + * * output: tensor whose data type is the same as that of input and shape is determined by InputShape. + */ + OH_NNBACKEND_OPS_RESHAPE = 45, + + /** + * Calculates the PReLU activation value of input and weight. + * + * Inputs: + * + * * input: n-dimensional tensor. If n is greater than or equal to 2, inputX must be [BatchSize, ..., Channels]. + * The second dimension is the number of channels. + * * weight: 1D tensor. The length of weight must be 1 or equal to the number of channels. If the length of weight is 1, + * all channels share the same weight. + * If the length of weight is equal to the number of channels, each channel exclusively has a weight. + * If n is less than 2 for inputX, the weight length must be 1. + * + * Outputs: + * + * * output: PReLU activation value of x, with the same shape and data type as inputX. + */ + OH_NNBACKEND_OPS_PRELU = 46, + + /** + * Calculates the Relu activation value of input. + * + * Inputs: + * + * * input: n-dimensional input tensor. + * + * Outputs: + * + * * output: n-dimensional tensor, with the same data type and shape as the input tensor. + */ + OH_NNBACKEND_OPS_RELU = 47, + + /** + * Calculates the Relu6 activation value of the input, that is, calculate min(max(x, 0), 6) for each element x in the input. + * + * Inputs: + * + * * input: n-dimensional input tensor. + * + * Outputs: + * + * * output: n-dimensional Relu6 tensor, with the same data type and shape as the input tensor. + */ + OH_NNBACKEND_OPS_RELU6 = 48, + + /** + * Applies layer normalization for a tensor from the specified axis. + * + * Inputs: + * + * * input: n-dimensional input tensor. + * * gamma: m-dimensional tensor. The dimensions of gamma must be the same as + * the shape of the part of the input tensor to normalize. + * * beta: m-dimensional tensor with the same shape as gamma. + * + * Parameters: + * + * * beginAxis is an NN_INT32 scalar that specifies the axis from which normalization starts. The value range is [1, rank(input)). + * * epsilon is a scalar of NN_FLOAT32. It is a tiny amount in the normalization formula. The common value is 1e-7. + * + * Outputs: + * + * * output: n-dimensional tensor, with the same data type and shape as the input tensor. + */ + OH_NNBACKEND_OPS_LAYER_NORM = 49, + + /** + * Calculates the accumulated value for a tensor along the specified dimension. + * + * Inputs: + * + * * input: n-dimensional input tensor, where n is less than 8. + * * axis: dimension used to calculate the product. The value is a 1D tensor. The value range of each element in axis is [–n, n). + * + * Parameters: + * + * * keepDims: indicates whether to retain the dimension. The value is a Boolean value. + * When its value is true, the number of output dimensions is the same as that of the input. + * When its value is false, the number of output dimensions is reduced. + * + * Outputs: + * + * * output: m-dimensional output tensor whose data type is the same as that of the input. + * If keepDims is false, m==n. If keepDims is true, mkeepDims is set to false, + * the number of dimensions is reduced for the input; if keepDims is set to true, the number of dimensions is retained. + * + * Inputs: + * + * * A n-dimensional input tensor, where n is less than 8. + * * A 1D tensor specifying the dimension used to operate the logical OR. The value range of each element in axis is [–n, n). + * + * Parameters: + * + * * keepDims: indicates whether to retain the dimension. The value is a Boolean value. + * + * Outputs: + * * output: m-dimensional output tensor whose data type is the same as that of the input. + * If keepDims is false, m==n. If keepDims is true, minput: n-dimensional tensor. + * + * Parameters: + * + * * src_t: data type of the input. + * * dst_t: data type of the output. + * + * Outputs: + * + * * output: n-dimensional tensor. The data type is determined by input2. + * The output shape is the same as the input shape. + */ + OH_NNBACKEND_OPS_QUANT_DTYPE_CAST = 52, + + /** + * Obtains the values and indices of the largest k entries in the last dimension. + * + * Inputs: + * + * * input: n-dimensional tensor. + * * input k: first k records of data and their indices. + * + * Parameters: + * + * * sorted: order of sorting. The value true means descending and false means ascending. + * + * Outputs: + * + * * output0: largest k elements in each slice of the last dimension. + * * output1: index of the value in the last dimension of the input. + */ + OH_NNBACKEND_OPS_TOP_K = 53, + + /** + * Returns the index of the maximum tensor value across axes. + * + * Inputs: + * + * * input: n-dimensional tensor (N, ∗), where ∗ means any number of additional dimensions. + * + * Parameters: + * + * * axis: dimension for calculating the index of the maximum. + * * keep_dims: indicates whether to maintain the input tensor dimension. The value is a Boolean value. + * + * Outputs: + * * output: index of the maximum input tensor on the axis. The value is a tensor. + */ + OH_NNBACKEND_OPS_ARG_MAX = 54, + + /** + * Adds a dimension based on the value of axis. + * + * Inputs: + * * input: n-dimensional tensor. + * + * Parameters: + * + * * axis: dimension to be added. The value of axis can be an integer or an array of integers. + * The value range of the integer is [-n, n). + * + * Outputs: + * * output: output tensor. + */ + OH_NNBACKEND_OPS_UNSQUEEZE = 55, + + /** + * Gaussian error linear unit activation function. The int quantization input is not supported. output=0.5∗input∗(1+tanh(input/2)) + * + * Inputs: + * * An n-dimensional input tensor. + * + * Outputs: + * * output: n-dimensional tensor, with the same data type and shape as the input tensor. + */ + OH_NNBACKEND_OPS_GELU = 56, +} OH_NNBackend_OperationType; + +/** + * @brief Enumerates the tensor data types. + * + * Tensors are usually used to set the input, output, and operator parameters of a model. When a tensor is used + * as the input or output of a model (or operator), set the tensor type to {@link OH_NNBACKEND_TENSOR}. + * When the tensor is used as an operator parameter, select an enumerated value other than {@link OH_NNBACKEND_TENSOR} as the tensor type. + * Assume that the pad parameter of the {@link OH_NNBACKEND_OPS_CONV2D} operator is being set. + * You need to set the type attribute of the {@link OH_NNBACKEND_Tensor} instance to {@link OH_NNBACKEND_CONV2D_PAD}. + * The settings of other operator parameters are similar. The enumerated values are named + * in the format OH_NNBACKEND_{Operator name}_{Attribute name}. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** This enumerated value is used when the tensor is used as the input or output of a model (or operator). */ + OH_NNBACKEND_TENSOR = 0, + + /** This enumerated value is used when the tensor is used as the activationType parameter of the Add operator. */ + OH_NNBACKEND_ADD_ACTIVATIONTYPE = 1, + + /** This enumerated value is used when the tensor is used as the kernel_size parameter of the AvgPool operator. */ + OH_NNBACKEND_AVG_POOL_KERNEL_SIZE = 2, + /** This enumerated value is used when the tensor is used as the stride parameter of the AvgPool operator. */ + OH_NNBACKEND_AVG_POOL_STRIDE = 3, + /** This enumerated value is used when the tensor is used as the pad_mode parameter of the AvgPool operator. */ + OH_NNBACKEND_AVG_POOL_PAD_MODE = 4, + /** This enumerated value is used when the tensor is used as the pad parameter of the AvgPool operator. */ + OH_NNBACKEND_AVG_POOL_PAD = 5, + /** This enumerated value is used when the tensor is used as the activation_type parameter of the AvgPool operator. */ + OH_NNBACKEND_AVG_POOL_ACTIVATION_TYPE = 6, + + /** This enumerated value is used when the tensor is used as the eosilon parameter of the BatchNorm operator. */ + OH_NNBACKEND_BATCH_NORM_EPSILON = 7, + + /** This enumerated value is used when the tensor is used as the blockSize parameter of the BatchToSpaceND operator. */ + OH_NNBACKEND_BATCH_TO_SPACE_ND_BLOCKSIZE = 8, + /** This enumerated value is used when the tensor is used as the crops parameter of the BatchToSpaceND operator. */ + OH_NNBACKEND_BATCH_TO_SPACE_ND_CROPS = 9, + + /** This enumerated value is used when the tensor is used as the axis parameter of the Concat operator. */ + OH_NNBACKEND_CONCAT_AXIS = 10, + + /** This enumerated value is used when the tensor is used as the strides parameter of the Conv2D operator. */ + OH_NNBACKEND_CONV2D_STRIDES = 11, + /** This enumerated value is used when the tensor is used as the pad parameter of the Conv2D operator. */ + OH_NNBACKEND_CONV2D_PAD = 12, + /** This enumerated value is used when the tensor is used as the dilation parameter of the Conv2D operator. */ + OH_NNBACKEND_CONV2D_DILATION = 13, + /** This enumerated value is used when the tensor is used as the padMode parameter of the Conv2D operator. */ + OH_NNBACKEND_CONV2D_PAD_MODE = 14, + /** This enumerated value is used when the tensor is used as the activationType parameter of the Conv2D operator. */ + OH_NNBACKEND_CONV2D_ACTIVATION_TYPE = 15, + /** This enumerated value is used when the tensor is used as the group parameter of the Conv2D operator. */ + OH_NNBACKEND_CONV2D_GROUP = 16, + + /** This enumerated value is used when the tensor is used as the strides parameter of the Conv2DTranspose operator. */ + OH_NNBACKEND_CONV2D_TRANSPOSE_STRIDES = 17, + /** This enumerated value is used when the tensor is used as the pad parameter of the Conv2DTranspose operator. */ + OH_NNBACKEND_CONV2D_TRANSPOSE_PAD = 18, + /** This enumerated value is used when the tensor is used as the dilation parameter of the Conv2DTranspose operator. */ + OH_NNBACKEND_CONV2D_TRANSPOSE_DILATION = 19, + /** This enumerated value is used when the tensor is used as the outputPaddings parameter of the Conv2DTranspose operator. */ + OH_NNBACKEND_CONV2D_TRANSPOSE_OUTPUT_PADDINGS = 20, + /** This enumerated value is used when the tensor is used as the padMode parameter of the Conv2DTranspose operator. */ + OH_NNBACKEND_CONV2D_TRANSPOSE_PAD_MODE = 21, + /** This enumerated value is used when the tensor is used as the activationType parameter of the Conv2DTranspose operator. */ + OH_NNBACKEND_CONV2D_TRANSPOSE_ACTIVATION_TYPE = 22, + /** This enumerated value is used when the tensor is used as the group parameter of the Conv2DTranspose operator. */ + OH_NNBACKEND_CONV2D_TRANSPOSE_GROUP = 23, + + /** This enumerated value is used when the tensor is used as the strides parameter of the DepthwiseConv2dNative operator. */ + OH_NNBACKEND_DEPTHWISE_CONV2D_NATIVE_STRIDES = 24, + /** This enumerated value is used when the tensor is used as the pad parameter of the DepthwiseConv2dNative operator. */ + OH_NNBACKEND_DEPTHWISE_CONV2D_NATIVE_PAD = 25, + /** This enumerated value is used when the tensor is used as the dilation parameter of the DepthwiseConv2dNative operator. */ + OH_NNBACKEND_DEPTHWISE_CONV2D_NATIVE_DILATION = 26, + /** This enumerated value is used when the tensor is used as the padMode parameter of the DepthwiseConv2dNative operator. */ + OH_NNBACKEND_DEPTHWISE_CONV2D_NATIVE_PAD_MODE = 27, + /** This enumerated value is used when the tensor is used as the activationType parameter of the DepthwiseConv2dNative operator. */ + OH_NNBACKEND_DEPTHWISE_CONV2D_NATIVE_ACTIVATION_TYPE = 28, + + /** This enumerated value is used when the tensor is used as the activationType parameter of the Div operator. */ + OH_NNBACKEND_DIV_ACTIVATIONTYPE = 29, + + /** This enumerated value is used when the tensor is used as the mode parameter of the Eltwise operator. */ + OH_NNBACKEND_ELTWISE_MODE = 30, + + /** This enumerated value is used when the tensor is used as the axis parameter of the FullConnection operator. */ + OH_NNBACKEND_FULL_CONNECTION_AXIS = 31, + /** This enumerated value is used when the tensor is used as the activationType parameter of the FullConnection operator. */ + OH_NNBACKEND_FULL_CONNECTION_ACTIVATIONTYPE = 32, + + /** This enumerated value is used when the tensor is used as the transposeA parameter of the Matmul operator. */ + OH_NNBACKEND_MATMUL_TRANSPOSE_A = 33, + /** This enumerated value is used when the tensor is used as the transposeB parameter of the Matmul operator. */ + OH_NNBACKEND_MATMUL_TRANSPOSE_B = 34, + /** This enumerated value is used when the tensor is used as the activationType parameter of the Matmul operator. */ + OH_NNBACKEND_MATMUL_ACTIVATION_TYPE = 35, + + /** This enumerated value is used when the tensor is used as the kernel_size parameter of the MaxPool operator. */ + OH_NNBACKEND_MAX_POOL_KERNEL_SIZE = 36, + /** This enumerated value is used when the tensor is used as the stride parameter of the MaxPool operator. */ + OH_NNBACKEND_MAX_POOL_STRIDE = 37, + /** This enumerated value is used when the tensor is used as the pad_mode parameter of the MaxPool operator. */ + OH_NNBACKEND_MAX_POOL_PAD_MODE = 38, + /** This enumerated value is used when the tensor is used as the pad parameter of the MaxPool operator. */ + OH_NNBACKEND_MAX_POOL_PAD = 39, + /** This enumerated value is used when the tensor is used as the activation_type parameter of the MaxPool operator. */ + OH_NNBACKEND_MAX_POOL_ACTIVATION_TYPE = 40, + + /** This enumerated value is used when the tensor is used as the activationType parameter of the Mul operator. */ + OH_NNBACKEND_MUL_ACTIVATION_TYPE = 41, + + /** This enumerated value is used when the tensor is used as the axis parameter of the OneHot operator. */ + OH_NNBACKEND_ONE_HOT_AXIS = 42, + + /** This enumerated value is used when the tensor is used as the constant_value parameter of the Pad operator. */ + OH_NNBACKEND_PAD_CONSTANT_VALUE = 43, + + /** This enumerated value is used when the tensor is used as the activationType parameter of the Scale operator. */ + OH_NNBACKEND_SCALE_ACTIVATIONTYPE = 44, + /** This enumerated value is used when the tensor is used as the axis parameter of the Scale operator. */ + OH_NNBACKEND_SCALE_AXIS = 45, + + /** This enumerated value is used when the tensor is used as the axis parameter of the Softmax operator. */ + OH_NNBACKEND_SOFTMAX_AXIS = 46, + + /** This enumerated value is used when the tensor is used as the BlockShape parameter of the SpaceToBatchND operator. */ + OH_NNBACKEND_SPACE_TO_BATCH_ND_BLOCK_SHAPE = 47, + /** This enumerated value is used when the tensor is used as the Paddings parameter of the SpaceToBatchND operator. */ + OH_NNBACKEND_SPACE_TO_BATCH_ND_PADDINGS = 48, + + /** This enumerated value is used when the tensor is used as the Axis parameter of the Split operator. */ + OH_NNBACKEND_SPLIT_AXIS = 49, + /** This enumerated value is used when the tensor is used as the OutputNum parameter of the Split operator. */ + OH_NNBACKEND_SPLIT_OUTPUT_NUM = 50, + /** This enumerated value is used when the tensor is used as the SizeSplits parameter of the Split operator. */ + OH_NNBACKEND_SPLIT_SIZE_SPLITS = 51, + + /** This enumerated value is used when the tensor is used as the Axis parameter of the Squeeze operator. */ + OH_NNBACKEND_SQUEEZE_AXIS = 52, + + /** This enumerated value is used when the tensor is used as the Axis parameter of the Stack operator. */ + OH_NNBACKEND_STACK_AXIS = 53, + + /** This enumerated value is used when the tensor is used as the BeginMask parameter of the StridedSlice operator. */ + OH_NNBACKEND_STRIDED_SLICE_BEGIN_MASK = 54, + /** This enumerated value is used when the tensor is used as the EndMask parameter of the StridedSlice operator. */ + OH_NNBACKEND_STRIDED_SLICE_END_MASK = 55, + /** This enumerated value is used when the tensor is used as the EllipsisMask parameter of the StridedSlice operator. */ + OH_NNBACKEND_STRIDED_SLICE_ELLIPSIS_MASK = 56, + /** This enumerated value is used when the tensor is used as the NewAxisMask parameter of the StridedSlice operator. */ + OH_NNBACKEND_STRIDED_SLICE_NEW_AXIS_MASK = 57, + /** This enumerated value is used when the tensor is used as the ShrinkAxisMask parameter of the StridedSlice operator. */ + OH_NNBACKEND_STRIDED_SLICE_SHRINK_AXIS_MASK = 58, + + /** This enumerated value is used when the tensor is used as the ActivationType parameter of the Sub operator. */ + OH_NNBACKEND_SUB_ACTIVATIONTYPE = 59, + + /** This enumerated value is used when the tensor is used as the keep_dims parameter of the ReduceMean operator. */ + OH_NNBACKEND_REDUCE_MEAN_KEEP_DIMS = 60, + + /** This enumerated value is used when the tensor is used as the new_height parameter of the ResizeBilinear operator. */ + OH_NNBACKEND_RESIZE_BILINEAR_NEW_HEIGHT = 61, + /** This enumerated value is used when the tensor is used as the new_width parameter of the ResizeBilinear operator. */ + OH_NNBACKEND_RESIZE_BILINEAR_NEW_WIDTH = 62, + /** This enumerated value is used when the tensor is used as the preserve_aspect_ratio parameter of the ResizeBilinear operator. */ + OH_NNBACKEND_RESIZE_BILINEAR_PRESERVE_ASPECT_RATIO = 63, + /** This enumerated value is used when the tensor is used as the coordinate_transform_mode parameter of the ResizeBilinear operator. */ + OH_NNBACKEND_RESIZE_BILINEAR_COORDINATE_TRANSFORM_MODE = 64, + /** This enumerated value is used when the tensor is used as the exclude_outside parameter of the ResizeBilinear operator. */ + OH_NNBACKEND_RESIZE_BILINEAR_EXCLUDE_OUTSIDE = 65, + + /** This enumerated value is used when the tensor is used as the beginNormAxis parameter of the LayerNorm operator. */ + OH_NNBACKEND_LAYER_NORM_BEGIN_NORM_AXIS = 66, + /** This enumerated value is used when the tensor is used as the epsilon parameter of the LayerNorm operator. */ + OH_NNBACKEND_LAYER_NORM_EPSILON = 67, + /** This enumerated value is used when the tensor is used as the beginParamsAxis parameter of the LayerNorm operator. */ + OH_NNBACKEND_LAYER_NORM_BEGIN_PARAM_AXIS = 68, + /** This enumerated value is used when the tensor is used as the elementwiseAffine parameter of the LayerNorm operator. */ + OH_NNBACKEND_LAYER_NORM_ELEMENTWISE_AFFINE = 69, + + /** This enumerated value is used when the tensor is used as the keep_dims parameter of the ReduceProd operator. */ + OH_NNBACKEND_REDUCE_PROD_KEEP_DIMS = 70, + + /** This enumerated value is used when the tensor is used as the keep_dims parameter of the ReduceAll operator. */ + OH_NNBACKEND_REDUCE_ALL_KEEP_DIMS = 71, + + /** This enumerated value is used when the tensor is used as the src_t parameter of the QuantDTypeCast operator. */ + OH_NNBACKEND_QUANT_DTYPE_CAST_SRC_T = 72, + /** This enumerated value is used when the tensor is used as the dst_t parameter of the QuantDTypeCast operator. */ + OH_NNBACKEND_QUANT_DTYPE_CAST_DST_T = 73, + + /** This enumerated value is used when the tensor is used as the Sorted parameter of the Topk operator. */ + OH_NNBACKEND_TOP_K_SORTED = 74, + + /** This enumerated value is used when the tensor is used as the axis parameter of the ArgMax operator. */ + OH_NNBACKEND_ARG_MAX_AXIS = 75, + /** This enumerated value is used when the tensor is used as the keepDims parameter of the ArgMax operator. */ + OH_NNBACKEND_ARG_MAX_KEEPDIMS = 76, + + /** This enumerated value is used when the tensor is used as the Axis parameter of the Unsqueeze operator. */ + OH_NNBACKEND_UNSQUEEZE_AXIS = 77, +} OH_NNBackend_TensorType; + +/** + * @brief This structure is used to store a 32-bit unsigned integer array. + * + * @since 9 + * @version 2.0 + */ +typedef struct OH_NNBackend_Array { + /** Pointer to the unsigned integer array */ + void* data; + /** Array length */ + size_t length; + /** Data type of the array*/ + OH_NNCore_DataType datatype; +} OH_NNBackend_Array; + + +typedef struct OH_NNBackend_Memory OH_NNBackend_Memory; + +#ifdef __cplusplus +} +#endif // __cplusplus + +/** @} */ +#endif // NEURAL_NETWORK_RUNTIME_TYPE_H