From 6c53f9fbea7d0b8786e1d29b850ab7bed85e167a Mon Sep 17 00:00:00 2001 From: David Monahan Date: Thu, 27 Apr 2023 15:21:19 +0100 Subject: IVGCVSW-7588 Implement ElementWiseBinary Op for Opaque Delegate * Added visit functions for ElementwiseBinary Ops * Moved MultiLayerFacade.hpp to common directory and updated both delegates to use it Signed-off-by: David Monahan Change-Id: I84b8bd74d15a194895e63da47c29be994531a889 --- delegate/common/src/MultiLayerFacade.hpp | 136 +++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 delegate/common/src/MultiLayerFacade.hpp (limited to 'delegate/common') diff --git a/delegate/common/src/MultiLayerFacade.hpp b/delegate/common/src/MultiLayerFacade.hpp new file mode 100644 index 0000000000..20ccd35f22 --- /dev/null +++ b/delegate/common/src/MultiLayerFacade.hpp @@ -0,0 +1,136 @@ +// +// Copyright © 2021-2023 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +// NOTE: the MultiLayerFacade class is a utility class which makes a chain +// of operators look like a single IConnectableLayer with the first +// layer in the chain supplying the input slots and the last supplying +// the output slots. It enables us, for example, to simulate a +// Tensorflow Lite FloorDiv operator by chaining a Div layer followed +// by a Floor layer and pass them as a single unit to the code that +// connects up the graph as the delegate proceeds to build up the +// Arm NN subgraphs. +// + +#include +#include + +namespace armnnDelegate +{ + + class MultiLayerFacade : public armnn::IConnectableLayer + { + public: + MultiLayerFacade() : + m_FirstLayer(nullptr), m_LastLayer(nullptr) {} + + MultiLayerFacade(armnn::IConnectableLayer* firstLayer, armnn::IConnectableLayer* lastLayer) : + m_FirstLayer(firstLayer), m_LastLayer(lastLayer) {} + + MultiLayerFacade(const MultiLayerFacade& obj) : + m_FirstLayer(obj.m_FirstLayer), m_LastLayer(obj.m_LastLayer) {} + + ~MultiLayerFacade() {} // we don't own the pointers + + MultiLayerFacade& operator=(const MultiLayerFacade& obj) + { + m_FirstLayer = obj.m_FirstLayer; + m_LastLayer = obj.m_LastLayer; + return *this; + } + + void AssignValues(armnn::IConnectableLayer* firstLayer, armnn::IConnectableLayer* lastLayer) + { + m_FirstLayer = firstLayer; + m_LastLayer = lastLayer; + } + + virtual const char* GetName() const override + { + return m_FirstLayer->GetName(); + } + + virtual unsigned int GetNumInputSlots() const override + { + return m_FirstLayer->GetNumInputSlots(); + } + + virtual unsigned int GetNumOutputSlots() const override + { + return m_LastLayer->GetNumOutputSlots(); + } + + virtual const armnn::IInputSlot& GetInputSlot(unsigned int index) const override + { + return m_FirstLayer->GetInputSlot(index); + } + + virtual armnn::IInputSlot& GetInputSlot(unsigned int index) override + { + return m_FirstLayer->GetInputSlot(index); + } + + virtual const armnn::IOutputSlot& GetOutputSlot(unsigned int index) const override + { + return m_LastLayer->GetOutputSlot(index); + } + + virtual armnn::IOutputSlot& GetOutputSlot(unsigned int index) override + { + return m_LastLayer->GetOutputSlot(index); + } + + virtual std::vector InferOutputShapes( + const std::vector& inputShapes) const override + { + // NOTE: do not expect this function to be used. Likely that if it is it might need to be overridden + // for particular sequences of operators. + return m_FirstLayer->InferOutputShapes(inputShapes); + } + + virtual LayerGuid GetGuid() const override + { + return m_FirstLayer->GetGuid(); + } + + virtual void ExecuteStrategy(armnn::IStrategy& strategy) const override + { + // Do not expect this function to be used so not providing an implementation + // if an implementation is required and the chain contains more than two operators + // would have to provide a way to record the intermediate layers so they could be + // visited... the same applies to the BackendSelectionHint + // below. + } + + virtual void BackendSelectionHint(armnn::Optional backend) override + { + // Do not expect this function to be used so not providing an implementation + } + + virtual armnn::LayerType GetType() const override + { + return m_FirstLayer->GetType(); + } + + virtual const armnn::BaseDescriptor& GetParameters() const override { return m_NullDescriptor; } + + void SetBackendId(const armnn::BackendId& id) override {} + + protected: + /// Retrieve the handles to the constant values stored by the layer. + /// @return A vector of the constant tensors stored by this layer. + ConstantTensors GetConstantTensorsByRef() override { return {}; } + ImmutableConstantTensors GetConstantTensorsByRef() const override { return {}; } + + private: + armnn::IConnectableLayer* m_FirstLayer; + armnn::IConnectableLayer* m_LastLayer; + + // to satisfy the GetParameters method need to hand back a NullDescriptor + armnn::NullDescriptor m_NullDescriptor; + }; + +} // namespace armnnDelegate -- cgit v1.2.1