blob: c0df47bac92a3ceb0f94f46e931f8f1c9d9eda95 [file] [log] [blame]
Jim Flynn4b2f3472021-10-13 21:20:07 +01001//
2// Copyright © 2021 Arm Ltd and Contributors. All rights reserved.
3// 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
99 // The Accept function needs to be wrapped in a no warn macro to avoid deprecation warnings from
100 // the deprecated ILayerVisitor which is used in the function.
101 ARMNN_NO_DEPRECATE_WARN_BEGIN
102 ARMNN_DEPRECATED_MSG_REMOVAL_DATE("Accept is deprecated. The ILayerVisitor that works in conjunction with this "
103 "Accept function is deprecated. Use IStrategy in combination with "
104 "ExecuteStrategy instead, which is an ABI/API stable version of the "
105 "visitor pattern.",
106 "22.05")
107 virtual void Accept(armnn::ILayerVisitor& visitor) const override
108 {
109 // Do not expect this function to be used so not providing an implementation
110 }
111 ARMNN_NO_DEPRECATE_WARN_END
112
113 virtual void ExecuteStrategy(armnn::IStrategy& strategy) const override
114 {
115 // Do not expect this function to be used so not providing an implementation
116 // if an implementation is required and the chain contains more than two operators
117 // would have to provide a way to record the intermediate layers so they could be
118 // visited... the same applies to the Accept method above and the BackendSelectionHint
119 // below.
120 }
121
122 virtual void BackendSelectionHint(armnn::Optional<armnn::BackendId> backend) override
123 {
124 // Do not expect this function to be used so not providing an implementation
125 }
126
127 virtual armnn::LayerType GetType() const override
128 {
129 return m_FirstLayer->GetType();
130 }
131
Jim Flynne4665962022-01-31 16:08:53 +0000132 virtual const armnn::BaseDescriptor& GetParameters() const override { return m_NullDescriptor; }
133
Nikhil Raj2e241752022-02-01 16:42:15 +0000134protected:
135 /// Retrieve the handles to the constant values stored by the layer.
136 /// @return A vector of the constant tensors stored by this layer.
137 ConstantTensors GetConstantTensorsByRef() override { return {}; }
138
Jim Flynn4b2f3472021-10-13 21:20:07 +0100139private:
140 armnn::IConnectableLayer* m_FirstLayer;
141 armnn::IConnectableLayer* m_LastLayer;
Jim Flynne4665962022-01-31 16:08:53 +0000142
143 // to satisfy the GetParameters method need to hand back a NullDescriptor
144 armnn::NullDescriptor m_NullDescriptor;
Jim Flynn4b2f3472021-10-13 21:20:07 +0100145};
146
147} // namespace armnnDelegate