ArmNN
 22.02
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)
79 #endif
80 
81 namespace armnn
82 {
83 
84 namespace
85 {
86 
87 template< typename ... Args>
88 bool IsNeonBackendSupported(Optional<std::string&> reasonIfUnsupported, Args... args)
89 {
90  IgnoreUnused(reasonIfUnsupported, (args)...);
91 #if defined(ARMCOMPUTENEON_ENABLED)
92  return true;
93 #else
94  SetValueChecked(reasonIfUnsupported, "The armnn library has been built without NEON support");
95  return false;
96 #endif
97 }
98 
99 template<typename FloatFunc, typename Uint8Func, typename ... Params>
100 bool IsSupportedForDataTypeNeon(Optional<std::string&> reasonIfUnsupported,
101  DataType dataType,
102  FloatFunc floatFuncPtr,
103  Uint8Func uint8FuncPtr,
104  Params&&... params)
105 {
106  return IsNeonBackendSupported(reasonIfUnsupported) &&
107  IsSupportedForDataTypeGeneric(reasonIfUnsupported,
108  dataType,
109  floatFuncPtr,
110  floatFuncPtr,
111  uint8FuncPtr,
112  &FalseFunc<>,
113  &FalseFunc<>,
114  std::forward<Params>(params)...);
115 }
116 
117 #if defined(ARMCOMPUTENEON_ENABLED)
118 template<class FuncType, class... Args>
119 inline bool IsWorkloadSupported(FuncType& func, Optional<std::string&> reasonIfUnsupported, Args&&... args)
120 {
121  arm_compute::Status aclStatus = func(std::forward<Args>(args)...);
122  const bool supported = (aclStatus.error_code() == arm_compute::ErrorCode::OK);
123  if (!supported && reasonIfUnsupported)
124  {
125  reasonIfUnsupported.value() = aclStatus.error_description();
126  }
127  return supported;
128 }
129 
130 #define FORWARD_WORKLOAD_VALIDATE_FUNC(func, reasonIfUnsupported, ...) \
131  return IsWorkloadSupported(func, reasonIfUnsupported, __VA_ARGS__);
132 #else
133 #define FORWARD_WORKLOAD_VALIDATE_FUNC(func, reasonIfUnsupported, ...) \
134  return IsNeonBackendSupported(reasonIfUnsupported, __VA_ARGS__);
135 #endif
136 } // anonymous namespace
137 
139  : m_ModelContextPtr(modelContextPtr)
140 {
141 }
142 
144  : m_ModelContextPtr(nullptr)
145 {
146 }
147 
149  const std::vector<TensorInfo>& infos,
150  const BaseDescriptor& descriptor,
151  const Optional<LstmInputParamsInfo>& lstmParamsInfo,
152  const Optional<QuantizedLstmInputParamsInfo>& quantizedLstmParamsInfo,
153  Optional<std::string&> reasonIfUnsupported) const
154 {
155  switch (type)
156  {
158  return IsActivationSupported(infos[0],
159  infos[1],
160  *(PolymorphicDowncast<const ActivationDescriptor*>(&descriptor)),
161  reasonIfUnsupported);
162  case LayerType::Addition:
163  return IsAdditionSupported(infos[0], infos[1], infos[2], reasonIfUnsupported);
165  return IsArgMinMaxSupported(infos[0],
166  infos[1],
167  *(PolymorphicDowncast<const ArgMinMaxDescriptor*>(&descriptor)),
168  reasonIfUnsupported);
170  return IsBatchNormalizationSupported(infos[0],
171  infos[1],
172  infos[2],
173  infos[3],
174  infos[4],
175  infos[5],
176  *(PolymorphicDowncast<const BatchNormalizationDescriptor*>
177  (&descriptor)),
178  reasonIfUnsupported);
180  return IsBatchToSpaceNdSupported(infos[0],
181  infos[1],
182  *(PolymorphicDowncast<const BatchToSpaceNdDescriptor*>(&descriptor)),
183  reasonIfUnsupported);
185  return IsComparisonSupported(infos[0],
186  infos[1],
187  infos[2],
188  *(PolymorphicDowncast<const ComparisonDescriptor*>(&descriptor)),
189  reasonIfUnsupported);
190  case LayerType::Concat:
191  {
192  std::vector<const TensorInfo*> inputInfos;
193  for (uint32_t i = 0; i < (infos.size() - 1); i++)
194  {
195  inputInfos.push_back(&infos[i]);
196  }
197  return IsConcatSupported(inputInfos,
198  infos[infos.size() - 1],
199  *(PolymorphicDowncast<const OriginsDescriptor*>(&descriptor)),
201  }
202  case LayerType::Constant:
203  return IsConstantSupported(infos[0], reasonIfUnsupported);
205  return IsConvertBf16ToFp32Supported(infos[0], infos[1], reasonIfUnsupported);
207  return IsConvertFp16ToFp32Supported(infos[0], infos[1], reasonIfUnsupported);
209  return IsConvertFp32ToBf16Supported(infos[0], infos[1], reasonIfUnsupported);
211  return IsConvertFp32ToFp16Supported(infos[0], infos[1], reasonIfUnsupported);
213  {
214  if (infos.size() != 4)
215  {
216  throw InvalidArgumentException("Invalid number of TransposeConvolution2d TensorInfos. "
217  "TensorInfos should be of format: {input, output, weights, biases}.");
218  }
219 
220  auto desc = *(PolymorphicDowncast<const Convolution2dDescriptor*>(&descriptor));
221  if (infos[3] == TensorInfo())
222  {
223  return IsConvolution2dSupported(infos[0],
224  infos[1],
225  desc,
226  infos[2],
227  EmptyOptional(),
228  reasonIfUnsupported);
229  }
230  else
231  {
232  return IsConvolution2dSupported(infos[0],
233  infos[1],
234  desc,
235  infos[2],
236  infos[3],
237  reasonIfUnsupported);
238  }
239  }
241  return IsDepthToSpaceSupported(infos[0],
242  infos[1],
243  *(PolymorphicDowncast<const DepthToSpaceDescriptor*>(&descriptor)),
244  reasonIfUnsupported);
246  {
247  if (infos.size() != 4)
248  {
249  throw InvalidArgumentException("Invalid number of DepthwiseConvolution2d TensorInfos. "
250  "TensorInfos should be of format: {input, output, weights, biases}.");
251  }
252 
253  auto desc = *(PolymorphicDowncast<const DepthwiseConvolution2dDescriptor*>(&descriptor));
254  if (infos[3] == TensorInfo())
255  {
256  return IsDepthwiseConvolutionSupported(infos[0],
257  infos[1],
258  desc,
259  infos[2],
260  EmptyOptional(),
261  reasonIfUnsupported);
262  }
263  else
264  {
265  return IsDepthwiseConvolutionSupported(infos[0],
266  infos[1],
267  desc,
268  infos[2],
269  infos[3],
270  reasonIfUnsupported);
271  }
272  }
274  return IsDequantizeSupported(infos[0], infos[1], reasonIfUnsupported);
275  case LayerType::Division:
276  return IsDivisionSupported(infos[0], infos[1], infos[2], reasonIfUnsupported);
278  return IsElementwiseUnarySupported(infos[0],
279  infos[1],
280  *(PolymorphicDowncast<const ElementwiseUnaryDescriptor*>(&descriptor)),
281  reasonIfUnsupported);
282  case LayerType::Fill:
283  return IsFillSupported(infos[0],
284  infos[1],
285  *(PolymorphicDowncast<const FillDescriptor*>(&descriptor)),
286  reasonIfUnsupported);
287  case LayerType::Floor:
288  return IsFloorSupported(infos[0], infos[1], reasonIfUnsupported);
290  return IsFullyConnectedSupported(infos[0],
291  infos[1],
292  infos[2],
293  infos[3],
294  *(PolymorphicDowncast<const FullyConnectedDescriptor*>(&descriptor)),
295  reasonIfUnsupported);
296  case LayerType::Gather:
297  return IsGatherSupported(infos[0],
298  infos[1],
299  infos[2],
300  *(PolymorphicDowncast<const GatherDescriptor*>(&descriptor)),
301  reasonIfUnsupported);
302  case LayerType::Input:
303  return IsInputSupported(infos[0], reasonIfUnsupported);
305  return IsInstanceNormalizationSupported(infos[0],
306  infos[1],
307  *(PolymorphicDowncast<const InstanceNormalizationDescriptor*>
308  (&descriptor)),
309  reasonIfUnsupported);
311  return IsL2NormalizationSupported(infos[0],
312  infos[1],
313  *(PolymorphicDowncast<const L2NormalizationDescriptor*>(&descriptor)),
314  reasonIfUnsupported);
316  return IsLogicalBinarySupported(infos[0],
317  infos[1],
318  infos[2],
319  *(PolymorphicDowncast<const LogicalBinaryDescriptor*>(&descriptor)),
320  reasonIfUnsupported);
322  return IsLogSoftmaxSupported(infos[0],
323  infos[1],
324  *(PolymorphicDowncast<const LogSoftmaxDescriptor*>(&descriptor)),
325  reasonIfUnsupported);
326  case LayerType::Lstm:
327  return IsLstmSupported(infos[0],
328  infos[1],
329  infos[2],
330  infos[3],
331  infos[4],
332  infos[5],
333  infos[6],
334  *(PolymorphicDowncast<const LstmDescriptor*>(&descriptor)),
335  lstmParamsInfo.value(),
337  case LayerType::QLstm:
338  return IsQLstmSupported(infos[0],
339  infos[1],
340  infos[2],
341  infos[3],
342  infos[4],
343  infos[5],
344  *(PolymorphicDowncast<const QLstmDescriptor*>(&descriptor)),
345  lstmParamsInfo.value(),
347  case LayerType::Maximum:
348  return IsMaximumSupported(infos[0], infos[1], infos[2], reasonIfUnsupported);
349  case LayerType::Mean:
350  return IsMeanSupported(infos[0],
351  infos[1],
352  *(PolymorphicDowncast<const MeanDescriptor*>(&descriptor)),
353  reasonIfUnsupported);
354  case LayerType::Minimum:
355  return IsMinimumSupported(infos[0], infos[1], infos[2], reasonIfUnsupported);
357  return IsMultiplicationSupported(infos[0], infos[1], infos[2], reasonIfUnsupported);
359  return IsNormalizationSupported(infos[0],
360  infos[1],
361  *(PolymorphicDowncast<const NormalizationDescriptor*>(&descriptor)),
362  reasonIfUnsupported);
363  case LayerType::Output:
364  return IsOutputSupported(infos[0], reasonIfUnsupported);
365  case LayerType::Pad:
366  return IsPadSupported(infos[0],
367  infos[1],
368  *(PolymorphicDowncast<const PadDescriptor*>(&descriptor)),
369  reasonIfUnsupported);
370  case LayerType::Permute:
371  return IsPermuteSupported(infos[0],
372  infos[1],
373  *(PolymorphicDowncast<const PermuteDescriptor*>(&descriptor)),
374  reasonIfUnsupported);
376  return IsPooling2dSupported(infos[0],
377  infos[1],
378  *(PolymorphicDowncast<const Pooling2dDescriptor*>(&descriptor)),
379  reasonIfUnsupported);
380  case LayerType::Prelu:
381  return IsPreluSupported(infos[0], infos[1], infos[2], reasonIfUnsupported);
382  case LayerType::Quantize:
383  return IsQuantizeSupported(infos[0], infos[1], reasonIfUnsupported);
385  return IsQuantizedLstmSupported(infos[0],
386  infos[1],
387  infos[2],
388  infos[3],
389  infos[4],
390  quantizedLstmParamsInfo.value(),
392  case LayerType::Reshape:
393  return IsReshapeSupported(infos[0],
394  infos[1],
395  *(PolymorphicDowncast<const ReshapeDescriptor*>(&descriptor)),
396  reasonIfUnsupported);
397  case LayerType::Resize:
398  return IsResizeSupported(infos[0],
399  infos[1],
400  *(PolymorphicDowncast<const ResizeDescriptor*>(&descriptor)),
401  reasonIfUnsupported);
402  case LayerType::Reduce:
403  return IsReduceSupported(infos[0],
404  infos[1],
405  *(PolymorphicDowncast<const ReduceDescriptor*>(&descriptor)),
406  reasonIfUnsupported);
407  case LayerType::Slice:
408  return IsSliceSupported(infos[0],
409  infos[1],
410  *(PolymorphicDowncast<const SliceDescriptor*>(&descriptor)),
411  reasonIfUnsupported);
412  case LayerType::Softmax:
413  return IsSoftmaxSupported(infos[0],
414  infos[1],
415  *(PolymorphicDowncast<const SoftmaxDescriptor*>(&descriptor)),
416  reasonIfUnsupported);
418  return IsSpaceToBatchNdSupported(infos[0],
419  infos[1],
420  *(PolymorphicDowncast<const SpaceToBatchNdDescriptor*>(&descriptor)),
421  reasonIfUnsupported);
423  return IsSpaceToDepthSupported(infos[0],
424  infos[1],
425  *(PolymorphicDowncast<const SpaceToDepthDescriptor*>(&descriptor)),
426  reasonIfUnsupported);
427  case LayerType::Splitter:
428  {
429  std::vector<TensorInfo> outputInfos;
430  for (uint32_t i = 1; i < infos.size(); i++)
431  {
432  outputInfos.push_back(infos[i]);
433  }
434  return IsSplitterSupported(infos[0],
435  {outputInfos.begin(), outputInfos.end()},
436  *(PolymorphicDowncast<const ViewsDescriptor*>(&descriptor)),
438  }
439  case LayerType::Stack:
440  {
441  std::vector<const TensorInfo*> inputInfos;
442  for (uint32_t i = 0; i < infos.size() - 1; i++)
443  {
444  inputInfos.push_back(&infos[i]);
445  }
446  return IsStackSupported(inputInfos,
447  infos[infos.size() - 1],
448  *(PolymorphicDowncast<const StackDescriptor*>(&descriptor)),
450  }
452  return IsStridedSliceSupported(infos[0],
453  infos[1],
454  *(PolymorphicDowncast<const StridedSliceDescriptor*>(&descriptor)),
455  reasonIfUnsupported);
457  return IsSubtractionSupported(infos[0], infos[1], infos[2], reasonIfUnsupported);
459  return IsTransposeSupported(infos[0],
460  infos[1],
461  *(PolymorphicDowncast<const TransposeDescriptor*>(&descriptor)),
462  reasonIfUnsupported);
464  {
465  if (infos.size() != 4)
466  {
467  throw InvalidArgumentException("Invalid number of TransposeConvolution2d TensorInfos. "
468  "TensorInfos should be of format: {input, output, weights, biases}.");
469  }
470 
471  auto desc = *(PolymorphicDowncast<const TransposeConvolution2dDescriptor*>(&descriptor));
472  if (infos[3] == TensorInfo())
473  {
474  return IsTransposeConvolution2dSupported(infos[0],
475  infos[1],
476  desc,
477  infos[2],
478  EmptyOptional(),
479  reasonIfUnsupported);
480  }
481  else
482  {
483  return IsTransposeConvolution2dSupported(infos[0],
484  infos[1],
485  desc,
486  infos[2],
487  infos[3],
488  reasonIfUnsupported);
489  }
490  }
491  case LayerType::Cast:
492  return IsCastSupported(infos[0], infos[1], reasonIfUnsupported);
494  return IsChannelShuffleSupported(infos[0],
495  infos[1],
496  *(PolymorphicDowncast<const ChannelShuffleDescriptor*>(&descriptor)),
497  reasonIfUnsupported);
499  {
500  if (infos.size() != 4)
501  {
502  throw InvalidArgumentException("Invalid number of Convolution3d TensorInfos. "
503  "TensorInfos should be of format: {input, output, weights, biases}.");
504  }
505 
506  auto desc = *(PolymorphicDowncast<const Convolution3dDescriptor*>(&descriptor));
507  if (infos[3] == TensorInfo())
508  {
509  return IsConvolution3dSupported(infos[0],
510  infos[1],
511  desc,
512  infos[2],
513  EmptyOptional(),
514  reasonIfUnsupported);
515  }
516  else
517  {
518  return IsConvolution3dSupported(infos[0],
519  infos[1],
520  desc,
521  infos[2],
522  infos[3],
523  reasonIfUnsupported);
524  }
525  }
526  case LayerType::MemCopy:
527  return LayerSupportBase::IsMemCopySupported(infos[0], infos[1], reasonIfUnsupported);
529  return LayerSupportBase::IsMemImportSupported(infos[0], infos[1], reasonIfUnsupported);
531  {
532  auto desc = *(PolymorphicDowncast<const DetectionPostProcessDescriptor*>(&descriptor));
534  infos[1],
535  infos[2],
536  infos[3],
537  infos[4],
538  infos[5],
539  infos[6],
540  desc,
541  reasonIfUnsupported);
542  }
543  case LayerType::Map:
544  return true;
545  case LayerType::Unmap:
546  return true;
547  case LayerType::Merge:
548  return LayerSupportBase::IsMergeSupported(infos[0],
549  infos[1],
550  infos[2],
551  reasonIfUnsupported);
552  case LayerType::Rank:
553  return true;
554  case LayerType::Shape:
555  return LayerSupportBase::IsShapeSupported(infos[0],
556  infos[1],
557  reasonIfUnsupported);
558  default:
559  // layers not supported in neon by default:
560  // debug, fakequantization, precompiled, standin,
561  // switch, unidirectionalsequencelstm, pooling3d
562  return false;
563  }
564 }
565 
567  const TensorInfo& output,
569  Optional<std::string&> reasonIfUnsupported) const
570 {
571  IgnoreUnused(descriptor);
573  reasonIfUnsupported,
574  input,
575  output,
576  descriptor);
577 }
578 
580  const TensorInfo& input1,
581  const TensorInfo& output,
582  Optional<std::string&> reasonIfUnsupported) const
583 {
585  reasonIfUnsupported,
586  input0,
587  input1,
588  output,
589  nullptr);
590 }
591 
593  const TensorInfo& output,
595  Optional<std::string&> reasonIfUnsupported) const
596 {
598  reasonIfUnsupported,
599  input,
600  output,
601  descriptor);
602 }
603 
605  const TensorInfo& output,
606  const TensorInfo& mean,
607  const TensorInfo& var,
608  const TensorInfo& beta,
609  const TensorInfo& gamma,
611  Optional<std::string&> reasonIfUnsupported) const
612 {
614  reasonIfUnsupported,
615  input,
616  output,
617  mean,
618  var,
619  beta,
620  gamma,
621  descriptor,
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& output,
639  Optional<std::string&> reasonIfUnsupported) const
640 {
642  reasonIfUnsupported,
643  input,
644  output);
645 }
646 
648  const TensorInfo& output,
650  Optional<std::string&> reasonIfUnsupported) const
651 {
653  reasonIfUnsupported,
654  input,
655  output,
656  descriptor);
657 }
658 
660  const TensorInfo& input1,
661  const TensorInfo& output,
663  Optional<std::string&> reasonIfUnsupported) const
664 {
665 
667  reasonIfUnsupported,
668  input0,
669  input1,
670  output,
671  descriptor);
672 }
673 
674 bool NeonLayerSupport::IsConcatSupported(const std::vector<const TensorInfo*> inputs,
675  const TensorInfo& output,
677  Optional<std::string&> reasonIfUnsupported) const
678 {
679  if (descriptor.GetNumDimensions() <= descriptor.GetConcatAxis())
680  {
681  SetValueChecked(reasonIfUnsupported, "Neon Concat: Concat axis > Number of dimensions.");
682  return false;
683  }
684 
685  unsigned int concatInnerAxis = (descriptor.GetNumDimensions() - descriptor.GetConcatAxis()) - 1;
686  if(concatInnerAxis < 3) // Width, height, or channels
687  {
689  reasonIfUnsupported,
690  inputs,
691  output,
692  descriptor);
693  }
694  else if (concatInnerAxis == 3)
695  {
696  for (auto& input : inputs)
697  {
698  if (input && !output.IsTypeSpaceMatch(*input)) // Cannot use sub-tensors if the types are not same space
699  {
700  SetValueChecked(reasonIfUnsupported, "Neon Concat: Types and quantization parameters must match.");
701  return false;
702  }
703  }
704  return true; // Sub-tensors support concat along batch
705  }
706  else // > 4 dimensions not supported.
707  {
708  SetValueChecked(reasonIfUnsupported, "Neon Concat: Maximum of 4 dimensions supported.");
709  return false;
710  }
711 }
712 
714  Optional<std::string&> reasonIfUnsupported) const
715 {
717  reasonIfUnsupported,
718  output);
719 }
720 
722  const TensorInfo& output,
723  Optional<std::string&> reasonIfUnsupported) const
724 {
725  armnn::IgnoreUnused(input);
726  armnn::IgnoreUnused(output);
727  armnn::IgnoreUnused(reasonIfUnsupported);
728  return true;
729 }
730 
732  const TensorInfo& output,
733  Optional<std::string&> reasonIfUnsupported) const
734 {
735  armnn::IgnoreUnused(input);
736  armnn::IgnoreUnused(output);
737  armnn::IgnoreUnused(reasonIfUnsupported);
738  return true;
739 }
740 
742  const TensorInfo& output,
743  Optional<std::string&> reasonIfUnsupported) const
744 {
745  armnn::IgnoreUnused(input);
746  armnn::IgnoreUnused(output);
747  armnn::IgnoreUnused(reasonIfUnsupported);
748  return true;
749 }
750 
752  const TensorInfo& output,
753  Optional<std::string&> reasonIfUnsupported) const
754 {
755  armnn::IgnoreUnused(input);
756  armnn::IgnoreUnused(output);
757  armnn::IgnoreUnused(reasonIfUnsupported);
758  return true;
759 }
760 
762  const TensorInfo& output,
764  const TensorInfo& weights,
766  Optional<std::string&> reasonIfUnsupported) const
767 {
768  bool isFastMathEnabled = false;
769 #if defined(ARMCOMPUTENEON_ENABLED)
770  if (m_ModelContextPtr)
771  {
772  if (m_ModelContextPtr.get() != nullptr)
773  {
774  auto modelOptions = dynamic_cast<NeonBackendModelContext*>(m_ModelContextPtr.get());
775  if (modelOptions)
776  {
777  isFastMathEnabled = modelOptions->IsFastMathEnabled();
778  }
779  }
780  }
781 #endif
782 
784  reasonIfUnsupported,
785  input,
786  output,
787  descriptor,
788  weights,
789  biases,
790  isFastMathEnabled,
791  nullptr);
792 }
793 
795  const TensorInfo& output,
797  const TensorInfo& weights,
799  Optional<std::string&> reasonIfUnsupported) const
800 {
801  bool isFastMathEnabled = false;
802 #if defined(ARMCOMPUTENEON_ENABLED)
803  if (m_ModelContextPtr)
804  {
805  if (m_ModelContextPtr.get() != nullptr)
806  {
807  auto modelOptions = dynamic_cast<NeonBackendModelContext*>(m_ModelContextPtr.get());
808  if (modelOptions)
809  {
810  isFastMathEnabled = modelOptions->IsFastMathEnabled();
811  }
812  }
813  }
814 #endif
815 
817  reasonIfUnsupported,
818  input,
819  output,
820  descriptor,
821  weights,
822  biases,
823  isFastMathEnabled,
824  nullptr);
825 }
826 
828  const TensorInfo& output,
830  Optional<std::string&> reasonIfUnsupported) const
831 {
833  reasonIfUnsupported,
834  input,
835  output,
836  descriptor);
837 }
838 
840  const TensorInfo& output,
842  const TensorInfo& weights,
844  Optional<std::string&> reasonIfUnsupported) const
845 {
847  reasonIfUnsupported,
848  input,
849  output,
850  descriptor,
851  weights,
852  biases,
853  nullptr);
854 }
855 
857  const TensorInfo& output,
858  Optional<std::string&> reasonIfUnsupported) const
859 {
861  reasonIfUnsupported,
862  input,
863  output);
864 }
865 
867  const TensorInfo& output,
869  const TensorInfo& weights,
871  Optional<std::string&> reasonIfUnsupported) const
872 {
874  reasonIfUnsupported,
875  input,
876  output,
877  descriptor,
878  weights,
879  biases,
880  nullptr);
881 }
882 
884  const TensorInfo& output,
886  Optional<std::string&> reasonIfUnsupported) const
887 {
888  switch(descriptor.m_Operation)
889  {
890  case UnaryOperation::Abs:
892  reasonIfUnsupported,
893  input,
894  output);
895  case UnaryOperation::Exp:
897  reasonIfUnsupported,
898  input,
899  output);
902  reasonIfUnsupported,
903  input,
904  output);
905  case UnaryOperation::Log:
907  reasonIfUnsupported,
908  input,
909  output);
910  case UnaryOperation::Neg:
912  reasonIfUnsupported,
913  input,
914  output);
917  reasonIfUnsupported,
918  input,
919  output);
920  case UnaryOperation::Sin:
922  reasonIfUnsupported,
923  input,
924  output);
925  default:
926  return false;
927  }
928 }
929 
931  const TensorInfo& output,
932  const FillDescriptor& descriptor,
933  Optional<std::string&> reasonIfUnsupported) const
934 {
935  armnn::IgnoreUnused(input);
936  armnn::IgnoreUnused(output);
937  armnn::IgnoreUnused(descriptor);
938 
939  return IsNeonBackendSupported(reasonIfUnsupported);
940 }
941 
943  const TensorInfo& output,
944  Optional<std::string&> reasonIfUnsupported) const
945 {
946  armnn::IgnoreUnused(output);
947  return IsNeonBackendSupported(reasonIfUnsupported) &&
948  IsSupportedForDataTypeGeneric(reasonIfUnsupported,
949  input.GetDataType(),
950  &FalseFuncF16<>,
951  &TrueFunc<>,
952  &FalseFuncU8<>,
953  &FalseFuncI32<>,
954  &FalseFuncU8<>);
955 }
956 
958  const TensorInfo& output,
959  const TensorInfo& weights,
960  const TensorInfo& biases,
962  Optional<std::string&> reasonIfUnsupported) const
963 {
965  reasonIfUnsupported,
966  input,
967  output,
968  weights,
969  biases,
970  descriptor,
971  nullptr);
972 }
973 
975  const TensorInfo& input1,
976  const TensorInfo& output,
978  Optional<std::string&> reasonIfUnsupported) const
979 {
981  reasonIfUnsupported,
982  input0,
983  input1,
984  output,
985  descriptor);
986 }
987 
989  Optional<std::string&> reasonIfUnsupported) const
990 {
991  return IsNeonBackendSupported(reasonIfUnsupported, input);
992 }
993 
995  const TensorInfo& output,
997  Optional<std::string&> reasonIfUnsupported) const
998 {
1000  reasonIfUnsupported,
1001  input,
1002  output,
1003  descriptor);
1004 }
1005 
1007  const TensorInfo& output,
1009  Optional<std::string&> reasonIfUnsupported) const
1010 {
1011  FORWARD_WORKLOAD_VALIDATE_FUNC(NeonL2NormalizationWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
1012 }
1013 
1015  const TensorInfo& input1,
1016  const TensorInfo& output,
1018  Optional<std::string&> reasonIfUnsupported) const
1019 {
1020  switch(descriptor.m_Operation)
1021  {
1024  reasonIfUnsupported,
1025  input0,
1026  input1,
1027  output);
1030  reasonIfUnsupported,
1031  input0,
1032  input1,
1033  output);
1034  default:
1035  return false;
1036  }
1037 }
1038 
1040  const TensorInfo& output,
1042  Optional<std::string&> reasonIfUnsupported) const
1043 {
1044  FORWARD_WORKLOAD_VALIDATE_FUNC(NeonLogSoftmaxWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
1045 }
1046 
1048  const TensorInfo& outputStateIn,
1049  const TensorInfo& cellStateIn,
1050  const TensorInfo& scratchBuffer,
1051  const TensorInfo& outputStateOut,
1052  const TensorInfo& cellStateOut,
1053  const TensorInfo& output,
1054  const LstmDescriptor& descriptor,
1056  Optional<std::string&> reasonIfUnsupported) const
1057 {
1059  reasonIfUnsupported,
1060  input,
1061  outputStateIn,
1062  cellStateIn,
1063  scratchBuffer,
1064  outputStateOut,
1065  cellStateOut,
1066  output,
1067  descriptor,
1068  paramsInfo);
1069 }
1070 
1072  const TensorInfo& input1,
1073  const TensorInfo& output,
1074  Optional<std::string&> reasonIfUnsupported) const
1075 {
1077  reasonIfUnsupported,
1078  input0,
1079  input1,
1080  output);
1081 }
1082 
1084  const TensorInfo& output,
1085  const MeanDescriptor& descriptor,
1086  Optional<std::string&> reasonIfUnsupported) const
1087 {
1089  reasonIfUnsupported,
1090  input,
1091  output,
1092  descriptor);
1093 }
1094 
1096  const TensorInfo& input1,
1097  const TensorInfo& output,
1098  Optional<std::string&> reasonIfUnsupported) const
1099 {
1101  reasonIfUnsupported,
1102  input0,
1103  input1,
1104  output);
1105 }
1106 
1108  const TensorInfo& input1,
1109  const TensorInfo& output,
1110  Optional<std::string&> reasonIfUnsupported) const
1111 {
1113  reasonIfUnsupported,
1114  input0,
1115  input1,
1116  output,
1117  nullptr);
1118 }
1119 
1121  const TensorInfo& input1,
1122  const TensorInfo& output,
1123  Optional<std::string&> reasonIfUnsupported) const
1124 {
1126  reasonIfUnsupported,
1127  input0,
1128  input1,
1129  output,
1130  nullptr);
1131 }
1132 
1134  const TensorInfo& output,
1136  Optional<std::string&> reasonIfUnsupported) const
1137 {
1139  reasonIfUnsupported,
1140  input,
1141  output,
1142  descriptor);
1143 }
1144 
1146  Optional<std::string&> reasonIfUnsupported) const
1147 {
1148  return IsNeonBackendSupported(reasonIfUnsupported, output);
1149 }
1150 
1152  const TensorInfo& output,
1153  const PadDescriptor& descriptor,
1154  Optional<std::string&> reasonIfUnsupported) const
1155 {
1157  reasonIfUnsupported,
1158  input,
1159  output,
1160  descriptor);
1161 }
1162 
1164  const TensorInfo& output,
1166  Optional<std::string&> reasonIfUnsupported) const
1167 {
1168  FORWARD_WORKLOAD_VALIDATE_FUNC(NeonPermuteWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
1169 }
1170 
1172  const TensorInfo& output,
1174  Optional<std::string&> reasonIfUnsupported) const
1175 {
1176  FORWARD_WORKLOAD_VALIDATE_FUNC(NeonPooling2dWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
1177 }
1178 
1180  const armnn::TensorInfo &alpha,
1181  const armnn::TensorInfo &output,
1182  armnn::Optional<std::string &> reasonIfUnsupported) const
1183 {
1184  FORWARD_WORKLOAD_VALIDATE_FUNC(NeonPreluWorkloadValidate, reasonIfUnsupported, input, alpha, output);
1185 }
1186 
1190  const TensorInfo& outputStateOut,
1191  const TensorInfo& cellStateOut,
1192  const TensorInfo& output,
1193  const QLstmDescriptor& descriptor,
1195  Optional<std::string&> reasonIfUnsupported) const
1196 {
1197  // Check required here in order to pass IsLayerSupported for datatypes tests
1198  if (input.GetDataType() == armnn::DataType::QAsymmS8 &&
1199  previousOutputIn.GetDataType() == armnn::DataType::QAsymmS8 &&
1200  previousCellStateIn.GetDataType() == armnn::DataType::QSymmS16 &&
1201  outputStateOut.GetDataType() == armnn::DataType::QAsymmS8 &&
1202  cellStateOut.GetDataType() == armnn::DataType::QSymmS16 &&
1204  {
1206  reasonIfUnsupported,
1207  input,
1208  previousCellStateIn,
1209  previousOutputIn,
1210  cellStateOut,
1211  outputStateOut,
1212  output,
1213  descriptor,
1214  paramsInfo);
1215  }
1216  else
1217  {
1218  return false;
1219  }
1220 }
1221 
1223  const TensorInfo& output,
1224  Optional<std::string&> reasonIfUnsupported) const
1225 {
1227  reasonIfUnsupported,
1228  input,
1229  output);
1230 }
1231 
1233  const TensorInfo& cellStateIn,
1234  const TensorInfo& outputStateIn,
1235  const TensorInfo& cellStateOut,
1236  const TensorInfo& outputStateOut,
1238  Optional<std::string&> reasonIfUnsupported) const
1239 {
1241  reasonIfUnsupported,
1242  input,
1243  cellStateIn,
1244  outputStateIn,
1245  cellStateOut,
1246  outputStateOut,
1247  paramsInfo);
1248 }
1249 
1251  const TensorInfo& output,
1253  Optional<std::string&> reasonIfUnsupported) const
1254 {
1256  reasonIfUnsupported,
1257  input,
1258  output,
1259  descriptor);
1260 }
1261 
1263  const TensorInfo& output,
1265  Optional<std::string&> reasonIfUnsupported) const
1266 {
1267  armnn::IgnoreUnused(descriptor);
1269  reasonIfUnsupported,
1270  input,
1271  output);
1272 }
1273 
1275  const TensorInfo& output,
1277  Optional<std::string&> reasonIfUnsupported) const
1278 {
1280  reasonIfUnsupported,
1281  input,
1282  output,
1283  descriptor);
1284 }
1285 
1287  const TensorInfo& output,
1288  const SliceDescriptor& descriptor,
1289  Optional<std::string&> reasonIfUnsupported) const
1290 {
1292  reasonIfUnsupported,
1293  input,
1294  output,
1295  descriptor);
1296 }
1297 
1299  const TensorInfo& output,
1301  Optional<std::string&> reasonIfUnsupported) const
1302 {
1303  FORWARD_WORKLOAD_VALIDATE_FUNC(NeonSoftmaxWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
1304 }
1305 
1307  const TensorInfo& output,
1309  Optional<std::string&> reasonIfUnsupported) const
1310 {
1312  reasonIfUnsupported,
1313  input,
1314  output,
1315  descriptor);
1316 }
1317 
1319  const TensorInfo& output,
1321  Optional<std::string&> reasonIfUnsupported) const
1322 {
1324  reasonIfUnsupported,
1325  input,
1326  output,
1327  descriptor);
1328 }
1329 
1331  const std::vector<std::reference_wrapper<TensorInfo>>& outputs,
1332  const ViewsDescriptor& descriptor,
1333  Optional<std::string&> reasonIfUnsupported) const
1334 {
1335 #if defined(ARMCOMPUTENEON_ENABLED)
1336  // Split along the last dimension, cannot use sub-tensors
1337  // as width and height of the sub-tensors do not match
1338  // the width and height of the parent tensor
1339  // in case of input with more than 2D.
1340  std::set<unsigned int> splitAxis = ComputeSplitAxis(descriptor, input.GetShape());
1341  if (descriptor.GetNumDimensions() > 2 && splitAxis.size() == 1 &&
1342  *splitAxis.begin() == descriptor.GetNumDimensions() - 1 )
1343  {
1345  reasonIfUnsupported,
1346  input,
1347  outputs,
1348  *splitAxis.begin());
1349  }
1350 #endif
1351  IgnoreUnused(descriptor);
1352  for (auto output : outputs)
1353  {
1354  if (!input.IsTypeSpaceMatch(output)) // Cannot use sub-tensors if the types are not same space
1355  {
1356  SetValueChecked(reasonIfUnsupported, "Neon Splitter: Types and quantization parameters must match.");
1357  return false;
1358  }
1359  }
1360  return true;
1361 }
1362 
1363 bool NeonLayerSupport::IsStackSupported(const std::vector<const TensorInfo*>& inputs,
1364  const TensorInfo& output,
1365  const StackDescriptor& descriptor,
1366  Optional<std::string&> reasonIfUnsupported) const
1367 {
1369  reasonIfUnsupported,
1370  inputs,
1371  output,
1372  descriptor);
1373 }
1374 
1376  const TensorInfo& output,
1378  Optional<std::string&> reasonIfUnsupported) const
1379 {
1381  reasonIfUnsupported,
1382  input,
1383  output,
1384  descriptor);
1385 }
1386 
1388  const TensorInfo& input1,
1389  const TensorInfo& output,
1390  Optional<std::string&> reasonIfUnsupported) const
1391 {
1393  reasonIfUnsupported,
1394  input0,
1395  input1,
1396  output,
1397  nullptr);
1398 }
1399 
1401  const TensorInfo& output,
1403  const TensorInfo& weights,
1405  Optional<std::string&> reasonIfUnsupported) const
1406 {
1408  reasonIfUnsupported,
1409  input,
1410  output,
1411  descriptor,
1412  weights,
1413  biases);
1414 }
1415 
1417  const TensorInfo& output,
1419  Optional<std::string&> reasonIfUnsupported) const
1420 {
1421  FORWARD_WORKLOAD_VALIDATE_FUNC(NeonTransposeWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
1422 }
1423 
1424 } // 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:434
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
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
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.
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 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)
const TensorInfo const TensorInfo const TensorInfo const TensorInfo & outputStateOut
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 ResizeBilinearDescriptor for the ResizeBilinearLayer.
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:35
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)
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
arm_compute::Status NeonCastValidate(const TensorInfo &input, const TensorInfo &output)
A GatherDescriptor for the GatherLayer.
Status
enumeration
Definition: Types.hpp:29
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
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
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
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
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)
const TensorInfo & output
A SpaceToBatchNdDescriptor for the SpaceToBatchNdLayer.
arm_compute::Status NeonNormalizationWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const NormalizationDescriptor &descriptor)
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
uint32_t GetNumDimensions() const
Get the number of dimensions.
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)
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.
const TensorInfo const TensorInfo const TensorInfo const TensorInfo const TensorInfo & cellStateOut
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:458
bool IsPermuteSupported(const TensorInfo &input, const TensorInfo &output, const PermuteDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override