From 762ea2402e7e75b9e2443f3f87cccd6aa1bd6a7e Mon Sep 17 00:00:00 2001 From: wejoncy Date: Tue, 14 Mar 2023 10:55:37 +0800 Subject: [PATCH] fix --- .../nnapi_builtin/builders/impl/base_op_builder.cc | 2 ++ .../nnapi/nnapi_builtin/builders/model_builder.cc | 8 +++++--- .../nnapi/nnapi_builtin/builders/model_builder.h | 14 +++++++------- .../nnapi/nnapi_builtin/nnapi_api_helper.cc | 4 +++- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/impl/base_op_builder.cc b/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/impl/base_op_builder.cc index d0c615c6ac..f1137d94d7 100644 --- a/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/impl/base_op_builder.cc +++ b/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/impl/base_op_builder.cc @@ -53,7 +53,9 @@ Status BaseOpBuilder::AddToModelBuilder(ModelBuilder& model_builder, const NodeU }; ORT_RETURN_IF_NOT(IsOpSupported(model_builder.GetInitializerTensors(), node_unit, params), "Unsupported operator ", node_unit.OpType()); +#ifndef NDEBUG model_builder.SetDebugTrackNode(node_unit.Index()); +#endif ORT_RETURN_IF_ERROR(AddToModelBuilderImpl(model_builder, node_unit)); LOGS_DEFAULT(VERBOSE) << "Operator name: [" << node_unit.Name() << "] type: [" << node_unit.OpType() << "] was added"; diff --git a/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/model_builder.cc b/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/model_builder.cc index 9e8f494eb7..89413d43a7 100644 --- a/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/model_builder.cc +++ b/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/model_builder.cc @@ -2,6 +2,7 @@ // Licensed under the MIT License. #include "model_builder.h" + #include #include "core/common/common.h" @@ -552,9 +553,10 @@ Status ModelBuilder::Compile(std::unique_ptr& model) { return ORT_MAKE_STATUS(ONNXRUNTIME, EP_FAIL, "The model cannot run using current set of target devices, ", GetDevicesDescription(nnapi_target_devices_)); - // workaround for bugs in Android OS. sometimes ops are passed checking but failed at compilation. } - // else // no else after return + + // workaround for bugs in NNAPI drives on some phones. + // sometimes ops are passed checking but failed at compilation. if (target_device_option_ != TargetDeviceOption::ALL_DEVICES) { use_create_for_devices = true; } @@ -576,7 +578,7 @@ Status ModelBuilder::Compile(std::unique_ptr& model) { const auto* node(graph_viewer_.GetNode(onnx_node_idx)); auto stat_name = node->OpType() + ".nnapi_op_" + std::to_string(nnapi_idx); - if (!supported_ops[idx]) { + if (supported_ops[idx]) { optype_support_status[stat_name].first++; } else { optype_support_status[stat_name].second++; diff --git a/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/model_builder.h b/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/model_builder.h index 583bc2cd31..9183939f8e 100644 --- a/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/model_builder.h +++ b/onnxruntime/core/providers/nnapi/nnapi_builtin/builders/model_builder.h @@ -105,16 +105,16 @@ class ModelBuilder { int32_t GetEffectiveFeatureLevel() const { return nnapi_effective_feature_level_; } - // Just for Debugging - void SetDebugTrackNode(const size_t node_index) { #ifndef NDEBUG + // Set the node index to be tracked for debugging + // For now, NNAPI is a black box, LOGs are limited and it's hard to debug. + // ONNX node and NNAPI node are not a 1:1 mapping, like batch-normalization. + // We use this to track a specific onnx node which we are processing and record the detail mapping relationship. + // So we can log out each NNAPI OP status during model-building and compiling. + void SetDebugTrackNode(const size_t node_index) { track_node_index_ = node_index; -#else - // ORT_UNUSED_PARAMETER minimal build - (void)(node_index); -#endif } - +#endif private: const NnApi& nnapi_; const GraphViewer& graph_viewer_; diff --git a/onnxruntime/core/providers/nnapi/nnapi_builtin/nnapi_api_helper.cc b/onnxruntime/core/providers/nnapi/nnapi_builtin/nnapi_api_helper.cc index 542f6a992b..42cf6de263 100644 --- a/onnxruntime/core/providers/nnapi/nnapi_builtin/nnapi_api_helper.cc +++ b/onnxruntime/core/providers/nnapi/nnapi_builtin/nnapi_api_helper.cc @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +#include "core/providers/nnapi/nnapi_builtin/nnapi_api_helper.h" #include "core/common/inlined_containers_fwd.h" #include "core/providers/nnapi/nnapi_builtin/builders/model_builder.h" #include "core/providers/nnapi/nnapi_builtin/nnapi_lib/nnapi_implementation.h" -#include "core/providers/nnapi/nnapi_builtin/nnapi_api_helper.h" #include "core/common/logging/logging.h" #ifdef __ANDROID__ @@ -104,6 +104,8 @@ Status GetTargetDevices(const NnApi& nnapi_handle, TargetDeviceOption target_dev // and nnapi internally skip the last device if it has already found one. // 2) we can easily exclude nnapi-reference when not strict excluding CPU. // 3) we can easily log the detail of how op was assigned on NNAPI devices which is helpful for debugging. + // refer to https://source.android.com/docs/core/interaction/neural-networks#cpu-usage + // and https://android.googlesource.com/platform/frameworks/ml/+/master/nn/runtime/ExecutionPlan.cpp#2303 if (cpu_index != -1 && cpu_index != static_cast(devices.size()) - 1) { std::swap(devices[devices.size() - 1], devices[cpu_index]); }