2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
6 #include "RefLayerSupport.hpp"
7 #include "RefBackendId.hpp"
9 #include <InternalTypes.hpp>
10 #include <LayerSupportCommon.hpp>
11 #include <armnn/Types.hpp>
13 #include <backendsCommon/LayerSupportRegistry.hpp>
15 #include <boost/core/ignore_unused.hpp>
17 using namespace boost;
25 ILayerSupportSharedPtr GetLayerSupportPointer()
27 static ILayerSupportSharedPtr instance{new RefLayerSupport};
31 static StaticRegistryInitializer<LayerSupportRegistry> g_RegisterHelper{
32 LayerSupportRegistryInstance(),
34 [](const EmptyInitializer&)
36 return GetLayerSupportPointer();
40 template<typename Float32Func, typename Uint8Func, typename ... Params>
41 bool IsSupportedForDataTypeRef(Optional<std::string&> reasonIfUnsupported,
43 Float32Func floatFuncPtr,
44 Uint8Func uint8FuncPtr,
47 return IsSupportedForDataTypeGeneric(reasonIfUnsupported,
49 &FalseFunc<Params...>,
52 std::forward<Params>(params)...);
55 } // anonymous namespace
57 bool RefLayerSupport::IsActivationSupported(const TensorInfo& input,
58 const TensorInfo& output,
59 const ActivationDescriptor& descriptor,
60 Optional<std::string&> reasonIfUnsupported) const
62 ignore_unused(output);
63 ignore_unused(descriptor);
64 return IsSupportedForDataTypeRef(reasonIfUnsupported,
70 bool RefLayerSupport::IsAdditionSupported(const TensorInfo& input0,
71 const TensorInfo& input1,
72 const TensorInfo& output,
73 Optional<std::string&> reasonIfUnsupported) const
75 ignore_unused(input1);
76 ignore_unused(output);
77 return IsSupportedForDataTypeRef(reasonIfUnsupported,
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
92 ignore_unused(output);
97 ignore_unused(descriptor);
98 return IsSupportedForDataTypeRef(reasonIfUnsupported,
104 bool RefLayerSupport::IsConstantSupported(const TensorInfo& output,
105 Optional<std::string&> reasonIfUnsupported) const
107 return IsSupportedForDataTypeRef(reasonIfUnsupported,
108 output.GetDataType(),
113 bool RefLayerSupport::IsConvertFp16ToFp32Supported(const TensorInfo& input,
114 const TensorInfo& output,
115 Optional<std::string&> reasonIfUnsupported) const
117 return (IsSupportedForDataTypeGeneric(reasonIfUnsupported,
120 &FalseInputFuncF32<>,
122 IsSupportedForDataTypeGeneric(reasonIfUnsupported,
123 output.GetDataType(),
124 &FalseOutputFuncF16<>,
129 bool RefLayerSupport::IsConvertFp32ToFp16Supported(const TensorInfo& input,
130 const TensorInfo& output,
131 Optional<std::string&> reasonIfUnsupported) const
133 return (IsSupportedForDataTypeGeneric(reasonIfUnsupported,
135 &FalseInputFuncF16<>,
138 IsSupportedForDataTypeGeneric(reasonIfUnsupported,
139 output.GetDataType(),
141 &FalseOutputFuncF32<>,
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
152 ignore_unused(output);
153 ignore_unused(descriptor);
154 ignore_unused(weights);
155 ignore_unused(biases);
156 return IsSupportedForDataTypeRef(reasonIfUnsupported,
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
169 ignore_unused(output);
170 ignore_unused(descriptor);
171 ignore_unused(weights);
172 ignore_unused(biases);
173 return IsSupportedForDataTypeRef(reasonIfUnsupported,
179 bool RefLayerSupport::IsDivisionSupported(const TensorInfo& input0,
180 const TensorInfo& input1,
181 const TensorInfo& output,
182 Optional<std::string&> reasonIfUnsupported) const
184 ignore_unused(input1);
185 ignore_unused(output);
186 return IsSupportedForDataTypeRef(reasonIfUnsupported,
187 input0.GetDataType(),
192 bool RefLayerSupport::IsFakeQuantizationSupported(const TensorInfo& input,
193 const FakeQuantizationDescriptor& descriptor,
194 Optional<std::string&> reasonIfUnsupported) const
196 ignore_unused(descriptor);
197 return IsSupportedForDataTypeRef(reasonIfUnsupported,
203 bool RefLayerSupport::IsFloorSupported(const TensorInfo& input,
204 const TensorInfo& output,
205 Optional<std::string&> reasonIfUnsupported) const
207 ignore_unused(output);
208 return IsSupportedForDataTypeRef(reasonIfUnsupported,
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
221 ignore_unused(output);
222 ignore_unused(weights);
223 ignore_unused(biases);
224 ignore_unused(descriptor);
225 return IsSupportedForDataTypeRef(reasonIfUnsupported,
231 bool RefLayerSupport::IsInputSupported(const TensorInfo& input,
232 Optional<std::string&> reasonIfUnsupported) const
234 return IsSupportedForDataTypeRef(reasonIfUnsupported,
240 bool RefLayerSupport::IsL2NormalizationSupported(const TensorInfo& input,
241 const TensorInfo& output,
242 const L2NormalizationDescriptor& descriptor,
243 Optional<std::string&> reasonIfUnsupported) const
245 ignore_unused(output);
246 ignore_unused(descriptor);
247 return IsSupportedForDataTypeRef(reasonIfUnsupported,
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
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);
309 bool RefLayerSupport::IsMeanSupported(const TensorInfo& input,
310 const TensorInfo& output,
311 const MeanDescriptor& descriptor,
312 Optional<std::string&> reasonIfUnsupported) const
314 ignore_unused(output);
315 ignore_unused(descriptor);
316 return IsSupportedForDataTypeRef(reasonIfUnsupported,
322 bool RefLayerSupport::IsMergerSupported(const std::vector<const TensorInfo*> inputs,
323 const OriginsDescriptor& descriptor,
324 Optional<std::string&> reasonIfUnsupported) const
326 ignore_unused(descriptor);
327 return IsSupportedForDataTypeRef(reasonIfUnsupported,
328 inputs[0]->GetDataType(),
333 bool RefLayerSupport::IsMultiplicationSupported(const TensorInfo& input0,
334 const TensorInfo& input1,
335 const TensorInfo& output,
336 Optional<std::string&> reasonIfUnsupported) const
338 ignore_unused(input1);
339 ignore_unused(output);
340 return IsSupportedForDataTypeRef(reasonIfUnsupported,
341 input0.GetDataType(),
346 bool RefLayerSupport::IsNormalizationSupported(const TensorInfo& input,
347 const TensorInfo& output,
348 const NormalizationDescriptor& descriptor,
349 Optional<std::string&> reasonIfUnsupported) const
351 ignore_unused(output);
352 ignore_unused(descriptor);
353 return IsSupportedForDataTypeRef(reasonIfUnsupported,
359 bool RefLayerSupport::IsOutputSupported(const TensorInfo& output,
360 Optional<std::string&> reasonIfUnsupported) const
362 return IsSupportedForDataTypeRef(reasonIfUnsupported,
363 output.GetDataType(),
368 bool RefLayerSupport::IsPadSupported(const TensorInfo& input,
369 const TensorInfo& output,
370 const PadDescriptor& descriptor,
371 Optional<std::string&> reasonIfUnsupported) const
373 ignore_unused(input);
374 ignore_unused(output);
375 ignore_unused(descriptor);
376 ignore_unused(reasonIfUnsupported);
380 bool RefLayerSupport::IsPermuteSupported(const TensorInfo& input,
381 const TensorInfo& output,
382 const PermuteDescriptor& descriptor,
383 Optional<std::string&> reasonIfUnsupported) const
385 ignore_unused(output);
386 ignore_unused(descriptor);
387 return IsSupportedForDataTypeRef(reasonIfUnsupported,
393 bool RefLayerSupport::IsPooling2dSupported(const TensorInfo& input,
394 const TensorInfo& output,
395 const Pooling2dDescriptor& descriptor,
396 Optional<std::string&> reasonIfUnsupported) const
398 ignore_unused(output);
399 ignore_unused(descriptor);
400 return IsSupportedForDataTypeRef(reasonIfUnsupported,
406 bool RefLayerSupport::IsReshapeSupported(const TensorInfo& input,
407 Optional<std::string&> reasonIfUnsupported) const
409 return IsSupportedForDataTypeRef(reasonIfUnsupported,
415 bool RefLayerSupport::IsResizeBilinearSupported(const TensorInfo& input,
416 Optional<std::string&> reasonIfUnsupported) const
418 return IsSupportedForDataTypeRef(reasonIfUnsupported,
424 bool RefLayerSupport::IsSoftmaxSupported(const TensorInfo& input,
425 const TensorInfo& output,
426 const SoftmaxDescriptor& descriptor,
427 Optional<std::string&> reasonIfUnsupported) const
429 ignore_unused(output);
430 ignore_unused(descriptor);
431 return IsSupportedForDataTypeRef(reasonIfUnsupported,
437 bool RefLayerSupport::IsSplitterSupported(const TensorInfo& input,
438 const ViewsDescriptor& descriptor,
439 Optional<std::string&> reasonIfUnsupported) const
441 ignore_unused(descriptor);
442 return IsSupportedForDataTypeRef(reasonIfUnsupported,
448 bool RefLayerSupport::IsSubtractionSupported(const TensorInfo& input0,
449 const TensorInfo& input1,
450 const TensorInfo& output,
451 Optional<std::string&> reasonIfUnsupported) const
453 ignore_unused(input1);
454 ignore_unused(output);
455 return IsSupportedForDataTypeRef(reasonIfUnsupported,
456 input0.GetDataType(),