From 0210109eb6fa486fda3774e1e74f784f1a32d770 Mon Sep 17 00:00:00 2001 From: Cisco Cervellera Date: Tue, 7 Sep 2021 11:34:43 +0100 Subject: MLECO-2160: Error repor when Ethos-U is not used Change-Id: I0dab5308bf5c3eba9b4bb2c9bf0939ac9598d2f6 --- source/application/tensorflow-lite-micro/Model.cc | 34 ++++++++++++++++++++++ .../tensorflow-lite-micro/include/Model.hpp | 7 +++-- .../include/TensorFlowLiteMicro.hpp | 1 + 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/source/application/tensorflow-lite-micro/Model.cc b/source/application/tensorflow-lite-micro/Model.cc index 80ef3c3..acc2f0e 100644 --- a/source/application/tensorflow-lite-micro/Model.cc +++ b/source/application/tensorflow-lite-micro/Model.cc @@ -67,6 +67,16 @@ bool arm::app::Model::Init(tflite::MicroAllocator* allocator) debug("loading op resolver\n"); this->EnlistOperations(); + +#if !defined(ARM_NPU) + /* If it is not a NPU build check if the model contains a NPU operator */ + bool contains_ethosu_operator = this->ContainsEthosUOperator(); + if (contains_ethosu_operator) + { + printf_err("Ethos-U operator present in the model but this build does not include Ethos-U drivers\n"); + return false; + } +#endif /* ARM_NPU */ /* Create allocator instance, if it doesn't exist */ this->m_pAllocator = allocator; @@ -236,6 +246,30 @@ bool arm::app::Model::IsDataSigned() const return this->GetType() == kTfLiteInt8; } +bool arm::app::Model::ContainsEthosUOperator() const +{ + /* We expect there to be only one subgraph. */ + const uint32_t nOperators = tflite::NumSubgraphOperators(this->m_pModel, 0); + const tflite::SubGraph* subgraph = this->m_pModel->subgraphs()->Get(0); + const auto* opcodes = this->m_pModel->operator_codes(); + + /* check for custom operators */ + for (size_t i = 0; (i < nOperators); ++i) + { + const tflite::Operator* op = subgraph->operators()->Get(i); + const tflite::OperatorCode* opcode = opcodes->Get(op->opcode_index()); + + auto builtin_code = tflite::GetBuiltinCode(opcode); + if ((builtin_code == tflite::BuiltinOperator_CUSTOM) && + ( nullptr != opcode->custom_code()) && + ( 0 == std::string(opcode->custom_code()->c_str()).compare("ethos-u"))) + { + return true; + } + } + return false; +} + bool arm::app::Model::RunInference() { bool inference_state = false; diff --git a/source/application/tensorflow-lite-micro/include/Model.hpp b/source/application/tensorflow-lite-micro/include/Model.hpp index 70e17ad..b814da4 100644 --- a/source/application/tensorflow-lite-micro/include/Model.hpp +++ b/source/application/tensorflow-lite-micro/include/Model.hpp @@ -84,8 +84,11 @@ namespace app { /** @brief Checks if the model uses signed data. */ bool IsDataSigned() const; - /** @brief Runs the inference (invokes the interpreter). */ - virtual bool RunInference(); + /** @brief Checks if the model uses Ethos-U operator */ + bool ContainsEthosUOperator() const; + + /** @brief Runs the inference (invokes the interpreter). */ + virtual bool RunInference(); /** @brief Model information handler common to all models. * @return true or false based on execution success. diff --git a/source/application/tensorflow-lite-micro/include/TensorFlowLiteMicro.hpp b/source/application/tensorflow-lite-micro/include/TensorFlowLiteMicro.hpp index 1333f6c..545ede1 100644 --- a/source/application/tensorflow-lite-micro/include/TensorFlowLiteMicro.hpp +++ b/source/application/tensorflow-lite-micro/include/TensorFlowLiteMicro.hpp @@ -51,6 +51,7 @@ #include "tensorflow/lite/c/common.h" #include "tensorflow/lite/micro/kernels/micro_ops.h" #include "tensorflow/lite/schema/schema_generated.h" +#include "tensorflow/lite/schema/schema_utils.h" #if defined (TESTS) #include "tensorflow/lite/micro/test_helpers.h" -- cgit v1.2.1