Release 18.02
[platform/upstream/armnn.git] / src / armnn / Layers.hpp
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // See LICENSE file in the project root for full license information.
4 //
5 #pragma once
6
7 #include "LayersFwd.hpp"
8
9 #include "Layer.hpp"
10 #include "InternalTypes.hpp"
11
12 #include <armnn/Descriptors.hpp>
13
14 #include <boost/core/ignore_unused.hpp>
15
16 namespace armnn
17 {
18
19 class ScopedCpuTensorHandle;
20
21 template <typename Parameters>
22 class LayerWithParameters : public Layer
23 {
24 public:
25     typedef Parameters DescriptorType;
26
27     const Parameters& GetParameters() const { return m_Param; }
28
29 protected:
30     LayerWithParameters(unsigned int numInputSlots,
31                         unsigned int numOutputSlots,
32                         LayerType type,
33                         const Parameters& param,
34                         const char* name)
35     :   Layer(numInputSlots, numOutputSlots, type, name)
36     ,   m_Param(param)
37     {
38     }
39
40     ~LayerWithParameters() = default;
41
42     /// Helper function to reduce duplication in *Layer::CreateWorkload
43     template <typename QueueDescriptor>
44     WorkloadInfo PrepInfoAndDesc(QueueDescriptor& descriptor, const Graph& graph) const
45     {
46         descriptor.m_Parameters = m_Param;
47         return Layer::PrepInfoAndDesc(descriptor, graph);
48     }
49
50     /// The parameters for the layer (not including tensor-valued weights etc.)
51     Parameters m_Param;
52 };
53
54 class ActivationLayer : public LayerWithParameters<ActivationDescriptor>
55 {
56 public:
57     virtual std::unique_ptr<IWorkload> CreateWorkload(const Graph&            graph,
58                                                       const IWorkloadFactory& factory) const override;
59
60     ActivationLayer* Clone(Graph& graph) const override;
61
62     void ValidateTensorShapesFromInputs() override;
63
64 protected:
65     ActivationLayer(const ActivationDescriptor &param, const char* name);
66     ~ActivationLayer() = default;
67 };
68
69 class AdditionLayer : public Layer
70 {
71 public:
72     virtual std::unique_ptr<IWorkload> CreateWorkload(const Graph&            graph,
73                                                       const IWorkloadFactory& factory) const override;
74
75     AdditionLayer* Clone(Graph& graph) const override;
76
77     void ValidateTensorShapesFromInputs() override;
78
79 protected:
80     AdditionLayer(const char* name);
81     ~AdditionLayer() = default;
82 };
83
84 class BatchNormalizationLayer : public LayerWithParameters<BatchNormalizationDescriptor>
85 {
86 public:
87     std::unique_ptr<ScopedCpuTensorHandle> m_Mean;
88     std::unique_ptr<ScopedCpuTensorHandle> m_Variance;
89     std::unique_ptr<ScopedCpuTensorHandle> m_Beta;
90     std::unique_ptr<ScopedCpuTensorHandle> m_Gamma;
91
92     virtual std::unique_ptr<IWorkload> CreateWorkload(const Graph&            graph,
93                                                       const IWorkloadFactory& factory) const override;
94
95     BatchNormalizationLayer* Clone(Graph& graph) const override;
96
97     void ValidateTensorShapesFromInputs() override;
98
99 protected:
100     BatchNormalizationLayer(const BatchNormalizationDescriptor& param, const char* name);
101     ~BatchNormalizationLayer() = default;
102 };
103
104 class Convolution2dLayer : public LayerWithParameters<Convolution2dDescriptor>
105 {
106 public:
107     std::unique_ptr<ScopedCpuTensorHandle> m_Weight;
108     std::unique_ptr<ScopedCpuTensorHandle> m_Bias;
109
110     virtual std::unique_ptr<IWorkload> CreateWorkload(const Graph&            graph,
111                                                       const IWorkloadFactory& factory) const override;
112
113     Convolution2dLayer* Clone(Graph& graph) const override;
114
115     void ValidateTensorShapesFromInputs() override;
116
117 protected:
118     Convolution2dLayer(const Convolution2dDescriptor& param, const char* name);
119     ~Convolution2dLayer() = default;
120 };
121
122 class DepthwiseConvolution2dLayer : public LayerWithParameters<DepthwiseConvolution2dDescriptor>
123 {
124 public:
125     std::unique_ptr<ScopedCpuTensorHandle> m_Weight;
126     std::unique_ptr<ScopedCpuTensorHandle> m_Bias;
127
128     virtual std::unique_ptr<IWorkload> CreateWorkload(const Graph& graph,
129                                                       const IWorkloadFactory& factory) const override;
130
131     DepthwiseConvolution2dLayer* Clone(Graph& graph) const override;
132
133     void ValidateTensorShapesFromInputs() override;
134
135 protected:
136     DepthwiseConvolution2dLayer(const DepthwiseConvolution2dDescriptor& param, const char* name);
137     ~DepthwiseConvolution2dLayer() = default;
138 };
139
140 class FakeQuantizationLayer : public LayerWithParameters<FakeQuantizationDescriptor>
141 {
142 public:
143     virtual std::unique_ptr<IWorkload> CreateWorkload(const Graph&            graph,
144                                                       const IWorkloadFactory& factory) const override;
145
146     FakeQuantizationLayer* Clone(Graph& graph) const override;
147
148     void ValidateTensorShapesFromInputs() override;
149
150 protected:
151     FakeQuantizationLayer(const FakeQuantizationDescriptor& descriptor, const char* name);
152     ~FakeQuantizationLayer() = default;
153 };
154
155 class FloorLayer : public Layer
156 {
157 public:
158     virtual std::unique_ptr<IWorkload> CreateWorkload(const Graph& graph,
159                                                       const IWorkloadFactory& factory) const override;
160
161     FloorLayer* Clone(Graph& graph) const override;
162
163     void ValidateTensorShapesFromInputs() override;
164
165 protected:
166     FloorLayer(const char* name);
167     ~FloorLayer() = default;
168 };
169
170 class FullyConnectedLayer : public LayerWithParameters<FullyConnectedDescriptor>
171 {
172 public:
173     std::unique_ptr<ScopedCpuTensorHandle> m_Weight;
174     std::unique_ptr<ScopedCpuTensorHandle> m_Bias;
175
176     virtual std::unique_ptr<IWorkload> CreateWorkload(const Graph&            graph,
177                                                       const IWorkloadFactory& factory) const override;
178
179     FullyConnectedLayer* Clone(Graph& graph) const override;
180
181     void ValidateTensorShapesFromInputs() override;
182
183 protected:
184     FullyConnectedLayer(const FullyConnectedDescriptor& param, const char* name);
185     ~FullyConnectedLayer() = default;
186 };
187
188 class InputLayer : public BindableLayer
189 {
190 public:
191     virtual std::unique_ptr<IWorkload> CreateWorkload(const Graph&            graph,
192                                                       const IWorkloadFactory& factory) const override;
193
194     InputLayer* Clone(Graph& graph) const override;
195
196     void ValidateTensorShapesFromInputs() override;
197
198 protected:
199     InputLayer(LayerBindingId id, const char* name);
200     ~InputLayer() = default;
201 };
202
203 class MergerLayer : public LayerWithParameters<OriginsDescriptor>
204 {
205 public:
206     virtual std::unique_ptr<IWorkload> CreateWorkload(const Graph&            graph,
207                                                       const IWorkloadFactory& factory) const override;
208     virtual void CreateTensorHandles(Graph& graph, const IWorkloadFactory& factory) override;
209
210     MergerLayer* Clone(Graph& graph) const override;
211
212     void ValidateTensorShapesFromInputs() override;
213
214 protected:
215     MergerLayer(const OriginsDescriptor& param, const char* name);
216     ~MergerLayer() = default;
217 };
218
219 class MultiplicationLayer : public Layer
220 {
221 public:
222     virtual std::unique_ptr<IWorkload> CreateWorkload(const Graph&            graph,
223                                                       const IWorkloadFactory& factory) const override;
224
225     MultiplicationLayer* Clone(Graph& graph) const override;
226
227     void ValidateTensorShapesFromInputs() override;
228
229 protected:
230     MultiplicationLayer(const char* name);
231     ~MultiplicationLayer() = default;
232 };
233
234 class NormalizationLayer : public LayerWithParameters<NormalizationDescriptor>
235 {
236 public:
237     virtual std::unique_ptr<IWorkload> CreateWorkload(const Graph&            graph,
238                                                       const IWorkloadFactory& factory) const override;
239
240     NormalizationLayer* Clone(Graph& graph) const override;
241
242     void ValidateTensorShapesFromInputs() override;
243
244 protected:
245     NormalizationLayer(const NormalizationDescriptor& param, const char* name);
246     ~NormalizationLayer() = default;
247 };
248
249 class OutputLayer : public BindableLayer
250 {
251 public:
252     virtual std::unique_ptr<IWorkload> CreateWorkload(const Graph&            graph,
253                                                       const IWorkloadFactory& factory) const override;
254     virtual void CreateTensorHandles(Graph& graph, const IWorkloadFactory& factory) override
255     {
256         boost::ignore_unused(graph, factory);
257     }
258
259     OutputLayer* Clone(Graph& graph) const override;
260
261     void ValidateTensorShapesFromInputs() override;
262
263 protected:
264     OutputLayer(LayerBindingId id, const char* name);
265     ~OutputLayer() = default;
266 };
267
268 class PermuteLayer : public LayerWithParameters<PermuteDescriptor>
269 {
270 public:
271     virtual std::unique_ptr<IWorkload> CreateWorkload(const Graph&            graph,
272                                                       const IWorkloadFactory& factory) const override;
273
274     PermuteLayer* Clone(Graph& graph) const override;
275
276     void ValidateTensorShapesFromInputs() override;
277
278     const PermutationVector& GetPermutation() const
279     {
280         return m_Param.m_DimMappings;
281     }
282
283     bool IsInverse(const Layer& other) const
284     {
285         return (other.GetType() == LayerType::Permute) &&
286             GetPermutation().IsInverse(boost::polymorphic_downcast<const PermuteLayer*>(&other)->GetPermutation());
287     }
288
289     bool IsEqual(const Layer& other) const
290     {
291         return (other.GetType() == LayerType::Permute) &&
292                GetPermutation().IsEqual(boost::polymorphic_downcast<const PermuteLayer*>(&other)->GetPermutation());
293     }
294
295 protected:
296     PermuteLayer(const PermuteDescriptor& param, const char* name);
297     ~PermuteLayer() = default;
298 };
299
300 class Pooling2dLayer : public LayerWithParameters<Pooling2dDescriptor>
301 {
302 public:
303     virtual std::unique_ptr<IWorkload> CreateWorkload(const Graph&            graph,
304                                                       const IWorkloadFactory& factory) const override;
305
306     Pooling2dLayer* Clone(Graph& graph) const override;
307
308     void ValidateTensorShapesFromInputs() override;
309
310 protected:
311     Pooling2dLayer(const Pooling2dDescriptor& param, const char* name);
312     ~Pooling2dLayer() = default;
313 };
314
315 class SoftmaxLayer : public LayerWithParameters<SoftmaxDescriptor>
316 {
317 public:
318     virtual std::unique_ptr<IWorkload> CreateWorkload(const Graph&            graph,
319                                                       const IWorkloadFactory& factory) const override;
320
321     SoftmaxLayer* Clone(Graph& graph) const override;
322
323     void ValidateTensorShapesFromInputs() override;
324
325 protected:
326     SoftmaxLayer(const SoftmaxDescriptor& param, const char* name);
327     ~SoftmaxLayer() = default;
328 };
329
330 class SplitterLayer : public LayerWithParameters<ViewsDescriptor>
331 {
332 public:
333     virtual std::unique_ptr<IWorkload> CreateWorkload(const Graph&            graph,
334                                                       const IWorkloadFactory& factory) const override;
335     virtual void CreateTensorHandles(Graph& graph, const IWorkloadFactory& factory) override;
336
337     SplitterLayer* Clone(Graph& graph) const override;
338
339     void ValidateTensorShapesFromInputs() override;
340
341 protected:
342     SplitterLayer(const ViewsDescriptor& param, const char* name);
343     ~SplitterLayer() = default;
344 };
345
346 class MemCopyLayer : public Layer
347 {
348 public:
349     virtual std::unique_ptr<IWorkload>
350     CreateWorkload(const Graph& graph, const IWorkloadFactory& factory) const override;
351
352     MemCopyLayer* Clone(Graph& graph) const override;
353
354     void ValidateTensorShapesFromInputs() override;
355
356 protected:
357     MemCopyLayer(const char* name);
358     ~MemCopyLayer() = default;
359 };
360
361 class ResizeBilinearLayer : public LayerWithParameters<ResizeBilinearDescriptor>
362 {
363 public:
364     virtual std::unique_ptr<IWorkload>
365         CreateWorkload(const Graph& graph, const IWorkloadFactory& factory) const override;
366
367     ResizeBilinearLayer* Clone(Graph& graph) const override;
368
369     void ValidateTensorShapesFromInputs() override;
370
371 protected:
372     ResizeBilinearLayer(const ResizeBilinearDescriptor& param, const char* name);
373     ~ResizeBilinearLayer() = default;
374 };
375
376 class L2NormalizationLayer : public Layer
377 {
378 public:
379     virtual std::unique_ptr<IWorkload> CreateWorkload(const Graph& graph,
380         const IWorkloadFactory& factory) const override;
381
382     L2NormalizationLayer* Clone(Graph& graph) const override;
383
384     void ValidateTensorShapesFromInputs() override;
385
386 protected:
387     L2NormalizationLayer(const char* name);
388     ~L2NormalizationLayer() = default;
389 };
390
391 class ConstantLayer : public Layer
392 {
393 public:
394     virtual std::unique_ptr<IWorkload> CreateWorkload(const Graph& graph,
395         const IWorkloadFactory& factory) const override;
396
397     ConstantLayer* Clone(Graph& graph) const override;
398
399     void ValidateTensorShapesFromInputs() override;
400
401 protected:
402     ConstantLayer(const std::shared_ptr<ScopedCpuTensorHandle>& input, const char* name);
403     ~ConstantLayer() = default;
404
405 private:
406     std::shared_ptr<ScopedCpuTensorHandle> m_LayerOutput;
407 };
408
409 class ReshapeLayer : public LayerWithParameters<ReshapeDescriptor>
410 {
411 public:
412     virtual std::unique_ptr<IWorkload> CreateWorkload(const Graph& graph,
413         const IWorkloadFactory& factory) const override;
414
415     ReshapeLayer* Clone(Graph& graph) const override;
416
417     void ValidateTensorShapesFromInputs() override;
418
419     bool IsEqual(const Layer& other) const
420     {
421         return (other.GetType() == LayerType::Reshape) &&
422                m_Param.m_TargetShape == boost::polymorphic_downcast<const ReshapeLayer*>(&other)->m_Param.m_TargetShape;
423     }
424
425 protected:
426     ReshapeLayer(const ReshapeDescriptor& desc, const char* name);
427     ~ReshapeLayer() = default;
428 };
429
430 }