aboutsummaryrefslogtreecommitdiff
path: root/delegate/src/MultiLayerFacade.hpp
blob: aa00be8f609462c99ecfb74fa63b5f1b2c2ff221 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//
// Copyright © 2021,2022 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 <common/include/ProfilingGuid.hpp>
#include <armnn/INetwork.hpp>

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<armnn::TensorShape> InferOutputShapes(
        const std::vector<armnn::TensorShape>& 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<armnn::BackendId> 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 {}; }

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