aboutsummaryrefslogtreecommitdiff
path: root/ModelToINetworkConverter.hpp
blob: 5ee6a3418e29e25db8e09f3e32a2fdf49f60c91a (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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
//
// Copyright © 2017 Arm Ltd. All rights reserved.
// See LICENSE file in the project root for full license information.
//

#pragma once

#include "ArmnnDriver.hpp"
#include "ArmnnDriverImpl.hpp"

#include <NeuralNetworks.h>
#include <ActivationFunctor.h>

#include <armnn/ArmNN.hpp>
#include <armnn/INetwork.hpp>
#include <CpuExecutor.h>

#include "Utils.hpp"

#include <memory>
#include <vector>
#include <set>

namespace armnn_driver
{

class ConstTensorPin;
class LayerInputHandle;

enum class ConversionResult
{
    Success,
    ErrorMappingPools,
    UnsupportedFeature
};

// A helper performing the conversion from an AndroidNN driver Model representation,
// to an armnn::INetwork object
template<typename HalVersion>
class ModelToINetworkConverter
{
public:
    using HalModel = typename HalVersion::Model;

    ModelToINetworkConverter(armnn::Compute compute,
                             const HalModel& model,
                             const std::set<unsigned int>& forcedUnsupportedOperations);

    ConversionResult GetConversionResult() const { return m_ConversionResult; }

    // Returns the ArmNN INetwork corresponding to the input model, if preparation went smoothly, nullptr otherwise.
    armnn::INetwork* GetINetwork() const { return m_Network.get(); }

    bool IsOperationSupported(uint32_t operationIndex) const;

private:
    void Convert();

#if defined(ARMNN_ANDROID_NN_V1_1) // Using ::android::hardware::neuralnetworks::V1_1.
    bool ConvertOperation(const ::android::hardware::neuralnetworks::V1_1::Operation& operation);

    bool ConvertDiv(const ::android::hardware::neuralnetworks::V1_1::Operation& operation);
#endif

    bool ConvertOperation(const ::android::hardware::neuralnetworks::V1_0::Operation& operation);

    bool ConvertAdd(const ::android::hardware::neuralnetworks::V1_0::Operation& operation);

    bool ConvertAveragePool2d(const ::android::hardware::neuralnetworks::V1_0::Operation& operation);

    bool ConvertConcatenation(const ::android::hardware::neuralnetworks::V1_0::Operation& operation);

    bool ConvertConv2d(const ::android::hardware::neuralnetworks::V1_0::Operation& operation);

    bool ConvertDepthwiseConv2d(const ::android::hardware::neuralnetworks::V1_0::Operation& operation);

    bool ConvertFloor(const ::android::hardware::neuralnetworks::V1_0::Operation& operation);

    bool ConvertFullyConnected(const ::android::hardware::neuralnetworks::V1_0::Operation& operation);

    bool ConvertLogistic(const ::android::hardware::neuralnetworks::V1_0::Operation& operation);

    bool ConvertLocalResponseNormalization(const ::android::hardware::neuralnetworks::V1_0::Operation& operation);

    bool ConvertL2Normalization(const ::android::hardware::neuralnetworks::V1_0::Operation& operation);

    bool ConvertL2Pool2d(const ::android::hardware::neuralnetworks::V1_0::Operation& operation);

    bool ConvertMaxPool2d(const ::android::hardware::neuralnetworks::V1_0::Operation& operation);

    bool ConvertMul(const ::android::hardware::neuralnetworks::V1_0::Operation& operation);

    bool ConvertReLu(const ::android::hardware::neuralnetworks::V1_0::Operation& operation);

    bool ConvertReLu1(const ::android::hardware::neuralnetworks::V1_0::Operation& operation);

    bool ConvertReLu6(const ::android::hardware::neuralnetworks::V1_0::Operation& operation);

    bool ConvertSoftmax(const ::android::hardware::neuralnetworks::V1_0::Operation& operation);

    bool ConvertTanH(const ::android::hardware::neuralnetworks::V1_0::Operation& operation);

    bool ConvertReshape(const ::android::hardware::neuralnetworks::V1_0::Operation& operation);

    bool ConvertResizeBilinear(const ::android::hardware::neuralnetworks::V1_0::Operation& operation);

    bool ConvertLstm(const ::android::hardware::neuralnetworks::V1_0::Operation& operation);

    bool ConvertToActivation(const ::android::hardware::neuralnetworks::V1_0::Operation& operation,
                             const char* operationName,
                             const armnn::ActivationDescriptor& activationDesc);

    bool ConvertPooling2d(const ::android::hardware::neuralnetworks::V1_0::Operation& operation,
                          const char* name, armnn::PoolingAlgorithm poolType);

    const void* GetOperandValueReadOnlyAddress(const Operand& operand) const;

    template<typename HalOperation>
    const Operand* GetInputOperand(const HalOperation& operation, uint32_t inputIndex) const;

    template<typename HalOperation>
    const Operand* GetOutputOperand(const HalOperation& operation, uint32_t outputIndex) const;

    template<typename HalOperation, typename T>
    bool GetInputScalar(const HalOperation& operation, uint32_t inputIndex, OperandType type, T& outValue) const;

    template<typename HalOperation>
    bool GetInputInt32(const HalOperation& operation, uint32_t inputIndex, int32_t& outValue) const;

    template<typename HalOperation>
    bool GetInputFloat32(const HalOperation& operation, uint32_t inputIndex, float& outValue) const;

    template<typename HalOperation>
    bool GetInputActivationFunctionImpl(const HalOperation& operation,
                                        uint32_t inputIndex,
                                        OperandType type,
                                        ActivationFn& outActivationFunction) const;

    template<typename HalOperation>
    bool GetInputActivationFunction(const HalOperation& operation,
                                    uint32_t inputIndex,
                                    ActivationFn& outActivationFunction) const;

    template<typename HalOperation>
    bool GetInputActivationFunctionFromTensor(const HalOperation& operation,
                                              uint32_t inputIndex,
                                              ActivationFn& outActivationFunction) const;

    template<typename HalOperation>
    bool GetOptionalInputActivation(const HalOperation& operation,
                                    uint32_t inputIndex,
                                    ActivationFn& activationFunction) const;

    template<typename HalOperation>
    bool GetInputPaddingScheme(const HalOperation& operation,
                               uint32_t inputIndex,
                               android::nn::PaddingScheme& outPaddingScheme) const;

    template<typename HalOperation>
    LayerInputHandle ConvertToLayerInputHandle(const HalOperation& operation, uint32_t inputIndex);

    template<typename HalOperation>
    ConstTensorPin ConvertOperationInputToConstTensorPin(
        const HalOperation& operation,
        uint32_t inputIndex,
        const armnn::PermutationVector& dimensionMappings = g_DontPermute,
        const armnn::TensorShape* overrideTensorShape = nullptr,
        bool optional = false);

    ConstTensorPin ConvertOperandToConstTensorPin(
        const Operand& operand,
        const armnn::PermutationVector& dimensionMappings = g_DontPermute,
        const armnn::TensorShape* overrideTensorShape = nullptr,
        bool optional = false);

    bool GetTensorInt32Values(const Operand& operand, std::vector<int32_t>& outValues) const;

    armnn::IConnectableLayer* ProcessActivation(const armnn::TensorInfo& tensorInfo,
                                                ActivationFn activation,
                                                armnn::IConnectableLayer* prevLayer);

    template<typename HalOperation>
    bool SetupAndTrackLayerOutputSlot(const HalOperation& operation,
                                      uint32_t operationOutputIndex,
                                      armnn::IConnectableLayer& layer,
                                      uint32_t layerOutputIndex);

    template<typename HalOperation>
    bool SetupAndTrackLayerOutputSlot(const HalOperation& operation,
                                      uint32_t outputIndex,
                                      armnn::IConnectableLayer& layer);

    // Input data
    armnn::Compute                m_Compute;
    const HalModel&               m_Model;
    const std::set<unsigned int>& m_ForcedUnsupportedOperations;

    // Output data
    armnn::INetworkPtr       m_Network;
    ConversionResult         m_ConversionResult;
    std::map<uint32_t, bool> m_OperationSupported;

    // Working/intermediate data
    std::vector<armnn::IOutputSlot*>          m_OutputSlotForOperand;
    std::vector<android::nn::RunTimePoolInfo> m_MemPools;
};

} // armnn_driver