IVGCVSW-1946: Remove armnn/src from the include paths
[platform/upstream/armnn.git] / src / backends / reference / RefLayerSupport.cpp
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #include "RefLayerSupport.hpp"
7 #include "RefBackendId.hpp"
8
9 #include <InternalTypes.hpp>
10 #include <LayerSupportCommon.hpp>
11 #include <armnn/Types.hpp>
12
13 #include <backendsCommon/LayerSupportRegistry.hpp>
14
15 #include <boost/core/ignore_unused.hpp>
16
17 using namespace boost;
18
19 namespace armnn
20 {
21
22 namespace
23 {
24
25 ILayerSupportSharedPtr GetLayerSupportPointer()
26 {
27     static ILayerSupportSharedPtr instance{new RefLayerSupport};
28     return instance;
29 }
30
31 static StaticRegistryInitializer<LayerSupportRegistry> g_RegisterHelper{
32     LayerSupportRegistryInstance(),
33     RefBackendId(),
34     [](const EmptyInitializer&)
35     {
36         return GetLayerSupportPointer();
37     }
38 };
39
40 template<typename Float32Func, typename Uint8Func, typename ... Params>
41 bool IsSupportedForDataTypeRef(Optional<std::string&> reasonIfUnsupported,
42                                DataType dataType,
43                                Float32Func floatFuncPtr,
44                                Uint8Func uint8FuncPtr,
45                                Params&&... params)
46 {
47     return IsSupportedForDataTypeGeneric(reasonIfUnsupported,
48                                          dataType,
49                                          &FalseFunc<Params...>,
50                                          floatFuncPtr,
51                                          uint8FuncPtr,
52                                          std::forward<Params>(params)...);
53 }
54
55 } // anonymous namespace
56
57 bool RefLayerSupport::IsActivationSupported(const TensorInfo& input,
58                                             const TensorInfo& output,
59                                             const ActivationDescriptor& descriptor,
60                                             Optional<std::string&> reasonIfUnsupported) const
61 {
62     ignore_unused(output);
63     ignore_unused(descriptor);
64     return IsSupportedForDataTypeRef(reasonIfUnsupported,
65                                      input.GetDataType(),
66                                      &TrueFunc<>,
67                                      &TrueFunc<>);
68 }
69
70 bool RefLayerSupport::IsAdditionSupported(const TensorInfo& input0,
71                                           const TensorInfo& input1,
72                                           const TensorInfo& output,
73                                           Optional<std::string&> reasonIfUnsupported) const
74 {
75     ignore_unused(input1);
76     ignore_unused(output);
77     return IsSupportedForDataTypeRef(reasonIfUnsupported,
78                                      input0.GetDataType(),
79                                      &TrueFunc<>,
80                                      &TrueFunc<>);
81 }
82
83 bool RefLayerSupport::IsBatchNormalizationSupported(const TensorInfo& input,
84                                                     const TensorInfo& output,
85                                                     const TensorInfo& mean,
86                                                     const TensorInfo& var,
87                                                     const TensorInfo& beta,
88                                                     const TensorInfo& gamma,
89                                                     const BatchNormalizationDescriptor& descriptor,
90                                                     Optional<std::string&> reasonIfUnsupported) const
91 {
92     ignore_unused(output);
93     ignore_unused(mean);
94     ignore_unused(var);
95     ignore_unused(beta);
96     ignore_unused(gamma);
97     ignore_unused(descriptor);
98     return IsSupportedForDataTypeRef(reasonIfUnsupported,
99                                      input.GetDataType(),
100                                      &TrueFunc<>,
101                                      &TrueFunc<>);
102 }
103
104 bool RefLayerSupport::IsConstantSupported(const TensorInfo& output,
105                                           Optional<std::string&> reasonIfUnsupported) const
106 {
107     return IsSupportedForDataTypeRef(reasonIfUnsupported,
108                                      output.GetDataType(),
109                                      &TrueFunc<>,
110                                      &TrueFunc<>);
111 }
112
113 bool RefLayerSupport::IsConvertFp16ToFp32Supported(const TensorInfo& input,
114                                                    const TensorInfo& output,
115                                                    Optional<std::string&> reasonIfUnsupported) const
116 {
117     return (IsSupportedForDataTypeGeneric(reasonIfUnsupported,
118                                           input.GetDataType(),
119                                           &TrueFunc<>,
120                                           &FalseInputFuncF32<>,
121                                           &FalseFuncU8<>) &&
122             IsSupportedForDataTypeGeneric(reasonIfUnsupported,
123                                           output.GetDataType(),
124                                           &FalseOutputFuncF16<>,
125                                           &TrueFunc<>,
126                                           &FalseFuncU8<>));
127 }
128
129 bool RefLayerSupport::IsConvertFp32ToFp16Supported(const TensorInfo& input,
130                                                    const TensorInfo& output,
131                                                    Optional<std::string&> reasonIfUnsupported) const
132 {
133     return (IsSupportedForDataTypeGeneric(reasonIfUnsupported,
134                                           input.GetDataType(),
135                                           &FalseInputFuncF16<>,
136                                           &TrueFunc<>,
137                                           &FalseFuncU8<>) &&
138             IsSupportedForDataTypeGeneric(reasonIfUnsupported,
139                                           output.GetDataType(),
140                                           &TrueFunc<>,
141                                           &FalseOutputFuncF32<>,
142                                           &FalseFuncU8<>));
143 }
144
145 bool RefLayerSupport::IsConvolution2dSupported(const TensorInfo& input,
146                                                const TensorInfo& output,
147                                                const Convolution2dDescriptor& descriptor,
148                                                const TensorInfo& weights,
149                                                const Optional<TensorInfo>& biases,
150                                                Optional<std::string&> reasonIfUnsupported) const
151 {
152     ignore_unused(output);
153     ignore_unused(descriptor);
154     ignore_unused(weights);
155     ignore_unused(biases);
156     return IsSupportedForDataTypeRef(reasonIfUnsupported,
157                                      input.GetDataType(),
158                                      &TrueFunc<>,
159                                      &TrueFunc<>);
160 }
161
162 bool RefLayerSupport::IsDepthwiseConvolutionSupported(const TensorInfo& input,
163                                                       const TensorInfo& output,
164                                                       const DepthwiseConvolution2dDescriptor& descriptor,
165                                                       const TensorInfo& weights,
166                                                       const Optional<TensorInfo>& biases,
167                                                       Optional<std::string&> reasonIfUnsupported) const
168 {
169     ignore_unused(output);
170     ignore_unused(descriptor);
171     ignore_unused(weights);
172     ignore_unused(biases);
173     return IsSupportedForDataTypeRef(reasonIfUnsupported,
174                                      input.GetDataType(),
175                                      &TrueFunc<>,
176                                      &TrueFunc<>);
177 }
178
179 bool RefLayerSupport::IsDivisionSupported(const TensorInfo& input0,
180                                           const TensorInfo& input1,
181                                           const TensorInfo& output,
182                                           Optional<std::string&> reasonIfUnsupported) const
183 {
184     ignore_unused(input1);
185     ignore_unused(output);
186     return IsSupportedForDataTypeRef(reasonIfUnsupported,
187                                      input0.GetDataType(),
188                                      &TrueFunc<>,
189                                      &TrueFunc<>);
190 }
191
192 bool RefLayerSupport::IsFakeQuantizationSupported(const TensorInfo& input,
193                                                   const FakeQuantizationDescriptor& descriptor,
194                                                   Optional<std::string&> reasonIfUnsupported) const
195 {
196     ignore_unused(descriptor);
197     return IsSupportedForDataTypeRef(reasonIfUnsupported,
198                                      input.GetDataType(),
199                                      &TrueFunc<>,
200                                      &FalseFuncU8<>);
201 }
202
203 bool RefLayerSupport::IsFloorSupported(const TensorInfo& input,
204                                        const TensorInfo& output,
205                                        Optional<std::string&> reasonIfUnsupported) const
206 {
207     ignore_unused(output);
208     return IsSupportedForDataTypeRef(reasonIfUnsupported,
209                                      input.GetDataType(),
210                                      &TrueFunc<>,
211                                      &FalseFuncU8<>);
212 }
213
214 bool RefLayerSupport::IsFullyConnectedSupported(const TensorInfo& input,
215                                                 const TensorInfo& output,
216                                                 const TensorInfo& weights,
217                                                 const TensorInfo& biases,
218                                                 const FullyConnectedDescriptor& descriptor,
219                                                 Optional<std::string&> reasonIfUnsupported) const
220 {
221     ignore_unused(output);
222     ignore_unused(weights);
223     ignore_unused(biases);
224     ignore_unused(descriptor);
225     return IsSupportedForDataTypeRef(reasonIfUnsupported,
226                                      input.GetDataType(),
227                                      &TrueFunc<>,
228                                      &TrueFunc<>);
229 }
230
231 bool RefLayerSupport::IsInputSupported(const TensorInfo& input,
232                                        Optional<std::string&> reasonIfUnsupported) const
233 {
234     return IsSupportedForDataTypeRef(reasonIfUnsupported,
235                                      input.GetDataType(),
236                                      &TrueFunc<>,
237                                      &TrueFunc<>);
238 }
239
240 bool RefLayerSupport::IsL2NormalizationSupported(const TensorInfo& input,
241                                                  const TensorInfo& output,
242                                                  const L2NormalizationDescriptor& descriptor,
243                                                  Optional<std::string&> reasonIfUnsupported) const
244 {
245     ignore_unused(output);
246     ignore_unused(descriptor);
247     return IsSupportedForDataTypeRef(reasonIfUnsupported,
248                                      input.GetDataType(),
249                                      &TrueFunc<>,
250                                      &FalseFuncU8<>);
251 }
252
253 bool RefLayerSupport::IsLstmSupported(const TensorInfo& input,
254                                       const TensorInfo& outputStateIn,
255                                       const TensorInfo& cellStateIn,
256                                       const TensorInfo& scratchBuffer,
257                                       const TensorInfo& outputStateOut,
258                                       const TensorInfo& cellStateOut,
259                                       const TensorInfo& output,
260                                       const LstmDescriptor& descriptor,
261                                       const TensorInfo& inputToForgetWeights,
262                                       const TensorInfo& inputToCellWeights,
263                                       const TensorInfo& inputToOutputWeights,
264                                       const TensorInfo& recurrentToForgetWeights,
265                                       const TensorInfo& recurrentToCellWeights,
266                                       const TensorInfo& recurrentToOutputWeights,
267                                       const TensorInfo& forgetGateBias,
268                                       const TensorInfo& cellBias,
269                                       const TensorInfo& outputGateBias,
270                                       const TensorInfo* inputToInputWeights,
271                                       const TensorInfo* recurrentToInputWeights,
272                                       const TensorInfo* cellToInputWeights,
273                                       const TensorInfo* inputGateBias,
274                                       const TensorInfo* projectionWeights,
275                                       const TensorInfo* projectionBias,
276                                       const TensorInfo* cellToForgetWeights,
277                                       const TensorInfo* cellToOutputWeights,
278                                       Optional<std::string&> reasonIfUnsupported) const
279 {
280     ignore_unused(input);
281     ignore_unused(outputStateIn);
282     ignore_unused(cellStateIn);
283     ignore_unused(scratchBuffer);
284     ignore_unused(outputStateOut);
285     ignore_unused(cellStateOut);
286     ignore_unused(output);
287     ignore_unused(descriptor);
288     ignore_unused(inputToForgetWeights);
289     ignore_unused(inputToCellWeights);
290     ignore_unused(inputToOutputWeights);
291     ignore_unused(recurrentToForgetWeights);
292     ignore_unused(recurrentToCellWeights);
293     ignore_unused(recurrentToOutputWeights);
294     ignore_unused(forgetGateBias);
295     ignore_unused(cellBias);
296     ignore_unused(outputGateBias);
297     ignore_unused(inputToInputWeights);
298     ignore_unused(recurrentToInputWeights);
299     ignore_unused(cellToInputWeights);
300     ignore_unused(inputGateBias);
301     ignore_unused(projectionWeights);
302     ignore_unused(projectionBias);
303     ignore_unused(cellToForgetWeights);
304     ignore_unused(cellToOutputWeights);
305     ignore_unused(reasonIfUnsupported);
306     return false;
307 }
308
309 bool RefLayerSupport::IsMeanSupported(const TensorInfo& input,
310                                       const TensorInfo& output,
311                                       const MeanDescriptor& descriptor,
312                                       Optional<std::string&> reasonIfUnsupported) const
313 {
314     ignore_unused(output);
315     ignore_unused(descriptor);
316     return IsSupportedForDataTypeRef(reasonIfUnsupported,
317                                      input.GetDataType(),
318                                      &TrueFunc<>,
319                                      &TrueFunc<>);
320 }
321
322 bool RefLayerSupport::IsMergerSupported(const std::vector<const TensorInfo*> inputs,
323                                         const OriginsDescriptor& descriptor,
324                                         Optional<std::string&> reasonIfUnsupported) const
325 {
326     ignore_unused(descriptor);
327     return IsSupportedForDataTypeRef(reasonIfUnsupported,
328                                      inputs[0]->GetDataType(),
329                                      &TrueFunc<>,
330                                      &TrueFunc<>);
331 }
332
333 bool RefLayerSupport::IsMultiplicationSupported(const TensorInfo& input0,
334                                                 const TensorInfo& input1,
335                                                 const TensorInfo& output,
336                                                 Optional<std::string&> reasonIfUnsupported) const
337 {
338     ignore_unused(input1);
339     ignore_unused(output);
340     return IsSupportedForDataTypeRef(reasonIfUnsupported,
341                                      input0.GetDataType(),
342                                      &TrueFunc<>,
343                                      &TrueFunc<>);
344 }
345
346 bool RefLayerSupport::IsNormalizationSupported(const TensorInfo& input,
347                                                const TensorInfo& output,
348                                                const NormalizationDescriptor& descriptor,
349                                                Optional<std::string&> reasonIfUnsupported) const
350 {
351     ignore_unused(output);
352     ignore_unused(descriptor);
353     return IsSupportedForDataTypeRef(reasonIfUnsupported,
354                                      input.GetDataType(),
355                                      &TrueFunc<>,
356                                      &FalseFuncU8<>);
357 }
358
359 bool RefLayerSupport::IsOutputSupported(const TensorInfo& output,
360                                         Optional<std::string&> reasonIfUnsupported) const
361 {
362     return IsSupportedForDataTypeRef(reasonIfUnsupported,
363                                      output.GetDataType(),
364                                      &TrueFunc<>,
365                                      &TrueFunc<>);
366 }
367
368 bool RefLayerSupport::IsPadSupported(const TensorInfo& input,
369                                      const TensorInfo& output,
370                                      const PadDescriptor& descriptor,
371                                      Optional<std::string&> reasonIfUnsupported) const
372 {
373     ignore_unused(input);
374     ignore_unused(output);
375     ignore_unused(descriptor);
376     ignore_unused(reasonIfUnsupported);
377     return false;
378 }
379
380 bool RefLayerSupport::IsPermuteSupported(const TensorInfo& input,
381                                          const TensorInfo& output,
382                                          const PermuteDescriptor& descriptor,
383                                          Optional<std::string&> reasonIfUnsupported) const
384 {
385     ignore_unused(output);
386     ignore_unused(descriptor);
387     return IsSupportedForDataTypeRef(reasonIfUnsupported,
388                                      input.GetDataType(),
389                                      &TrueFunc<>,
390                                      &TrueFunc<>);
391 }
392
393 bool RefLayerSupport::IsPooling2dSupported(const TensorInfo& input,
394                                            const TensorInfo& output,
395                                            const Pooling2dDescriptor& descriptor,
396                                            Optional<std::string&> reasonIfUnsupported) const
397 {
398     ignore_unused(output);
399     ignore_unused(descriptor);
400     return IsSupportedForDataTypeRef(reasonIfUnsupported,
401                                      input.GetDataType(),
402                                      &TrueFunc<>,
403                                      &TrueFunc<>);
404 }
405
406 bool RefLayerSupport::IsReshapeSupported(const TensorInfo& input,
407                                          Optional<std::string&> reasonIfUnsupported) const
408 {
409     return IsSupportedForDataTypeRef(reasonIfUnsupported,
410                                      input.GetDataType(),
411                                      &TrueFunc<>,
412                                      &TrueFunc<>);
413 }
414
415 bool RefLayerSupport::IsResizeBilinearSupported(const TensorInfo& input,
416                                                 Optional<std::string&> reasonIfUnsupported) const
417 {
418     return IsSupportedForDataTypeRef(reasonIfUnsupported,
419                                      input.GetDataType(),
420                                      &TrueFunc<>,
421                                      &TrueFunc<>);
422 }
423
424 bool RefLayerSupport::IsSoftmaxSupported(const TensorInfo& input,
425                                          const TensorInfo& output,
426                                          const SoftmaxDescriptor& descriptor,
427                                          Optional<std::string&> reasonIfUnsupported) const
428 {
429     ignore_unused(output);
430     ignore_unused(descriptor);
431     return IsSupportedForDataTypeRef(reasonIfUnsupported,
432                                      input.GetDataType(),
433                                      &TrueFunc<>,
434                                      &TrueFunc<>);
435 }
436
437 bool RefLayerSupport::IsSplitterSupported(const TensorInfo& input,
438                                           const ViewsDescriptor& descriptor,
439                                           Optional<std::string&> reasonIfUnsupported) const
440 {
441     ignore_unused(descriptor);
442     return IsSupportedForDataTypeRef(reasonIfUnsupported,
443                                      input.GetDataType(),
444                                      &TrueFunc<>,
445                                      &TrueFunc<>);
446 }
447
448 bool RefLayerSupport::IsSubtractionSupported(const TensorInfo& input0,
449                                              const TensorInfo& input1,
450                                              const TensorInfo& output,
451                                              Optional<std::string&> reasonIfUnsupported) const
452 {
453     ignore_unused(input1);
454     ignore_unused(output);
455     return IsSupportedForDataTypeRef(reasonIfUnsupported,
456                                      input0.GetDataType(),
457                                      &TrueFunc<>,
458                                      &TrueFunc<>);
459 }
460
461 } // namespace armnn