blob: aa00be8f609462c99ecfb74fa63b5f1b2c2ff221 [file] [log] [blame]
Jim Flynn4b2f3472021-10-13 21:20:07 +01001//
Cathal Corbett53837672022-09-01 11:34:37 +01002// Copyright © 2021,2022 Arm Ltd and Contributors. All rights reserved.
Jim Flynn4b2f3472021-10-13 21:20:07 +01003// SPDX-License-Identifier: MIT
4//
5
6#pragma once
7
8// NOTE: the MultiLayerFacade class is a utility class which makes a chain
9// of operators look like a single IConnectableLayer with the first
10// layer in the chain supplying the input slots and the last supplying
11// the output slots. It enables us, for example, to simulate a
12// Tensorflow Lite FloorDiv operator by chaining a Div layer followed
13// by a Floor layer and pass them as a single unit to the code that
14// connects up the graph as the delegate proceeds to build up the
15// Arm NN subgraphs.
16//
17
18#include <common/include/ProfilingGuid.hpp>
19#include <armnn/INetwork.hpp>
20
21namespace armnnDelegate
22{
23
24class MultiLayerFacade : public armnn::IConnectableLayer
25{
26public:
27 MultiLayerFacade() :
28 m_FirstLayer(nullptr), m_LastLayer(nullptr) {}
29
30 MultiLayerFacade(armnn::IConnectableLayer* firstLayer, armnn::IConnectableLayer* lastLayer) :
31 m_FirstLayer(firstLayer), m_LastLayer(lastLayer) {}
32
33 MultiLayerFacade(const MultiLayerFacade& obj) :
34 m_FirstLayer(obj.m_FirstLayer), m_LastLayer(obj.m_LastLayer) {}
35
36 ~MultiLayerFacade() {} // we don't own the pointers
37
38 MultiLayerFacade& operator=(const MultiLayerFacade& obj)
39 {
40 m_FirstLayer = obj.m_FirstLayer;
41 m_LastLayer = obj.m_LastLayer;
42 return *this;
43 }
44
45 void AssignValues(armnn::IConnectableLayer* firstLayer, armnn::IConnectableLayer* lastLayer)
46 {
47 m_FirstLayer = firstLayer;
48 m_LastLayer = lastLayer;
49 }
50
51 virtual const char* GetName() const override
52 {
53 return m_FirstLayer->GetName();
54 }
55
56 virtual unsigned int GetNumInputSlots() const override
57 {
58 return m_FirstLayer->GetNumInputSlots();
59 }
60
61 virtual unsigned int GetNumOutputSlots() const override
62 {
63 return m_LastLayer->GetNumOutputSlots();
64 }
65
66 virtual const armnn::IInputSlot& GetInputSlot(unsigned int index) const override
67 {
68 return m_FirstLayer->GetInputSlot(index);
69 }
70
71 virtual armnn::IInputSlot& GetInputSlot(unsigned int index) override
72 {
73 return m_FirstLayer->GetInputSlot(index);
74 }
75
76 virtual const armnn::IOutputSlot& GetOutputSlot(unsigned int index) const override
77 {
78 return m_LastLayer->GetOutputSlot(index);
79 }
80
81 virtual armnn::IOutputSlot& GetOutputSlot(unsigned int index) override
82 {
83 return m_LastLayer->GetOutputSlot(index);
84 }
85
86 virtual std::vector<armnn::TensorShape> InferOutputShapes(
87 const std::vector<armnn::TensorShape>& inputShapes) const override
88 {
89 // NOTE: do not expect this function to be used. Likely that if it is it might need to be overridden
90 // for particular sequences of operators.
91 return m_FirstLayer->InferOutputShapes(inputShapes);
92 }
93
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000094 virtual LayerGuid GetGuid() const override
Jim Flynn4b2f3472021-10-13 21:20:07 +010095 {
96 return m_FirstLayer->GetGuid();
97 }
98
Jim Flynn4b2f3472021-10-13 21:20:07 +010099 virtual void ExecuteStrategy(armnn::IStrategy& strategy) const override
100 {
101 // Do not expect this function to be used so not providing an implementation
102 // if an implementation is required and the chain contains more than two operators
103 // would have to provide a way to record the intermediate layers so they could be
Nikhil Raj4d2eec02022-05-30 11:08:52 +0100104 // visited... the same applies to the BackendSelectionHint
Jim Flynn4b2f3472021-10-13 21:20:07 +0100105 // below.
106 }
107
108 virtual void BackendSelectionHint(armnn::Optional<armnn::BackendId> backend) override
109 {
110 // Do not expect this function to be used so not providing an implementation
111 }
112
113 virtual armnn::LayerType GetType() const override
114 {
115 return m_FirstLayer->GetType();
116 }
117
Jim Flynne4665962022-01-31 16:08:53 +0000118 virtual const armnn::BaseDescriptor& GetParameters() const override { return m_NullDescriptor; }
119
Cathal Corbett53837672022-09-01 11:34:37 +0100120 void SetBackendId(const armnn::BackendId& id) override {}
121
Nikhil Raj2e241752022-02-01 16:42:15 +0000122protected:
123 /// Retrieve the handles to the constant values stored by the layer.
124 /// @return A vector of the constant tensors stored by this layer.
125 ConstantTensors GetConstantTensorsByRef() override { return {}; }
126
Jim Flynn4b2f3472021-10-13 21:20:07 +0100127private:
128 armnn::IConnectableLayer* m_FirstLayer;
129 armnn::IConnectableLayer* m_LastLayer;
Jim Flynne4665962022-01-31 16:08:53 +0000130
131 // to satisfy the GetParameters method need to hand back a NullDescriptor
132 armnn::NullDescriptor m_NullDescriptor;
Jim Flynn4b2f3472021-10-13 21:20:07 +0100133};
134
135} // namespace armnnDelegate