From 3c24f43ff9afb50898d6a73ccddbc0936f72fdad Mon Sep 17 00:00:00 2001 From: Sadik Armagan Date: Mon, 19 Oct 2020 17:35:30 +0100 Subject: IVGCVSW-5365 'Create the TfLite Delegate subdirectory in ArmNN' * Created delegate sub-directory under armnn * Created Delegate, ArmnnSubgraph and DelegateOptions classes * Created cmake files. * Integrated doctest (under MIT license) as testing framework Signed-off-by: Sadik Armagan Change-Id: If725ebd62c40a97c783cdad22bca48709d44338c --- delegate/include/armnn_delegate.hpp | 155 ++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 delegate/include/armnn_delegate.hpp (limited to 'delegate/include/armnn_delegate.hpp') diff --git a/delegate/include/armnn_delegate.hpp b/delegate/include/armnn_delegate.hpp new file mode 100644 index 0000000000..6136f2bebe --- /dev/null +++ b/delegate/include/armnn_delegate.hpp @@ -0,0 +1,155 @@ +// +// Copyright © 2020 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include "DelegateOptions.hpp" + +#include +#include +#include +#include + +namespace armnnDelegate +{ + +TfLiteStatus DelegatePrepare(TfLiteContext* context, TfLiteDelegate* delegate); + +/// Delegate class +class Delegate +{ + friend class ArmnnSubgraph; +public: + explicit Delegate(armnnDelegate::DelegateOptions options); + + TfLiteIntArray* CollectOperatorsToDelegate(TfLiteContext* context); + + TfLiteDelegate* GetDelegate(); + +private: + TfLiteDelegate m_Delegate = { + reinterpret_cast(this), // .data_ + DelegatePrepare, // .Prepare + nullptr, // .CopyFromBufferHandle + nullptr, // .CopyToBufferHandle + nullptr, // .FreeBufferHandle + kTfLiteDelegateFlagsNone, // .flags + }; + + /// Arm NN Runtime pointer + armnn::IRuntimePtr m_Runtime; + /// Arm NN Delegate Options + armnnDelegate::DelegateOptions m_Options; +}; + +/// ArmnnSubgraph class where parsing the nodes to ArmNN format and creating the ArmNN Graph +class ArmnnSubgraph +{ +public: + static ArmnnSubgraph* Create(TfLiteContext* tfLiteContext, + const TfLiteDelegateParams* parameters, + const Delegate* delegate); + + TfLiteStatus Prepare(TfLiteContext* tfLiteContext); + + TfLiteStatus Invoke(TfLiteContext* tfLiteContext); + + static TfLiteStatus VisitNode(armnn::INetworkPtr& network, + TfLiteContext* tfLiteContext, + TfLiteRegistration* tfLiteRegistration, + TfLiteNode* tfLiteNode, + int nodeIndex); + +private: + ArmnnSubgraph(armnn::NetworkId networkId, armnn::IRuntime* runtime) + : m_NetworkId(networkId), m_Runtime(runtime) + {} + + /// The Network Id + armnn::NetworkId m_NetworkId; + /// ArmNN Rumtime + armnn::IRuntime* m_Runtime; +}; + +void* ArmnnSubgraphInit(TfLiteContext* tfLiteContext, const char* buffer, size_t length) +{ + const TfLiteDelegateParams* parameters = reinterpret_cast(buffer); + + return static_cast(ArmnnSubgraph::Create( + tfLiteContext, parameters, static_cast<::armnnDelegate::Delegate*>(parameters->delegate->data_))); +} + +TfLiteStatus ArmnnSubgraphPrepare(TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode) +{ + if (tfLiteNode->user_data == nullptr) + { + return kTfLiteError; + } + + return static_cast(tfLiteNode->user_data)->Prepare(tfLiteContext); +} + +TfLiteStatus ArmnnSubgraphInvoke(TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode) +{ + if (tfLiteNode->user_data == nullptr) + { + return kTfLiteError; + } + + return static_cast(tfLiteNode->user_data)->Invoke(tfLiteContext); +} + +void ArmnnSubgraphFree(TfLiteContext* tfLiteContext, void* buffer) +{ + if (buffer != nullptr) + { + delete static_cast(buffer); + } +} + +const TfLiteRegistration armnnSubgraphRegistration = { + ArmnnSubgraphInit, // .init + ArmnnSubgraphFree, // .free + ArmnnSubgraphPrepare, // .prepare + ArmnnSubgraphInvoke, // .invoke + nullptr, // .profiling_string + 0, // .builtin_code + "TfLiteArmnnDelegate", // .custom_name + 1, // .version +}; + +TfLiteStatus DelegatePrepare(TfLiteContext* tfLiteContext, TfLiteDelegate* tfLiteDelegate) +{ + TfLiteIntArray* supportedOperators = + static_cast<::armnnDelegate::Delegate*>(tfLiteDelegate->data_)->CollectOperatorsToDelegate(tfLiteContext); + + const TfLiteStatus status = + tfLiteContext->ReplaceNodeSubsetsWithDelegateKernels( + tfLiteContext, armnnSubgraphRegistration, supportedOperators, tfLiteDelegate); + TfLiteIntArrayFree(supportedOperators); + + return status; +} + +} // armnnDelegate namespace + +armnnDelegate::DelegateOptions TfLiteArmnnDelegateOptionsDefault() { + armnnDelegate::DelegateOptions options(armnn::Compute::CpuRef); + return options; +} + +TfLiteDelegate* TfLiteArmnnDelegateCreate(armnnDelegate::DelegateOptions options) +{ + auto* armnnDelegate = new ::armnnDelegate::Delegate(options); + return armnnDelegate->GetDelegate(); +} + +void TfLiteArmnnDelegateDelete(TfLiteDelegate* tfLiteDelegate) +{ + if (tfLiteDelegate != nullptr) + { + delete static_cast<::armnnDelegate::Delegate*>(tfLiteDelegate->data_); + } +} \ No newline at end of file -- cgit v1.2.1