ArmNN
 22.11
NeonLayerSupport.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "NeonLayerSupport.hpp"
7 #include "NeonBackendId.hpp"
9 
10 #include <armnn/Exceptions.hpp>
11 #include <armnn/Tensor.hpp>
12 #include <armnn/Types.hpp>
14 
15 #include <InternalTypes.hpp>
16 #include <LayerSupportCommon.hpp>
19 
20 #if defined(ARMCOMPUTENEON_ENABLED)
85 #endif
86 
87 namespace armnn
88 {
89 
90 namespace
91 {
92 
93 template< typename ... Args>
94 bool IsNeonBackendSupported(Optional<std::string&> reasonIfUnsupported, Args... args)
95 {
96  IgnoreUnused(reasonIfUnsupported, (args)...);
97 #if defined(ARMCOMPUTENEON_ENABLED)
98  return true;
99 #else
100  SetValueChecked(reasonIfUnsupported, "The armnn library has been built without NEON support");
101  return false;
102 #endif
103 }
104 
105 template<typename FloatFunc, typename Uint8Func, typename ... Params>
106 bool IsSupportedForDataTypeNeon(Optional<std::string&> reasonIfUnsupported,
107  DataType dataType,
108  FloatFunc floatFuncPtr,
109  Uint8Func uint8FuncPtr,
110  Params&&... params)
111 {
112  return IsNeonBackendSupported(reasonIfUnsupported) &&
113  IsSupportedForDataTypeGeneric(reasonIfUnsupported,
114  dataType,
115  floatFuncPtr,
116  floatFuncPtr,
117  uint8FuncPtr,
118  &FalseFunc<>,
119  &FalseFunc<>,
120  std::forward<Params>(params)...);
121 }
122 
123 #if defined(ARMCOMPUTENEON_ENABLED)
124 template<class FuncType, class... Args>
125 inline bool IsWorkloadSupported(FuncType& func, Optional<std::string&> reasonIfUnsupported, Args&&... args)
126 {
127  arm_compute::Status aclStatus = func(std::forward<Args>(args)...);
128  const bool supported = (aclStatus.error_code() == arm_compute::ErrorCode::OK);
129  if (!supported && reasonIfUnsupported)
130  {
131  reasonIfUnsupported.value() = aclStatus.error_description();
132  }
133  return supported;
134 }
135 
136 #define FORWARD_WORKLOAD_VALIDATE_FUNC(func, reasonIfUnsupported, ...) \
137  return IsWorkloadSupported(func, reasonIfUnsupported, __VA_ARGS__);
138 #else
139 #define FORWARD_WORKLOAD_VALIDATE_FUNC(func, reasonIfUnsupported, ...) \
140  return IsNeonBackendSupported(reasonIfUnsupported, __VA_ARGS__);
141 #endif
142 } // anonymous namespace
143 
145  : m_ModelContextPtr(modelContextPtr)
146 {
147 }
148 
150  : m_ModelContextPtr(nullptr)
151 {
152 }
153 
155  const std::vector<TensorInfo>& infos,
156  const BaseDescriptor& descriptor,
157  const Optional<LstmInputParamsInfo>& lstmParamsInfo,
158  const Optional<QuantizedLstmInputParamsInfo>& quantizedLstmParamsInfo,
159  Optional<std::string&> reasonIfUnsupported) const
160 {
161  switch (type)
162  {
164  return IsActivationSupported(infos[0],
165  infos[1],
166  *(PolymorphicDowncast<const ActivationDescriptor*>(&descriptor)),
167  reasonIfUnsupported);
168  case LayerType::Addition:
169  return IsAdditionSupported(infos[0], infos[1], infos[2], reasonIfUnsupported);
171  return IsArgMinMaxSupported(infos[0],
172  infos[1],
173  *(PolymorphicDowncast<const ArgMinMaxDescriptor*>(&descriptor)),
174  reasonIfUnsupported);
176  return IsBatchMatMulSupported(infos[0],
177  infos[1],
178  infos[2],
179  *(PolymorphicDowncast<const BatchMatMulDescriptor*>(&descriptor)),
180  reasonIfUnsupported);
182  return IsBatchNormalizationSupported(infos[0],
183  infos[1],
184  infos[2],
185  infos[3],
186  infos[4],
187  infos[5],
188  *(PolymorphicDowncast<const BatchNormalizationDescriptor*>
189  (&descriptor)),
190  reasonIfUnsupported);
192  return IsBatchToSpaceNdSupported(infos[0],
193  infos[1],
194  *(PolymorphicDowncast<const BatchToSpaceNdDescriptor*>(&descriptor)),
195  reasonIfUnsupported);
196  case LayerType::Cast:
197  return IsCastSupported(infos[0], infos[1], reasonIfUnsupported);
199  return IsChannelShuffleSupported(infos[0],
200  infos[1],
201  *(PolymorphicDowncast<const ChannelShuffleDescriptor*>(&descriptor)),
202  reasonIfUnsupported);
204  return IsComparisonSupported(infos[0],
205  infos[1],
206  infos[2],
207  *(PolymorphicDowncast<const ComparisonDescriptor*>(&descriptor)),
208  reasonIfUnsupported);
209  case LayerType::Concat:
210  {
211  std::vector<const TensorInfo*> inputInfos;
212  for (uint32_t i = 0; i < (infos.size() - 1); i++)
213  {
214  inputInfos.push_back(&infos[i]);
215  }
216  return IsConcatSupported(inputInfos,
217  infos[infos.size() - 1],
218  *(PolymorphicDowncast<const OriginsDescriptor*>(&descriptor)),
220  }
221  case LayerType::Constant:
222  return IsConstantSupported(infos[0], reasonIfUnsupported);
224  return IsConvertBf16ToFp32Supported(infos[0], infos[1], reasonIfUnsupported);
226  return IsConvertFp16ToFp32Supported(infos[0], infos[1], reasonIfUnsupported);
228  return IsConvertFp32ToBf16Supported(infos[0], infos[1], reasonIfUnsupported);
230  return IsConvertFp32ToFp16Supported(infos[0], infos[1], reasonIfUnsupported);
232  {
233  if (infos.size() != 4)
234  {
235  throw InvalidArgumentException("Invalid number of TransposeConvolution2d TensorInfos. "
236  "TensorInfos should be of format: {input, output, weights, biases}.");
237  }
238 
239  auto desc = *(PolymorphicDowncast<const Convolution2dDescriptor*>(&descriptor));
240  if (infos[3] == TensorInfo())
241  {
242  return IsConvolution2dSupported(infos[0],
243  infos[1],
244  desc,
245  infos[2],
246  EmptyOptional(),
247  reasonIfUnsupported);
248  }
249  else
250  {
251  return IsConvolution2dSupported(infos[0],
252  infos[1],
253  desc,
254  infos[2],
255  infos[3],
256  reasonIfUnsupported);
257  }
258  }
260  {
261  if (infos.size() != 4)
262  {
263  throw InvalidArgumentException("Invalid number of Convolution3d TensorInfos. "
264  "TensorInfos should be of format: {input, output, weights, biases}.");
265  }
266 
267  auto desc = *(PolymorphicDowncast<const Convolution3dDescriptor*>(&descriptor));
268  if (infos[3] == TensorInfo())
269  {
270  return IsConvolution3dSupported(infos[0],
271  infos[1],
272  desc,
273  infos[2],
274  EmptyOptional(),
275  reasonIfUnsupported);
276  }
277  else
278  {
279  return IsConvolution3dSupported(infos[0],
280  infos[1],
281  desc,
282  infos[2],
283  infos[3],
284  reasonIfUnsupported);
285  }
286  }
288  return IsDepthToSpaceSupported(infos[0],
289  infos[1],
290  *(PolymorphicDowncast<const DepthToSpaceDescriptor*>(&descriptor)),
291  reasonIfUnsupported);
293  {
294  if (infos.size() != 4)
295  {
296  throw InvalidArgumentException("Invalid number of DepthwiseConvolution2d TensorInfos. "
297  "TensorInfos should be of format: {input, output, weights, biases}.");
298  }
299 
300  auto desc = *(PolymorphicDowncast<const DepthwiseConvolution2dDescriptor*>(&descriptor));
301  if (infos[3] == TensorInfo())
302  {
303  return IsDepthwiseConvolutionSupported(infos[0],
304  infos[1],
305  desc,
306  infos[2],
307  EmptyOptional(),
308  reasonIfUnsupported);
309  }
310  else
311  {
312  return IsDepthwiseConvolutionSupported(infos[0],
313  infos[1],
314  desc,
315  infos[2],
316  infos[3],
317  reasonIfUnsupported);
318  }
319  }
321  return IsDequantizeSupported(infos[0], infos[1], reasonIfUnsupported);
323  {
324  auto desc = *(PolymorphicDowncast<const DetectionPostProcessDescriptor*>(&descriptor));
326  infos[1],
327  infos[2],
328  infos[3],
329  infos[4],
330  infos[5],
331  infos[6],
332  desc,
333  reasonIfUnsupported);
334  }
335  case LayerType::Division:
336  return IsDivisionSupported(infos[0], infos[1], infos[2], reasonIfUnsupported);
338  return IsElementwiseUnarySupported(infos[0],
339  infos[1],
340  *(PolymorphicDowncast<const ElementwiseUnaryDescriptor*>(&descriptor)),
341  reasonIfUnsupported);
342  case LayerType::Fill:
343  return IsFillSupported(infos[0],
344  infos[1],
345  *(PolymorphicDowncast<const FillDescriptor*>(&descriptor)),
346  reasonIfUnsupported);
347  case LayerType::Floor:
348  return IsFloorSupported(infos[0], infos[1], reasonIfUnsupported);
350  return IsFullyConnectedSupported(infos[0],
351  infos[1],
352  infos[2],
353  infos[3],
354  *(PolymorphicDowncast<const FullyConnectedDescriptor*>(&descriptor)),
355  reasonIfUnsupported);
356  case LayerType::Gather:
357  return IsGatherSupported(infos[0],
358  infos[1],
359  infos[2],
360  *(PolymorphicDowncast<const GatherDescriptor*>(&descriptor)),
361  reasonIfUnsupported);
362  case LayerType::GatherNd:
363  return IsGatherNdSupported(infos[0],
364  infos[1],
365  infos[2],
366  reasonIfUnsupported);
367  case LayerType::Input:
368  return IsInputSupported(infos[0], reasonIfUnsupported);
370  return IsInstanceNormalizationSupported(infos[0],
371  infos[1],
372  *(PolymorphicDowncast<const InstanceNormalizationDescriptor*>
373  (&descriptor)),
374  reasonIfUnsupported);
376  return IsL2NormalizationSupported(infos[0],
377  infos[1],
378  *(PolymorphicDowncast<const L2NormalizationDescriptor*>(&descriptor)),
379  reasonIfUnsupported);
381  return IsLogicalBinarySupported(infos[0],
382  infos[1],
383  infos[2],
384  *(PolymorphicDowncast<const LogicalBinaryDescriptor*>(&descriptor)),
385  reasonIfUnsupported);
387  return IsLogSoftmaxSupported(infos[0],
388  infos[1],
389  *(PolymorphicDowncast<const LogSoftmaxDescriptor*>(&descriptor)),
390  reasonIfUnsupported);
391  case LayerType::Lstm:
392  return IsLstmSupported(infos[0],
393  infos[1],
394  infos[2],
395  infos[3],
396  infos[4],
397  infos[5],
398  infos[6],
399  *(PolymorphicDowncast<const LstmDescriptor*>(&descriptor)),
400  lstmParamsInfo.value(),
402  case LayerType::Map:
403  return true;
404  case LayerType::Maximum:
405  return IsMaximumSupported(infos[0], infos[1], infos[2], reasonIfUnsupported);
406  case LayerType::Mean:
407  return IsMeanSupported(infos[0],
408  infos[1],
409  *(PolymorphicDowncast<const MeanDescriptor*>(&descriptor)),
410  reasonIfUnsupported);
411  case LayerType::MemCopy:
412  return LayerSupportBase::IsMemCopySupported(infos[0], infos[1], reasonIfUnsupported);
414  return LayerSupportBase::IsMemImportSupported(infos[0], infos[1], reasonIfUnsupported);
415  case LayerType::Merge:
416  return LayerSupportBase::IsMergeSupported(infos[0],
417  infos[1],
418  infos[2],
419  reasonIfUnsupported);
420  case LayerType::Minimum:
421  return IsMinimumSupported(infos[0], infos[1], infos[2], reasonIfUnsupported);
423  return IsMultiplicationSupported(infos[0], infos[1], infos[2], reasonIfUnsupported);
425  return IsNormalizationSupported(infos[0],
426  infos[1],
427  *(PolymorphicDowncast<const NormalizationDescriptor*>(&descriptor)),
428  reasonIfUnsupported);
429  case LayerType::Output:
430  return IsOutputSupported(infos[0], reasonIfUnsupported);
431  case LayerType::Pad:
432  return IsPadSupported(infos[0],
433  infos[1],
434  *(PolymorphicDowncast<const PadDescriptor*>(&descriptor)),
435  reasonIfUnsupported);
436  case LayerType::Permute:
437  return IsPermuteSupported(infos[0],
438  infos[1],
439  *(PolymorphicDowncast<const PermuteDescriptor*>(&descriptor)),
440  reasonIfUnsupported);
442  return IsPooling2dSupported(infos[0],
443  infos[1],
444  *(PolymorphicDowncast<const Pooling2dDescriptor*>(&descriptor)),
445  reasonIfUnsupported);
447  return IsPooling3dSupported(infos[0],
448  infos[1],
449  *(PolymorphicDowncast<const Pooling3dDescriptor*>(&descriptor)),
450  reasonIfUnsupported);
451  case LayerType::Prelu:
452  return IsPreluSupported(infos[0], infos[1], infos[2], reasonIfUnsupported);
453  case LayerType::QLstm:
454  return IsQLstmSupported(infos[0],
455  infos[1],
456  infos[2],
457  infos[3],
458  infos[4],
459  infos[5],
460  *(PolymorphicDowncast<const QLstmDescriptor*>(&descriptor)),
461  lstmParamsInfo.value(),
463  case LayerType::Quantize:
464  return IsQuantizeSupported(infos[0], infos[1], reasonIfUnsupported);
466  return IsQuantizedLstmSupported(infos[0],
467  infos[1],
468  infos[2],
469  infos[3],
470  infos[4],
471  quantizedLstmParamsInfo.value(),
473  case LayerType::Rank:
474  return true;
475  case LayerType::Reshape:
476  return IsReshapeSupported(infos[0],
477  infos[1],
478  *(PolymorphicDowncast<const ReshapeDescriptor*>(&descriptor)),
479  reasonIfUnsupported);
480  case LayerType::Resize:
481  return IsResizeSupported(infos[0],
482  infos[1],
483  *(PolymorphicDowncast<const ResizeDescriptor*>(&descriptor)),
484  reasonIfUnsupported);
485  case LayerType::Reduce:
486  return IsReduceSupported(infos[0],
487  infos[1],
488  *(PolymorphicDowncast<const ReduceDescriptor*>(&descriptor)),
489  reasonIfUnsupported);
490  case LayerType::Shape:
491  return LayerSupportBase::IsShapeSupported(infos[0],
492  infos[1],
493  reasonIfUnsupported);
494  case LayerType::Slice:
495  return IsSliceSupported(infos[0],
496  infos[1],
497  *(PolymorphicDowncast<const SliceDescriptor*>(&descriptor)),
498  reasonIfUnsupported);
499  case LayerType::Softmax:
500  return IsSoftmaxSupported(infos[0],
501  infos[1],
502  *(PolymorphicDowncast<const SoftmaxDescriptor*>(&descriptor)),
503  reasonIfUnsupported);
505  return IsSpaceToBatchNdSupported(infos[0],
506  infos[1],
507  *(PolymorphicDowncast<const SpaceToBatchNdDescriptor*>(&descriptor)),
508  reasonIfUnsupported);
510  return IsSpaceToDepthSupported(infos[0],
511  infos[1],
512  *(PolymorphicDowncast<const SpaceToDepthDescriptor*>(&descriptor)),
513  reasonIfUnsupported);
514  case LayerType::Splitter:
515  {
516  std::vector<TensorInfo> outputInfos;
517  for (uint32_t i = 1; i < infos.size(); i++)
518  {
519  outputInfos.push_back(infos[i]);
520  }
521  return IsSplitterSupported(infos[0],
522  {outputInfos.begin(), outputInfos.end()},
523  *(PolymorphicDowncast<const ViewsDescriptor*>(&descriptor)),
525  }
526  case LayerType::Stack:
527  {
528  std::vector<const TensorInfo*> inputInfos;
529  for (uint32_t i = 0; i < infos.size() - 1; i++)
530  {
531  inputInfos.push_back(&infos[i]);
532  }
533  return IsStackSupported(inputInfos,
534  infos[infos.size() - 1],
535  *(PolymorphicDowncast<const StackDescriptor*>(&descriptor)),
537  }
539  return IsStridedSliceSupported(infos[0],
540  infos[1],
541  *(PolymorphicDowncast<const StridedSliceDescriptor*>(&descriptor)),
542  reasonIfUnsupported);
544  return IsSubtractionSupported(infos[0], infos[1], infos[2], reasonIfUnsupported);
546  return IsTransposeSupported(infos[0],
547  infos[1],
548  *(PolymorphicDowncast<const TransposeDescriptor*>(&descriptor)),
549  reasonIfUnsupported);
551  {
552  if (infos.size() != 4)
553  {
554  throw InvalidArgumentException("Invalid number of TransposeConvolution2d TensorInfos. "
555  "TensorInfos should be of format: {input, output, weights, biases}.");
556  }
557 
558  auto desc = *(PolymorphicDowncast<const TransposeConvolution2dDescriptor*>(&descriptor));
559  if (infos[3] == TensorInfo())
560  {
561  return IsTransposeConvolution2dSupported(infos[0],
562  infos[1],
563  desc,
564  infos[2],
565  EmptyOptional(),
566  reasonIfUnsupported);
567  }
568  else
569  {
570  return IsTransposeConvolution2dSupported(infos[0],
571  infos[1],
572  desc,
573  infos[2],
574  infos[3],
575  reasonIfUnsupported);
576  }
577  }
580  infos[1],
581  infos[2],
582  infos[3],
583  infos[4],
584  infos[5],
585  *(PolymorphicDowncast<const
586  UnidirectionalSequenceLstmDescriptor*>(&descriptor)),
587  lstmParamsInfo.value(),
589  case LayerType::Unmap:
590  return true;
591  default:
592  // layers not supported in neon by default:
593  // debug, fakequantization, precompiled,
594  // standin, switch
595  return false;
596  }
597 }
598 
600  const TensorInfo& output,
602  Optional<std::string&> reasonIfUnsupported) const
603 {
604  IgnoreUnused(descriptor);
606  reasonIfUnsupported,
607  input,
608  output,
609  descriptor);
610 }
611 
613  const TensorInfo& input1,
614  const TensorInfo& output,
615  Optional<std::string&> reasonIfUnsupported) const
616 {
618  reasonIfUnsupported,
619  input0,
620  input1,
621  output,
622  nullptr);
623 }
624 
626  const TensorInfo& output,
628  Optional<std::string&> reasonIfUnsupported) const
629 {
631  reasonIfUnsupported,
632  input,
633  output,
634  descriptor);
635 }
636 
638  const TensorInfo& inputY,
639  const TensorInfo& output,
641  Optional<std::string&> reasonIfUnsupported) const
642 {
644  reasonIfUnsupported,
645  inputX,
646  inputY,
647  output,
648  descriptor);
649 }
650 
652  const TensorInfo& output,
653  const TensorInfo& mean,
654  const TensorInfo& var,
655  const TensorInfo& beta,
656  const TensorInfo& gamma,
658  Optional<std::string&> reasonIfUnsupported) const
659 {
661  reasonIfUnsupported,
662  input,
663  output,
664  mean,
665  var,
666  beta,
667  gamma,
668  descriptor,
669  nullptr);
670 }
671 
673  const TensorInfo& output,
675  Optional<std::string&> reasonIfUnsupported) const
676 {
678  reasonIfUnsupported,
679  input,
680  output,
681  descriptor);
682 }
683 
685  const TensorInfo& output,
686  Optional<std::string&> reasonIfUnsupported) const
687 {
689  reasonIfUnsupported,
690  input,
691  output);
692 }
693 
695  const TensorInfo& output,
697  Optional<std::string&> reasonIfUnsupported) const
698 {
700  reasonIfUnsupported,
701  input,
702  output,
703  descriptor);
704 }
705 
707  const TensorInfo& input1,
708  const TensorInfo& output,
710  Optional<std::string&> reasonIfUnsupported) const
711 {
712 
714  reasonIfUnsupported,
715  input0,
716  input1,
717  output,
718  descriptor);
719 }
720 
721 bool NeonLayerSupport::IsConcatSupported(const std::vector<const TensorInfo*> inputs,
722  const TensorInfo& output,
724  Optional<std::string&> reasonIfUnsupported) const
725 {
726  if (descriptor.GetNumDimensions() <= descriptor.GetConcatAxis())
727  {
728  SetValueChecked(reasonIfUnsupported, "Neon Concat: Concat axis > Number of dimensions.");
729  return false;
730  }
731 
732  unsigned int concatInnerAxis = (descriptor.GetNumDimensions() - descriptor.GetConcatAxis()) - 1;
733  if(concatInnerAxis < 3) // Width, height, or channels
734  {
736  reasonIfUnsupported,
737  inputs,
738  output,
739  descriptor);
740  }
741  else if (concatInnerAxis == 3)
742  {
743  for (auto& input : inputs)
744  {
745  if (input && !output.IsTypeSpaceMatch(*input)) // Cannot use sub-tensors if the types are not same space
746  {
747  SetValueChecked(reasonIfUnsupported, "Neon Concat: Types and quantization parameters must match.");
748  return false;
749  }
750  }
751  return true; // Sub-tensors support concat along batch
752  }
753  else // > 4 dimensions not supported.
754  {
755  SetValueChecked(reasonIfUnsupported, "Neon Concat: Maximum of 4 dimensions supported.");
756  return false;
757  }
758 }
759 
761  Optional<std::string&> reasonIfUnsupported) const
762 {
764  reasonIfUnsupported,
765  output);
766 }
767 
769  const TensorInfo& output,
770  Optional<std::string&> reasonIfUnsupported) const
771 {
772  armnn::IgnoreUnused(input);
773  armnn::IgnoreUnused(output);
774  armnn::IgnoreUnused(reasonIfUnsupported);
775  return true;
776 }
777 
779  const TensorInfo& output,
780  Optional<std::string&> reasonIfUnsupported) const
781 {
782  armnn::IgnoreUnused(input);
783  armnn::IgnoreUnused(output);
784  armnn::IgnoreUnused(reasonIfUnsupported);
785  return true;
786 }
787 
789  const TensorInfo& output,
790  Optional<std::string&> reasonIfUnsupported) const
791 {
792  armnn::IgnoreUnused(input);
793  armnn::IgnoreUnused(output);
794  armnn::IgnoreUnused(reasonIfUnsupported);
795  return true;
796 }
797 
799  const TensorInfo& output,
800  Optional<std::string&> reasonIfUnsupported) const
801 {
802  armnn::IgnoreUnused(input);
803  armnn::IgnoreUnused(output);
804  armnn::IgnoreUnused(reasonIfUnsupported);
805  return true;
806 }
807 
809  const TensorInfo& output,
811  const TensorInfo& weights,
813  Optional<std::string&> reasonIfUnsupported) const
814 {
815  bool isFastMathEnabled = false;
816 #if defined(ARMCOMPUTENEON_ENABLED)
817  if (m_ModelContextPtr)
818  {
819  if (m_ModelContextPtr.get() != nullptr)
820  {
821  auto modelOptions = dynamic_cast<NeonBackendModelContext*>(m_ModelContextPtr.get());
822  if (modelOptions)
823  {
824  isFastMathEnabled = modelOptions->IsFastMathEnabled();
825  }
826  }
827  }
828 #endif
829 
831  reasonIfUnsupported,
832  input,
833  output,
834  descriptor,
835  weights,
836  biases,
837  isFastMathEnabled,
838  nullptr);
839 }
840 
842  const TensorInfo& output,
844  const TensorInfo& weights,
846  Optional<std::string&> reasonIfUnsupported) const
847 {
848  bool isFastMathEnabled = false;
849 #if defined(ARMCOMPUTENEON_ENABLED)
850  if (m_ModelContextPtr)
851  {
852  if (m_ModelContextPtr.get() != nullptr)
853  {
854  auto modelOptions = dynamic_cast<NeonBackendModelContext*>(m_ModelContextPtr.get());
855  if (modelOptions)
856  {
857  isFastMathEnabled = modelOptions->IsFastMathEnabled();
858  }
859  }
860  }
861 #endif
862 
864  reasonIfUnsupported,
865  input,
866  output,
867  descriptor,
868  weights,
869  biases,
870  isFastMathEnabled,
871  nullptr);
872 }
873 
875  const TensorInfo& output,
877  Optional<std::string&> reasonIfUnsupported) const
878 {
880  reasonIfUnsupported,
881  input,
882  output,
883  descriptor);
884 }
885 
887  const TensorInfo& output,
889  const TensorInfo& weights,
891  Optional<std::string&> reasonIfUnsupported) const
892 {
894  reasonIfUnsupported,
895  input,
896  output,
897  descriptor,
898  weights,
899  biases,
900  nullptr);
901 }
902 
904  const TensorInfo& output,
905  Optional<std::string&> reasonIfUnsupported) const
906 {
908  reasonIfUnsupported,
909  input,
910  output);
911 }
912 
914  const TensorInfo& output,
916  const TensorInfo& weights,
918  Optional<std::string&> reasonIfUnsupported) const
919 {
921  reasonIfUnsupported,
922  input,
923  output,
924  descriptor,
925  weights,
926  biases,
927  nullptr);
928 }
929 
931  const TensorInfo& output,
933  Optional<std::string&> reasonIfUnsupported) const
934 {
935  switch(descriptor.m_Operation)
936  {
937  case UnaryOperation::Abs:
939  reasonIfUnsupported,
940  input,
941  output);
942  case UnaryOperation::Exp:
944  reasonIfUnsupported,
945  input,
946  output);
949  reasonIfUnsupported,
950  input,
951  output);
952  case UnaryOperation::Log:
954  reasonIfUnsupported,
955  input,
956  output);
957  case UnaryOperation::Neg:
959  reasonIfUnsupported,
960  input,
961  output);
964  reasonIfUnsupported,
965  input,
966  output);
967  case UnaryOperation::Sin:
969  reasonIfUnsupported,
970  input,
971  output);
974  reasonIfUnsupported,
975  input,
976  output);
977  default:
978  return false;
979  }
980 }
981 
983  const TensorInfo& output,
984  const FillDescriptor& descriptor,
985  Optional<std::string&> reasonIfUnsupported) const
986 {
987  armnn::IgnoreUnused(input);
988  armnn::IgnoreUnused(output);
989  armnn::IgnoreUnused(descriptor);
990 
991  return IsNeonBackendSupported(reasonIfUnsupported);
992 }
993 
995  const TensorInfo& output,
996  Optional<std::string&> reasonIfUnsupported) const
997 {
998  armnn::IgnoreUnused(output);
999  return IsNeonBackendSupported(reasonIfUnsupported) &&
1000  IsSupportedForDataTypeGeneric(reasonIfUnsupported,
1001  input.GetDataType(),
1002  &FalseFuncF16<>,
1003  &TrueFunc<>,
1004  &FalseFuncU8<>,
1005  &FalseFuncI32<>,
1006  &FalseFuncU8<>);
1007 }
1008 
1010  const TensorInfo& output,
1011  const TensorInfo& weights,
1012  const TensorInfo& biases,
1014  Optional<std::string&> reasonIfUnsupported) const
1015 {
1017  reasonIfUnsupported,
1018  input,
1019  output,
1020  weights,
1021  biases,
1022  descriptor,
1023  nullptr);
1024 }
1025 
1027  const TensorInfo& input1,
1028  const TensorInfo& output,
1030  Optional<std::string&> reasonIfUnsupported) const
1031 {
1033  reasonIfUnsupported,
1034  input0,
1035  input1,
1036  output,
1037  descriptor);
1038 }
1039 
1041  const TensorInfo& input1,
1042  const TensorInfo& output,
1043  Optional<std::string&> reasonIfUnsupported) const
1044 {
1046  reasonIfUnsupported,
1047  input0,
1048  input1,
1049  output);
1050 }
1051 
1053  Optional<std::string&> reasonIfUnsupported) const
1054 {
1055  return IsNeonBackendSupported(reasonIfUnsupported, input);
1056 }
1057 
1059  const TensorInfo& output,
1061  Optional<std::string&> reasonIfUnsupported) const
1062 {
1064  reasonIfUnsupported,
1065  input,
1066  output,
1067  descriptor);
1068 }
1069 
1071  const TensorInfo& output,
1073  Optional<std::string&> reasonIfUnsupported) const
1074 {
1075  FORWARD_WORKLOAD_VALIDATE_FUNC(NeonL2NormalizationWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
1076 }
1077 
1079  const TensorInfo& input1,
1080  const TensorInfo& output,
1082  Optional<std::string&> reasonIfUnsupported) const
1083 {
1084  switch(descriptor.m_Operation)
1085  {
1088  reasonIfUnsupported,
1089  input0,
1090  input1,
1091  output);
1094  reasonIfUnsupported,
1095  input0,
1096  input1,
1097  output);
1098  default:
1099  return false;
1100  }
1101 }
1102 
1104  const TensorInfo& output,
1106  Optional<std::string&> reasonIfUnsupported) const
1107 {
1108  FORWARD_WORKLOAD_VALIDATE_FUNC(NeonLogSoftmaxWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
1109 }
1110 
1112  const TensorInfo& outputStateIn,
1113  const TensorInfo& cellStateIn,
1114  const TensorInfo& scratchBuffer,
1115  const TensorInfo& outputStateOut,
1116  const TensorInfo& cellStateOut,
1117  const TensorInfo& output,
1118  const LstmDescriptor& descriptor,
1120  Optional<std::string&> reasonIfUnsupported) const
1121 {
1123  reasonIfUnsupported,
1124  input,
1125  outputStateIn,
1126  cellStateIn,
1127  scratchBuffer,
1128  outputStateOut,
1129  cellStateOut,
1130  output,
1131  descriptor,
1132  paramsInfo);
1133 }
1134 
1136  const TensorInfo& input1,
1137  const TensorInfo& output,
1138  Optional<std::string&> reasonIfUnsupported) const
1139 {
1141  reasonIfUnsupported,
1142  input0,
1143  input1,
1144  output);
1145 }
1146 
1148  const TensorInfo& output,
1149  const MeanDescriptor& descriptor,
1150  Optional<std::string&> reasonIfUnsupported) const
1151 {
1153  reasonIfUnsupported,
1154  input,
1155  output,
1156  descriptor);
1157 }
1158 
1160  const TensorInfo& input1,
1161  const TensorInfo& output,
1162  Optional<std::string&> reasonIfUnsupported) const
1163 {
1165  reasonIfUnsupported,
1166  input0,
1167  input1,
1168  output);
1169 }
1170 
1172  const TensorInfo& input1,
1173  const TensorInfo& output,
1174  Optional<std::string&> reasonIfUnsupported) const
1175 {
1177  reasonIfUnsupported,
1178  input0,
1179  input1,
1180  output,
1181  nullptr);
1182 }
1183 
1185  const TensorInfo& input1,
1186  const TensorInfo& output,
1187  Optional<std::string&> reasonIfUnsupported) const
1188 {
1190  reasonIfUnsupported,
1191  input0,
1192  input1,
1193  output,
1194  nullptr);
1195 }
1196 
1198  const TensorInfo& output,
1200  Optional<std::string&> reasonIfUnsupported) const
1201 {
1203  reasonIfUnsupported,
1204  input,
1205  output,
1206  descriptor);
1207 }
1208 
1210  Optional<std::string&> reasonIfUnsupported) const
1211 {
1212  return IsNeonBackendSupported(reasonIfUnsupported, output);
1213 }
1214 
1216  const TensorInfo& output,
1217  const PadDescriptor& descriptor,
1218  Optional<std::string&> reasonIfUnsupported) const
1219 {
1221  reasonIfUnsupported,
1222  input,
1223  output,
1224  descriptor);
1225 }
1226 
1228  const TensorInfo& output,
1230  Optional<std::string&> reasonIfUnsupported) const
1231 {
1232  FORWARD_WORKLOAD_VALIDATE_FUNC(NeonPermuteWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
1233 }
1234 
1236  const TensorInfo& output,
1238  Optional<std::string&> reasonIfUnsupported) const
1239 {
1240  FORWARD_WORKLOAD_VALIDATE_FUNC(NeonPooling2dWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
1241 }
1242 
1244  const TensorInfo& output,
1246  Optional<std::string&> reasonIfUnsupported) const
1247 {
1248  FORWARD_WORKLOAD_VALIDATE_FUNC(NeonPooling3dWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
1249 }
1250 
1252  const armnn::TensorInfo &alpha,
1253  const armnn::TensorInfo &output,
1254  armnn::Optional<std::string &> reasonIfUnsupported) const
1255 {
1256  FORWARD_WORKLOAD_VALIDATE_FUNC(NeonPreluWorkloadValidate, reasonIfUnsupported, input, alpha, output);
1257 }
1258 
1262  const TensorInfo& outputStateOut,
1263  const TensorInfo& cellStateOut,
1264  const TensorInfo& output,
1265  const QLstmDescriptor& descriptor,
1267  Optional<std::string&> reasonIfUnsupported) const
1268 {
1269  // Check required here in order to pass IsLayerSupported for datatypes tests
1270  if (input.GetDataType() == armnn::DataType::QAsymmS8 &&
1271  previousOutputIn.GetDataType() == armnn::DataType::QAsymmS8 &&
1272  previousCellStateIn.GetDataType() == armnn::DataType::QSymmS16 &&
1273  outputStateOut.GetDataType() == armnn::DataType::QAsymmS8 &&
1274  cellStateOut.GetDataType() == armnn::DataType::QSymmS16 &&
1276  {
1278  reasonIfUnsupported,
1279  input,
1280  previousCellStateIn,
1281  previousOutputIn,
1282  cellStateOut,
1283  outputStateOut,
1284  output,
1285  descriptor,
1286  paramsInfo);
1287  }
1288  else
1289  {
1290  return false;
1291  }
1292 }
1293 
1295  const TensorInfo& output,
1296  Optional<std::string&> reasonIfUnsupported) const
1297 {
1299  reasonIfUnsupported,
1300  input,
1301  output);
1302 }
1303 
1305  const TensorInfo& cellStateIn,
1306  const TensorInfo& outputStateIn,
1307  const TensorInfo& cellStateOut,
1308  const TensorInfo& outputStateOut,
1310  Optional<std::string&> reasonIfUnsupported) const
1311 {
1313  reasonIfUnsupported,
1314  input,
1315  cellStateIn,
1316  outputStateIn,
1317  cellStateOut,
1318  outputStateOut,
1319  paramsInfo);
1320 }
1321 
1323  const TensorInfo& output,
1325  Optional<std::string&> reasonIfUnsupported) const
1326 {
1328  reasonIfUnsupported,
1329  input,
1330  output,
1331  descriptor);
1332 }
1333 
1335  const TensorInfo& output,
1337  Optional<std::string&> reasonIfUnsupported) const
1338 {
1339  armnn::IgnoreUnused(descriptor);
1341  reasonIfUnsupported,
1342  input,
1343  output);
1344 }
1345 
1347  const TensorInfo& output,
1349  Optional<std::string&> reasonIfUnsupported) const
1350 {
1352  reasonIfUnsupported,
1353  input,
1354  output,
1355  descriptor);
1356 }
1357 
1359  const TensorInfo& output,
1360  const SliceDescriptor& descriptor,
1361  Optional<std::string&> reasonIfUnsupported) const
1362 {
1364  reasonIfUnsupported,
1365  input,
1366  output,
1367  descriptor);
1368 }
1369 
1371  const TensorInfo& output,
1373  Optional<std::string&> reasonIfUnsupported) const
1374 {
1375  FORWARD_WORKLOAD_VALIDATE_FUNC(NeonSoftmaxWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
1376 }
1377 
1379  const TensorInfo& output,
1381  Optional<std::string&> reasonIfUnsupported) const
1382 {
1384  reasonIfUnsupported,
1385  input,
1386  output,
1387  descriptor);
1388 }
1389 
1391  const TensorInfo& output,
1393  Optional<std::string&> reasonIfUnsupported) const
1394 {
1396  reasonIfUnsupported,
1397  input,
1398  output,
1399  descriptor);
1400 }
1401 
1403  const std::vector<std::reference_wrapper<TensorInfo>>& outputs,
1404  const ViewsDescriptor& descriptor,
1405  Optional<std::string&> reasonIfUnsupported) const
1406 {
1407 #if defined(ARMCOMPUTENEON_ENABLED)
1408  // Split along the last dimension, cannot use sub-tensors
1409  // as width and height of the sub-tensors do not match
1410  // the width and height of the parent tensor
1411  // in case of input with more than 2D.
1412  std::set<unsigned int> splitAxis = ComputeSplitAxis(descriptor, input.GetShape());
1413  if (descriptor.GetNumDimensions() > 2 && splitAxis.size() == 1 &&
1414  *splitAxis.begin() == descriptor.GetNumDimensions() - 1 )
1415  {
1417  reasonIfUnsupported,
1418  input,
1419  outputs,
1420  *splitAxis.begin());
1421  }
1422 #endif
1423  IgnoreUnused(descriptor);
1424  for (auto output : outputs)
1425  {
1426  if (!input.IsTypeSpaceMatch(output)) // Cannot use sub-tensors if the types are not same space
1427  {
1428  SetValueChecked(reasonIfUnsupported, "Neon Splitter: Types and quantization parameters must match.");
1429  return false;
1430  }
1431  }
1432  return true;
1433 }
1434 
1435 bool NeonLayerSupport::IsStackSupported(const std::vector<const TensorInfo*>& inputs,
1436  const TensorInfo& output,
1437  const StackDescriptor& descriptor,
1438  Optional<std::string&> reasonIfUnsupported) const
1439 {
1441  reasonIfUnsupported,
1442  inputs,
1443  output,
1444  descriptor);
1445 }
1446 
1448  const TensorInfo& output,
1450  Optional<std::string&> reasonIfUnsupported) const
1451 {
1453  reasonIfUnsupported,
1454  input,
1455  output,
1456  descriptor);
1457 }
1458 
1460  const TensorInfo& input1,
1461  const TensorInfo& output,
1462  Optional<std::string&> reasonIfUnsupported) const
1463 {
1465  reasonIfUnsupported,
1466  input0,
1467  input1,
1468  output,
1469  nullptr);
1470 }
1471 
1473  const TensorInfo& output,
1475  const TensorInfo& weights,
1477  Optional<std::string&> reasonIfUnsupported) const
1478 {
1480  reasonIfUnsupported,
1481  input,
1482  output,
1483  descriptor,
1484  weights,
1485  biases);
1486 }
1487 
1489  const TensorInfo& output,
1491  Optional<std::string&> reasonIfUnsupported) const
1492 {
1493  FORWARD_WORKLOAD_VALIDATE_FUNC(NeonTransposeWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
1494 }
1495 
1497  const TensorInfo& outputStateIn,
1498  const TensorInfo& cellStateIn,
1499  const TensorInfo& outputStateOut,
1500  const TensorInfo& cellStateOut,
1501  const TensorInfo& output,
1504  Optional<std::string&> reasonIfUnsupported) const
1505 {
1506  if (input.GetDataType() == armnn::DataType::QAsymmS8 &&
1507  outputStateIn.GetDataType() == armnn::DataType::QAsymmS8 &&
1508  cellStateIn.GetDataType() == armnn::DataType::QSymmS16 &&
1509  outputStateOut.GetDataType() == armnn::DataType::QAsymmS8 &&
1510  cellStateOut.GetDataType() == armnn::DataType::QSymmS16 &&
1512  {
1514  reasonIfUnsupported,
1515  input,
1516  outputStateIn,
1517  cellStateIn,
1518  outputStateOut,
1519  cellStateOut,
1520  output,
1521  descriptor,
1522  paramsInfo);
1523  }
1524  else
1525  {
1527  reasonIfUnsupported,
1528  input,
1529  outputStateIn,
1530  cellStateIn,
1531  outputStateOut,
1532  cellStateOut,
1533  output,
1534  descriptor,
1535  paramsInfo);
1536  }
1537 }
1538 
1539 } // namespace armnn
arm_compute::Status NeonGatherWorkloadValidate(const TensorInfo &input, const TensorInfo &indices, const TensorInfo &output, const GatherDescriptor &descriptor)
arm_compute::Status NeonNegWorkloadValidate(const TensorInfo &input, const TensorInfo &output)
bool IsConcatSupported(const std::vector< const TensorInfo *> inputs, const TensorInfo &output, const OriginsDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
UnaryOperation m_Operation
Specifies the elementwiseUnary operation to execute.
bool IsSliceSupported(const TensorInfo &input, const TensorInfo &output, const SliceDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsSoftmaxSupported(const TensorInfo &input, const TensorInfo &output, const SoftmaxDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsConvolution2dSupported(const TensorInfo &input, const TensorInfo &output, const Convolution2dDescriptor &descriptor, const TensorInfo &weights, const Optional< TensorInfo > &biases, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
A ViewsDescriptor for the SplitterLayer.
bool IsTypeSpaceMatch(const TensorInfo &other) const
Check that the types are the same and, if quantize, that the quantization parameters are the same...
Definition: Tensor.cpp:432
bool IsConvertFp32ToFp16Supported(const TensorInfo &input, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status NeonSpaceToDepthWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const SpaceToDepthDescriptor &descriptor)
arm_compute::Status NeonSplitterWorkloadValidate(const TensorInfo &input, const std::vector< std::reference_wrapper< TensorInfo >> &outputs, unsigned int splitAxis)
A TransposeConvolution2dDescriptor for the TransposeConvolution2dLayer.
const TensorInfo const TensorInfo const TensorInfo const TensorInfo const TensorInfo const TensorInfo const LstmDescriptor const LstmInputParamsInfo & paramsInfo
const TensorShape & GetShape() const
Definition: Tensor.hpp:191
const TensorInfo & output
arm_compute::Status NeonLogSoftmaxWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const LogSoftmaxDescriptor &descriptor)
A ReshapeDescriptor for the ReshapeLayer.
bool IsGatherSupported(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const GatherDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported) const override
arm_compute::Status NeonBatchNormalizationValidate(const TensorInfo &input, const TensorInfo &output, const TensorInfo &mean, const TensorInfo &var, const TensorInfo &beta, const TensorInfo &gamma, const BatchNormalizationDescriptor &descriptor, const ActivationDescriptor *activationDescriptor)
bool IsDetectionPostProcessSupported(const TensorInfo &boxEncodings, const TensorInfo &scores, const TensorInfo &anchors, const TensorInfo &detectionBoxes, const TensorInfo &detectionClasses, const TensorInfo &detectionScores, const TensorInfo &numDetections, const DetectionPostProcessDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsMemImportSupported(const TensorInfo &input, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsDilatedDepthwiseConvolutionSupported(const TensorInfo &input, const TensorInfo &output, const DepthwiseConvolution2dDescriptor &descriptor, const TensorInfo &weights, const Optional< TensorInfo > &biases, Optional< std::string &> reason=EmptyOptional()) const override
bool IsQuantizedLstmSupported(const TensorInfo &input, const TensorInfo &cellStateIn, const TensorInfo &outputStateIn, const TensorInfo &cellStateOut, const TensorInfo &outputStateOut, const QuantizedLstmInputParamsInfo &paramsInfo, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
uint32_t GetNumDimensions() const
Get the number of dimensions.
A ComparisonDescriptor for the ComparisonLayer.
Definition: Descriptors.hpp:89
bool IsDepthToSpaceSupported(const TensorInfo &input, const TensorInfo &output, const DepthToSpaceDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
const TensorInfo const TensorInfo const TensorInfo const TensorInfo const TensorInfo & gamma
bool IsL2NormalizationSupported(const TensorInfo &input, const TensorInfo &output, const L2NormalizationDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsCastSupported(const TensorInfo &input, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsStridedSliceSupported(const TensorInfo &input, const TensorInfo &output, const StridedSliceDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
const std::vector< std::reference_wrapper< TensorInfo > > & outputs
bool IsLayerSupported(const LayerType &type, const std::vector< TensorInfo > &infos, const BaseDescriptor &descriptor, const Optional< LstmInputParamsInfo > &lstmParamsInfo, const Optional< QuantizedLstmInputParamsInfo > &quantizedLstmParamsInfo, Optional< std::string &> reasonIfUnsupported) const override
arm_compute::Status NeonGatherNdWorkloadValidate(const TensorInfo &paramsInfo, const TensorInfo &indicesInfo, const TensorInfo &outputInfo)
bool IsConvertFp32ToBf16Supported(const TensorInfo &input, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsAdditionSupported(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
A Convolution2dDescriptor for the Convolution2dLayer.
bool IsGatherNdSupported(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported) const
arm_compute::Status NeonDepthwiseConvolutionWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const DepthwiseConvolution2dDescriptor &descriptor, const TensorInfo &weights, const Optional< TensorInfo > &biases, const ActivationDescriptor *activationDescriptor)
arm_compute::Status NeonActivationWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const ActivationDescriptor &descriptor)
arm_compute::Status NeonMinimumWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output)
Validate function for validating the inputs and output.
arm_compute::Status NeonStridedSliceWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const StridedSliceDescriptor &descriptor)
const TensorInfo const ActivationDescriptor Optional< std::string & > reasonIfUnsupported
arm_compute::Status NeonTransposeConvolution2dWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const TransposeConvolution2dDescriptor &descriptor, const TensorInfo &weights, const Optional< TensorInfo > &biases)
arm_compute::Status NeonBatchMatMulValidate(const TensorInfo &inputX, const TensorInfo &inputY, const TensorInfo &output, const BatchMatMulDescriptor &descriptor)
arm_compute::Status NeonPooling3dWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const Pooling3dDescriptor &descriptor)
arm_compute::Status NeonLstmFloatWorkloadValidate(const TensorInfo &input, const TensorInfo &outputStateIn, const TensorInfo &cellStateIn, const TensorInfo &scratchBuffer, const TensorInfo &outputStateOut, const TensorInfo &cellStateOut, const TensorInfo &output, const LstmDescriptor &descriptor, const LstmInputParamsInfo &paramsInfo)
bool IsShapeSupported(const TensorInfo &input, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status NeonQLstmWorkloadValidate(const TensorInfo &input, const TensorInfo &cellStateIn, const TensorInfo &outputStateIn, const TensorInfo &cellStateOut, const TensorInfo &outputStateOut, const TensorInfo &output, const QLstmDescriptor &descriptor, const LstmInputParamsInfo &paramsInfo)
arm_compute::Status NeonSliceWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const SliceDescriptor &descriptor)
arm_compute::Status NeonFullyConnectedWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const TensorInfo &weights, const Optional< TensorInfo > &biases, const FullyConnectedDescriptor &descriptor, const ActivationDescriptor *activationDescriptor)
A LogicalBinaryDescriptor for the LogicalBinaryLayer.
bool IsConstantSupported(const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
Copyright (c) 2021 ARM Limited and Contributors.
arm_compute::Status NeonQuantizeWorkloadValidate(const TensorInfo &input, const TensorInfo &output)
bool IsPadSupported(const TensorInfo &input, const TensorInfo &output, const PadDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
void IgnoreUnused(Ts &&...)
const TensorInfo const ActivationDescriptor & descriptor
std::set< unsigned int > ComputeSplitAxis(const armnn::SplitterDescriptor &desc, const TensorShape &input)
arm_compute::Status NeonAdditionWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ActivationDescriptor *activationDescriptor)
A SpaceToDepthDescriptor for the SpaceToDepthLayer.
arm_compute::Status NeonLogWorkloadValidate(const TensorInfo &input, const TensorInfo &output)
arm_compute::Status NeonLogicalAndWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output)
arm_compute::Status NeonInstanceNormalizationWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const InstanceNormalizationDescriptor &descriptor)
bool IsPooling2dSupported(const TensorInfo &input, const TensorInfo &output, const Pooling2dDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status NeonLogicalOrWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output)
LogicalBinaryOperation m_Operation
Specifies the logical operation to execute.
A BatchToSpaceNdDescriptor for the BatchToSpaceNdLayer.
bool IsActivationSupported(const TensorInfo &input, const TensorInfo &output, const ActivationDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
The NeonBackendModelContext is used to pass in Neon specific backend ModelOptions.
bool IsMultiplicationSupported(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
const TensorInfo & outputStateIn
const TensorInfo const TensorInfo & previousCellStateIn
bool IsComparisonSupported(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ComparisonDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
A ResizeDescriptor for the ResizeLayer.
const TensorInfo & alpha
arm_compute::Status NeonL2NormalizationWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const L2NormalizationDescriptor &descriptor)
arm_compute::Status NeonAbsWorkloadValidate(const TensorInfo &input, const TensorInfo &output)
Base class for all descriptors.
Definition: Descriptors.hpp:22
A StackDescriptor for the StackLayer.
arm_compute::Status NeonQuantizedLstmWorkloadValidate(const TensorInfo &input, const TensorInfo &cellStateIn, const TensorInfo &outputStateIn, const TensorInfo &cellStateOut, const TensorInfo &outputStateOut, const QuantizedLstmInputParamsInfo &paramsInfo)
arm_compute::Status NeonStackWorkloadValidate(const std::vector< const TensorInfo *> &inputs, const TensorInfo &output, const StackDescriptor &descriptor)
arm_compute::Status NeonMeanWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const MeanDescriptor &descriptor)
arm_compute::Status NeonReduceWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const ReduceDescriptor &descriptor)
arm_compute::Status NeonSpaceToBatchNdWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const SpaceToBatchNdDescriptor &descriptor)
arm_compute::Status NeonSubtractionWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ActivationDescriptor *activationDescriptor)
A PadDescriptor for the PadLayer.
bool IsLogicalBinarySupported(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const LogicalBinaryDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported) const override
bool IsConvolution3dSupported(const TensorInfo &input, const TensorInfo &output, const Convolution3dDescriptor &descriptor, const TensorInfo &weights, const Optional< TensorInfo > &biases, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
DataType
Definition: Types.hpp:48
const TensorInfo const TensorInfo & cellStateIn
bool IsFillSupported(const TensorInfo &input, const TensorInfo &output, const FillDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
An LstmDescriptor for the LstmLayer.
arm_compute::Status NeonExpWorkloadValidate(const TensorInfo &input, const TensorInfo &output)
arm_compute::Status NeonReshapeWorkloadValidate(const TensorInfo &input, const TensorInfo &output)
bool IsInputSupported(const TensorInfo &input, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status NeonBatchToSpaceNdWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const BatchToSpaceNdDescriptor &descriptor)
bool IsStackSupported(const std::vector< const TensorInfo *> &inputs, const TensorInfo &output, const StackDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
std::shared_ptr< IBackendModelContext > IBackendSpecificModelContextPtr
A L2NormalizationDescriptor for the L2NormalizationLayer.
const TensorInfo const TensorInfo const TensorInfo & var
bool IsMinimumSupported(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsPreluSupported(const TensorInfo &input, const TensorInfo &alpha, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsOutputSupported(const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
An ArgMinMaxDescriptor for ArgMinMaxLayer.
Definition: Descriptors.hpp:67
bool IsInstanceNormalizationSupported(const TensorInfo &input, const TensorInfo &output, const InstanceNormalizationDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
DataType GetDataType() const
Definition: Tensor.hpp:198
An OriginsDescriptor for the ConcatLayer.
A ReduceDescriptor for the REDUCE operators.
A FullyConnectedDescriptor for the FullyConnectedLayer.
arm_compute::Status NeonLogicalNotWorkloadValidate(const TensorInfo &input, const TensorInfo &output)
const TensorInfo const TensorInfo const TensorInfo const TensorInfo & outputStateOut
bool IsNormalizationSupported(const TensorInfo &input, const TensorInfo &output, const NormalizationDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsElementwiseUnarySupported(const TensorInfo &input, const TensorInfo &output, const ElementwiseUnaryDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
const TensorInfo const TensorInfo const TensorInfo const TensorInfo const TensorInfo & cellStateOut
arm_compute::Status NeonCastValidate(const TensorInfo &input, const TensorInfo &output)
A GatherDescriptor for the GatherLayer.
Status
enumeration
Definition: Types.hpp:42
arm_compute::Status NeonChannelShuffleValidate(const TensorInfo &input, const TensorInfo &output, const ChannelShuffleDescriptor &descriptor)
arm_compute::Status NeonComparisonWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ComparisonDescriptor &descriptor)
bool IsDivisionSupported(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status NeonUnidirectionalSequenceLstmWorkloadValidate(const TensorInfo &input, const TensorInfo &outputStateIn, const TensorInfo &cellStateIn, const TensorInfo &outputStateOut, const TensorInfo &cellStateOut, const TensorInfo &output, const UnidirectionalSequenceLstmDescriptor &descriptor, const LstmInputParamsInfo &paramsInfo)
const TensorInfo const TensorInfo const TensorInfo const TensorInfo & beta
arm_compute::Status NeonConcatWorkloadValidate(const std::vector< const TensorInfo *> &inputs, const TensorInfo &output, const OriginsDescriptor &descriptor)
arm_compute::Status NeonPermuteWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const PermuteDescriptor &descriptor)
bool IsFloorSupported(const TensorInfo &input, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
A QLstmDescriptor for the QLstmLayer.
bool IsMergeSupported(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
DestType PolymorphicDowncast(SourceType *value)
Polymorphic downcast for build in pointers only.
arm_compute::Status NeonConvolution2dWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const Convolution2dDescriptor &descriptor, const TensorInfo &weights, const Optional< TensorInfo > &biases, bool isFastMathEnabled, const ActivationDescriptor *activationDescriptor)
bool IsLogSoftmaxSupported(const TensorInfo &input, const TensorInfo &output, const LogSoftmaxDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
An ActivationDescriptor for the ActivationLayer.
Definition: Descriptors.hpp:36
bool IsResizeSupported(const TensorInfo &input, const TensorInfo &output, const ResizeDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsMemCopySupported(const TensorInfo &input, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsTransposeConvolution2dSupported(const TensorInfo &input, const TensorInfo &output, const TransposeConvolution2dDescriptor &descriptor, const TensorInfo &weights, const Optional< TensorInfo > &biases, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
A SliceDescriptor for the SliceLayer.
A Convolution3dDescriptor for the Convolution3dLayer.
arm_compute::Status NeonDequantizeWorkloadValidate(const TensorInfo &input, const TensorInfo &output)
bool IsSplitterSupported(const TensorInfo &input, const std::vector< std::reference_wrapper< TensorInfo >> &outputs, const ViewsDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
const TensorInfo & previousOutputIn
A BatchMatMulDescriptor for the BatchMatMul operator.
bool IsReshapeSupported(const TensorInfo &input, const TensorInfo &output, const ReshapeDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status NeonDivisionWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ActivationDescriptor *activationDescriptor)
bool IsBatchNormalizationSupported(const TensorInfo &input, const TensorInfo &output, const TensorInfo &mean, const TensorInfo &var, const TensorInfo &beta, const TensorInfo &gamma, const BatchNormalizationDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsBatchMatMulSupported(const TensorInfo &inputX, const TensorInfo &inputY, const TensorInfo &output, const BatchMatMulDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const
A Pooling3dDescriptor for the Pooling3dLayer.
arm_compute::Status NeonConvolution3dWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const Convolution3dDescriptor &descriptor, const TensorInfo &weights, const Optional< TensorInfo > &biases, bool isFastMathEnabled, const ActivationDescriptor *activationDescriptor)
void SetValueChecked(Optional< T &> optionalRef, V &&val)
A SpaceToBatchNdDescriptor for the SpaceToBatchNdLayer.
arm_compute::Status NeonNormalizationWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const NormalizationDescriptor &descriptor)
arm_compute::Status NeonUnidirectionalSequenceLstmFloatWorkloadValidate(const TensorInfo &input, const TensorInfo &outputStateIn, const TensorInfo &cellStateIn, const TensorInfo &outputStateOut, const TensorInfo &cellStateOut, const TensorInfo &output, const UnidirectionalSequenceLstmDescriptor &descriptor, const LstmInputParamsInfo &paramsInfo)
bool IsQuantizeSupported(const TensorInfo &input, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
EmptyOptional is used to initialize the Optional class in case we want to have default value for an O...
Definition: Optional.hpp:32
arm_compute::Status NeonRsqrtWorkloadValidate(const TensorInfo &input, const TensorInfo &output)
bool IsConvertFp16ToFp32Supported(const TensorInfo &input, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status NeonPadWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const PadDescriptor &descriptor)
A ElementwiseUnaryDescriptor for the ElementwiseUnaryLayer.
bool IsSubtractionSupported(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsLstmSupported(const TensorInfo &input, const TensorInfo &outputStateIn, const TensorInfo &cellStateIn, const TensorInfo &scratchBuffer, const TensorInfo &outputStateOut, const TensorInfo &cellStateOut, const TensorInfo &output, const LstmDescriptor &descriptor, const LstmInputParamsInfo &paramsInfo, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status NeonArgMinMaxWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const ArgMinMaxDescriptor &descriptor)
arm_compute::Status NeonSoftmaxWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const SoftmaxDescriptor &descriptor)
bool IsSpaceToBatchNdSupported(const TensorInfo &input, const TensorInfo &output, const SpaceToBatchNdDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status NeonTransposeWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const TransposeDescriptor &descriptor)
const TensorInfo const Convolution2dDescriptor const TensorInfo const Optional< TensorInfo > & biases
bool IsPooling3dSupported(const TensorInfo &input, const TensorInfo &output, const Pooling3dDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
uint32_t GetNumDimensions() const
Get the number of dimensions.
arm_compute::Status NeonSqrtWorkloadValidate(const TensorInfo &input, const TensorInfo &output)
A MeanDescriptor for the MeanLayer.
bool IsDepthwiseConvolutionSupported(const TensorInfo &input, const TensorInfo &output, const DepthwiseConvolution2dDescriptor &descriptor, const TensorInfo &weights, const Optional< TensorInfo > &biases, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status NeonMaximumWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output)
bool IsArgMinMaxSupported(const TensorInfo &input, const TensorInfo &output, const ArgMinMaxDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsSpaceToDepthSupported(const TensorInfo &input, const TensorInfo &output, const SpaceToDepthDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
A TransposeDescriptor for the TransposeLayer.
A StridedSliceDescriptor for the StridedSliceLayer.
bool IsTransposeSupported(const TensorInfo &input, const TensorInfo &output, const TransposeDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsMaximumSupported(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status NeonConstantWorkloadValidate(const TensorInfo &output)
const TensorInfo & input1
bool IsFullyConnectedSupported(const TensorInfo &input, const TensorInfo &output, const TensorInfo &weights, const TensorInfo &biases, const FullyConnectedDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsMeanSupported(const TensorInfo &input, const TensorInfo &output, const MeanDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsBatchToSpaceNdSupported(const TensorInfo &input, const TensorInfo &output, const BatchToSpaceNdDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status NeonPreluWorkloadValidate(const TensorInfo &input, const TensorInfo &alpha, const TensorInfo &output)
#define FORWARD_WORKLOAD_VALIDATE_FUNC(func, reasonIfUnsupported,...)
arm_compute::Status NeonDepthToSpaceWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const DepthToSpaceDescriptor &descriptor)
A Pooling2dDescriptor for the Pooling2dLayer.
arm_compute::Status NeonResizeWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const ResizeDescriptor &descriptor)
bool IsUnidirectionalSequenceLstmSupported(const TensorInfo &input, const TensorInfo &outputStateIn, const TensorInfo &cellStateIn, const TensorInfo &outputStateOut, const TensorInfo &cellStateOut, const TensorInfo &output, const UnidirectionalSequenceLstmDescriptor &descriptor, const LstmInputParamsInfo &paramsInfo, Optional< std::string &> reasonIfUnsupported) const override
A NormalizationDescriptor for the NormalizationLayer.
bool IsQLstmSupported(const TensorInfo &input, const TensorInfo &previousOutputIn, const TensorInfo &previousCellStateIn, const TensorInfo &outputStateOut, const TensorInfo &cellStateOut, const TensorInfo &output, const QLstmDescriptor &descriptor, const LstmInputParamsInfo &paramsInfo, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsConvertBf16ToFp32Supported(const TensorInfo &input, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
const TensorInfo const TensorInfo const TensorInfo & scratchBuffer
An InstanceNormalizationDescriptor for InstanceNormalizationLayer.
unsigned int GetConcatAxis() const
Get the concatenation axis value.
A ChannelShuffleDescriptor for the ChannelShuffle operator.
bool IsSupportedForDataTypeGeneric(Optional< std::string &> reasonIfUnsupported, DataType dataType, Float16Func float16FuncPtr, Float32Func float32FuncPtr, Uint8Func uint8FuncPtr, Int32Func int32FuncPtr, BooleanFunc booleanFuncPtr, Params &&... params)
A SoftmaxDescriptor for the SoftmaxLayer.
bool IsReduceSupported(const TensorInfo &input, const TensorInfo &output, const ReduceDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
const TensorInfo const Convolution2dDescriptor const TensorInfo & weights
arm_compute::Status NeonPooling2dWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const Pooling2dDescriptor &descriptor)
arm_compute::Status NeonSinWorkloadValidate(const TensorInfo &input, const TensorInfo &output)
bool IsDequantizeSupported(const TensorInfo &input, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
A DepthwiseConvolution2dDescriptor for the DepthwiseConvolution2dLayer.
A FillDescriptor for the FillLayer.
A BatchNormalizationDescriptor for the BatchNormalizationLayer.
arm_compute::Status NeonMultiplicationWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ActivationDescriptor *activationDescriptor)
bool IsChannelShuffleSupported(const TensorInfo &input, const TensorInfo &output, const ChannelShuffleDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
const TensorInfo const TensorInfo & mean
A PermuteDescriptor for the PermuteLayer.
LayerType
When adding a new layer, adapt also the LastLayer enum value in the enum class LayerType below...
Definition: Types.hpp:468
bool IsPermuteSupported(const TensorInfo &input, const TensorInfo &output, const PermuteDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override