ArmNN
 22.02
ClLayerSupport.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 "ClLayerSupport.hpp"
7 #include "ClBackendId.hpp"
9 
11 
12 #include <InternalTypes.hpp>
13 #include <LayerSupportCommon.hpp>
14 
17 
18 #if defined(ARMCOMPUTECL_ENABLED)
81 #endif
82 
83 
84 namespace armnn
85 {
86 
87 namespace
88 {
89 
90 template<unsigned int FilterSize>
91 bool IsMatchingSize2d(const TensorInfo& weightInfo)
92 {
93  // Width & Height must match.
94  return (weightInfo.GetShape()[3] == FilterSize) && (weightInfo.GetShape()[2] == FilterSize);
95 }
96 
97 template<uint32_t ValidStride>
98 bool IsMatchingStride(uint32_t actualStride)
99 {
100  return ValidStride == actualStride;
101 }
102 
103 template<uint32_t FirstStride, uint32_t SecondStride, uint32_t... ValidStrides>
104 bool IsMatchingStride(uint32_t actualStride)
105 {
106  return IsMatchingStride<FirstStride>(actualStride) || IsMatchingStride<SecondStride, ValidStrides...>(actualStride);
107 }
108 
109 template<typename ... Args>
110 bool IsClBackendSupported(Optional<std::string&> reasonIfUnsupported, Args... args)
111 {
112  IgnoreUnused(reasonIfUnsupported, (args)...);
113 #if defined(ARMCOMPUTECL_ENABLED)
114  return true;
115 #else
116  if (reasonIfUnsupported)
117  {
118  reasonIfUnsupported.value() = "The armnn library has been built without CL support";
119  }
120  return false;
121 #endif
122 }
123 
124 #if defined(ARMCOMPUTECL_ENABLED)
125 #define FORWARD_CL_LAYER_SUPPORT_FUNC(expr) (expr)
126 #else
127 #define FORWARD_CL_LAYER_SUPPORT_FUNC(expr) IsClBackendSupported(reasonIfUnsupported)
128 #endif
129 
130 #if defined(ARMCOMPUTECL_ENABLED)
131 template<class FuncType, class... Args>
132 inline bool IsWorkloadSupported(FuncType&& func, Optional<std::string&> reasonIfUnsupported, Args&&... args)
133 {
134  arm_compute::Status aclStatus = func(std::forward<Args>(args)...);
135  const bool supported = (aclStatus.error_code() == arm_compute::ErrorCode::OK);
136  if (!supported && reasonIfUnsupported)
137  {
138  reasonIfUnsupported.value() = aclStatus.error_description();
139  }
140  return supported;
141 }
142 
143 #define FORWARD_WORKLOAD_VALIDATE_FUNC(func, reasonIfUnsupported, ...) \
144  return IsWorkloadSupported(func, reasonIfUnsupported, __VA_ARGS__);
145 #else
146 #define FORWARD_WORKLOAD_VALIDATE_FUNC(func, reasonIfUnsupported, ...) \
147  return IsClBackendSupported(reasonIfUnsupported, __VA_ARGS__);
148 #endif
149 
150 template<typename FloatFunc, typename Uint8Func, typename ... Params>
151 bool IsSupportedForDataTypeCl(Optional<std::string&> reasonIfUnsupported,
152  DataType dataType,
153  FloatFunc floatFuncPtr,
154  Uint8Func uint8FuncPtr,
155  Params&&... params)
156 {
157  return IsClBackendSupported(reasonIfUnsupported) &&
158  IsSupportedForDataTypeGeneric(reasonIfUnsupported,
159  dataType,
160  floatFuncPtr,
161  floatFuncPtr,
162  uint8FuncPtr,
163  &FalseFunc<>,
164  &FalseFunc<>,
165  std::forward<Params>(params)...);
166 }
167 } // anonymous namespace
168 
170  : m_ModelContextPtr(modelContextPtr)
171 {
172 }
173 
175  : m_ModelContextPtr(nullptr)
176 {
177 }
178 
180  const std::vector<TensorInfo>& infos,
181  const BaseDescriptor& descriptor,
182  const Optional<LstmInputParamsInfo>& lstmParamsInfo,
183  const Optional<QuantizedLstmInputParamsInfo>& quantizedLstmParamsInfo,
184  Optional<std::string&> reasonIfUnsupported) const
185 {
186  switch (type)
187  {
189  return IsActivationSupported(infos[0],
190  infos[1],
191  *(PolymorphicDowncast<const ActivationDescriptor*>(&descriptor)),
192  reasonIfUnsupported);
193  case LayerType::Addition:
194  return IsAdditionSupported(infos[0], infos[1], infos[2], reasonIfUnsupported);
196  return IsArgMinMaxSupported(infos[0],
197  infos[1],
198  *(PolymorphicDowncast<const ArgMinMaxDescriptor*>(&descriptor)),
199  reasonIfUnsupported);
201  return IsBatchNormalizationSupported(infos[0],
202  infos[1],
203  infos[2],
204  infos[3],
205  infos[4],
206  infos[5],
207  *(PolymorphicDowncast<const BatchNormalizationDescriptor*>
208  (&descriptor)),
209  reasonIfUnsupported);
211  return IsBatchToSpaceNdSupported(infos[0],
212  infos[1],
213  *(PolymorphicDowncast<const BatchToSpaceNdDescriptor*>(&descriptor)),
214  reasonIfUnsupported);
216  return IsComparisonSupported(infos[0],
217  infos[1],
218  infos[2],
219  *(PolymorphicDowncast<const ComparisonDescriptor*>(&descriptor)),
220  reasonIfUnsupported);
221  case LayerType::Concat:
222  {
223  std::vector<const TensorInfo*> inputInfos;
224  for (uint32_t i = 0; i < (infos.size() - 1); i++)
225  {
226  inputInfos.push_back(&infos[i]);
227  }
228  return IsConcatSupported(inputInfos,
229  infos[infos.size() - 1],
230  *(PolymorphicDowncast<const OriginsDescriptor*>(&descriptor)),
232  }
233  case LayerType::Constant:
234  return IsConstantSupported(infos[0], reasonIfUnsupported);
236  return IsConvertFp16ToFp32Supported(infos[0], infos[1], reasonIfUnsupported);
238  return IsConvertFp32ToFp16Supported(infos[0], infos[1], reasonIfUnsupported);
240  {
241  if (infos.size() != 4)
242  {
243  throw InvalidArgumentException("Invalid number of Convolution2d TensorInfos. "
244  "TensorInfos should be of format: {input, output, weights, biases}.");
245  }
246 
247  auto desc = *(PolymorphicDowncast<const Convolution2dDescriptor*>(&descriptor));
248  if (infos[3] == TensorInfo())
249  {
250  return IsConvolution2dSupported(infos[0],
251  infos[1],
252  desc,
253  infos[2],
254  EmptyOptional(),
255  reasonIfUnsupported);
256  }
257  else
258  {
259  return IsConvolution2dSupported(infos[0],
260  infos[1],
261  desc,
262  infos[2],
263  infos[3],
264  reasonIfUnsupported);
265  }
266  }
268  return IsDepthToSpaceSupported(infos[0],
269  infos[1],
270  *(PolymorphicDowncast<const DepthToSpaceDescriptor*>(&descriptor)),
271  reasonIfUnsupported);
273  {
274  if (infos.size() != 4)
275  {
276  throw InvalidArgumentException("Invalid number of DepthwiseConvolution2d TensorInfos. "
277  "TensorInfos should be of format: {input, output, weights, biases}.");
278  }
279 
280  auto desc = *(PolymorphicDowncast<const DepthwiseConvolution2dDescriptor*>(&descriptor));
281  if (infos[3] == TensorInfo())
282  {
283  return IsDepthwiseConvolutionSupported(infos[0],
284  infos[1],
285  desc,
286  infos[2],
287  EmptyOptional(),
288  reasonIfUnsupported);
289  }
290  else
291  {
292  return IsDepthwiseConvolutionSupported(infos[0],
293  infos[1],
294  desc,
295  infos[2],
296  infos[3],
297  reasonIfUnsupported);
298  }
299  }
301  return IsDequantizeSupported(infos[0], infos[1], reasonIfUnsupported);
302  case LayerType::Division:
303  return IsDivisionSupported(infos[0], infos[1], infos[2], reasonIfUnsupported);
305  return IsElementwiseUnarySupported(infos[0],
306  infos[1],
307  *(PolymorphicDowncast<const ElementwiseUnaryDescriptor*>(&descriptor)),
308  reasonIfUnsupported);
309  case LayerType::Fill:
310  return IsFillSupported(infos[0],
311  infos[1],
312  *(PolymorphicDowncast<const FillDescriptor*>(&descriptor)),
313  reasonIfUnsupported);
314  case LayerType::Floor:
315  return IsFloorSupported(infos[0], infos[1], reasonIfUnsupported);
317  return IsFullyConnectedSupported(infos[0],
318  infos[1],
319  infos[2],
320  infos[3],
321  *(PolymorphicDowncast<const FullyConnectedDescriptor*>(&descriptor)),
322  reasonIfUnsupported);
323  case LayerType::Gather:
324  return IsGatherSupported(infos[0],
325  infos[1],
326  infos[2],
327  *(PolymorphicDowncast<const GatherDescriptor*>(&descriptor)),
328  reasonIfUnsupported);
329  case LayerType::Input:
330  return IsInputSupported(infos[0], reasonIfUnsupported);
332  return IsInstanceNormalizationSupported(infos[0],
333  infos[1],
334  *(PolymorphicDowncast<const InstanceNormalizationDescriptor*>
335  (&descriptor)),
336  reasonIfUnsupported);
338  return IsL2NormalizationSupported(infos[0],
339  infos[1],
340  *(PolymorphicDowncast<const L2NormalizationDescriptor*>(&descriptor)),
341  reasonIfUnsupported);
343  return IsLogicalBinarySupported(infos[0],
344  infos[1],
345  infos[2],
346  *(PolymorphicDowncast<const LogicalBinaryDescriptor*>(&descriptor)),
347  reasonIfUnsupported);
349  return IsLogSoftmaxSupported(infos[0],
350  infos[1],
351  *(PolymorphicDowncast<const LogSoftmaxDescriptor*>(&descriptor)),
352  reasonIfUnsupported);
353  case LayerType::Lstm:
354  return IsLstmSupported(infos[0],
355  infos[1],
356  infos[2],
357  infos[3],
358  infos[4],
359  infos[5],
360  infos[6],
361  *(PolymorphicDowncast<const LstmDescriptor*>(&descriptor)),
362  lstmParamsInfo.value(),
364  case LayerType::QLstm:
365  return IsQLstmSupported(infos[0],
366  infos[1],
367  infos[2],
368  infos[3],
369  infos[4],
370  infos[5],
371  *(PolymorphicDowncast<const QLstmDescriptor*>(&descriptor)),
372  lstmParamsInfo.value(),
374  case LayerType::Maximum:
375  return IsMaximumSupported(infos[0], infos[1], infos[2], reasonIfUnsupported);
376  case LayerType::Mean:
377  return IsMeanSupported(infos[0],
378  infos[1],
379  *(PolymorphicDowncast<const MeanDescriptor*>(&descriptor)),
380  reasonIfUnsupported);
381  case LayerType::Minimum:
382  return IsMinimumSupported(infos[0], infos[1], infos[2], reasonIfUnsupported);
384  return IsMultiplicationSupported(infos[0], infos[1], infos[2], reasonIfUnsupported);
386  return IsNormalizationSupported(infos[0],
387  infos[1],
388  *(PolymorphicDowncast<const NormalizationDescriptor*>(&descriptor)),
389  reasonIfUnsupported);
390  case LayerType::Output:
391  return IsOutputSupported(infos[0], reasonIfUnsupported);
392  case LayerType::Pad:
393  return IsPadSupported(infos[0],
394  infos[1],
395  *(PolymorphicDowncast<const PadDescriptor*>(&descriptor)),
396  reasonIfUnsupported);
397  case LayerType::Permute:
398  return IsPermuteSupported(infos[0],
399  infos[1],
400  *(PolymorphicDowncast<const PermuteDescriptor*>(&descriptor)),
401  reasonIfUnsupported);
403  return IsPooling2dSupported(infos[0],
404  infos[1],
405  *(PolymorphicDowncast<const Pooling2dDescriptor*>(&descriptor)),
406  reasonIfUnsupported);
407  case LayerType::Prelu:
408  return IsPreluSupported(infos[0], infos[1], infos[2], reasonIfUnsupported);
409  case LayerType::Quantize:
410  return IsQuantizeSupported(infos[0], infos[1], reasonIfUnsupported);
412  return IsQuantizedLstmSupported(infos[0],
413  infos[1],
414  infos[2],
415  infos[3],
416  infos[4],
417  quantizedLstmParamsInfo.value(),
419  case LayerType::Reshape:
420  return IsReshapeSupported(infos[0],
421  infos[1],
422  *(PolymorphicDowncast<const ReshapeDescriptor*>(&descriptor)),
423  reasonIfUnsupported);
424  case LayerType::Resize:
425  return IsResizeSupported(infos[0],
426  infos[1],
427  *(PolymorphicDowncast<const ResizeDescriptor*>(&descriptor)),
428  reasonIfUnsupported);
429  case LayerType::Reduce:
430  return IsReduceSupported(infos[0],
431  infos[1],
432  *(PolymorphicDowncast<const ReduceDescriptor*>(&descriptor)),
433  reasonIfUnsupported);
434  case LayerType::Slice:
435  return IsSliceSupported(infos[0],
436  infos[1],
437  *(PolymorphicDowncast<const SliceDescriptor*>(&descriptor)),
438  reasonIfUnsupported);
439  case LayerType::Softmax:
440  return IsSoftmaxSupported(infos[0],
441  infos[1],
442  *(PolymorphicDowncast<const SoftmaxDescriptor*>(&descriptor)),
443  reasonIfUnsupported);
445  return IsSpaceToBatchNdSupported(infos[0],
446  infos[1],
447  *(PolymorphicDowncast<const SpaceToBatchNdDescriptor*>(&descriptor)),
448  reasonIfUnsupported);
450  return IsSpaceToDepthSupported(infos[0],
451  infos[1],
452  *(PolymorphicDowncast<const SpaceToDepthDescriptor*>(&descriptor)),
453  reasonIfUnsupported);
454  case LayerType::Splitter:
455  {
456  std::vector<TensorInfo> outputInfos;
457  for (uint32_t i = 1; i < infos.size(); i++)
458  {
459  outputInfos.push_back(infos[i]);
460  }
461  return IsSplitterSupported(infos[0],
462  {outputInfos.begin(), outputInfos.end()},
463  *(PolymorphicDowncast<const ViewsDescriptor*>(&descriptor)),
465  }
466  case LayerType::Stack:
467  {
468  std::vector<const TensorInfo*> inputInfos;
469  for (uint32_t i = 0; i < infos.size() - 1; i++)
470  {
471  inputInfos.push_back(&infos[i]);
472  }
473  return IsStackSupported(inputInfos,
474  infos[infos.size() - 1],
475  *(PolymorphicDowncast<const StackDescriptor*>(&descriptor)),
477  }
479  return IsStridedSliceSupported(infos[0],
480  infos[1],
481  *(PolymorphicDowncast<const StridedSliceDescriptor*>(&descriptor)),
482  reasonIfUnsupported);
484  return IsSubtractionSupported(infos[0], infos[1], infos[2], reasonIfUnsupported);
486  return IsTransposeSupported(infos[0],
487  infos[1],
488  *(PolymorphicDowncast<const TransposeDescriptor*>(&descriptor)),
489  reasonIfUnsupported);
491  {
492  if (infos.size() != 4)
493  {
494  throw InvalidArgumentException("Invalid number of TransposeConvolution2d TensorInfos. "
495  "TensorInfos should be of format: {input, output, weights, biases}.");
496  }
497 
498  auto desc = *(PolymorphicDowncast<const TransposeConvolution2dDescriptor*>(&descriptor));
499  if (infos[3] == TensorInfo())
500  {
501  return IsTransposeConvolution2dSupported(infos[0],
502  infos[1],
503  desc,
504  infos[2],
505  EmptyOptional(),
506  reasonIfUnsupported);
507  }
508  else
509  {
510  return IsTransposeConvolution2dSupported(infos[0],
511  infos[1],
512  desc,
513  infos[2],
514  infos[3],
515  reasonIfUnsupported);
516  }
517  }
518  case LayerType::Cast:
519  return IsCastSupported(infos[0], infos[1], reasonIfUnsupported);
521  return IsChannelShuffleSupported(infos[0],
522  infos[1],
523  *(PolymorphicDowncast<const ChannelShuffleDescriptor*>(&descriptor)),
524  reasonIfUnsupported);
526  {
527  if (infos.size() != 4)
528  {
529  throw InvalidArgumentException("Invalid number of Convolution3d TensorInfos. "
530  "TensorInfos should be of format: {input, output, weights, biases}.");
531  }
532 
533  auto desc = *(PolymorphicDowncast<const Convolution3dDescriptor*>(&descriptor));
534  if (infos[3] == TensorInfo())
535  {
536  return IsConvolution3dSupported(infos[0],
537  infos[1],
538  desc,
539  infos[2],
540  EmptyOptional(),
541  reasonIfUnsupported);
542  }
543  else
544  {
545  return IsConvolution3dSupported(infos[0],
546  infos[1],
547  desc,
548  infos[2],
549  infos[3],
550  reasonIfUnsupported);
551  }
552  }
553  case LayerType::MemCopy:
554  return LayerSupportBase::IsMemCopySupported(infos[0], infos[1], reasonIfUnsupported);
556  return LayerSupportBase::IsMemImportSupported(infos[0], infos[1], reasonIfUnsupported);
557  case LayerType::Map:
558  return true;
559  case LayerType::Unmap:
560  return true;
561  case LayerType::Merge:
562  return LayerSupportBase::IsMergeSupported(infos[0],
563  infos[1],
564  infos[2],
565  reasonIfUnsupported);
566  case LayerType::Rank:
567  return true;
568  case LayerType::Shape:
569  return LayerSupportBase::IsShapeSupported(infos[0],
570  infos[1],
571  reasonIfUnsupported);
574  infos[1],
575  reasonIfUnsupported);
578  infos[1],
579  reasonIfUnsupported);
580  default:
581  // layers not supported in cl by default:
582  // debug, detectionpostprocess, fakequantization, precompiled,
583  // standin, switch, unidirectionalsequencelstm, pooling3d
584  return false;
585  }
586 }
587 
589  const TensorInfo& output,
591  Optional<std::string&> reasonIfUnsupported) const
592 {
594  reasonIfUnsupported,
595  input,
596  output,
597  descriptor);
598 }
599 
601  const TensorInfo& input1,
602  const TensorInfo& output,
603  Optional<std::string&> reasonIfUnsupported) const
604 {
606  reasonIfUnsupported,
607  input0,
608  input1,
609  output,
610  nullptr);
611 }
612 
614  const TensorInfo& output,
616  Optional<std::string&> reasonIfUnsupported) const
617 {
618 
620  reasonIfUnsupported,
621  input,
622  output,
623  descriptor);
624 }
625 
627  const TensorInfo& output,
628  const TensorInfo& mean,
629  const TensorInfo& var,
630  const TensorInfo& beta,
631  const TensorInfo& gamma,
633  Optional<std::string&> reasonIfUnsupported) const
634 {
636  reasonIfUnsupported,
637  input,
638  output,
639  mean,
640  var,
641  beta,
642  gamma,
643  descriptor,
644  nullptr);
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& output,
661  Optional<std::string&> reasonIfUnsupported) const
662 {
664  reasonIfUnsupported,
665  input,
666  output);
667 }
668 
670  const TensorInfo& output,
672  Optional<std::string&> reasonIfUnsupported) const
673 {
675  reasonIfUnsupported,
676  input,
677  output,
678  descriptor);
679 }
680 
682  const TensorInfo& input1,
683  const TensorInfo& output,
685  Optional<std::string&> reasonIfUnsupported) const
686 {
688  reasonIfUnsupported,
689  input0,
690  input1,
691  output,
692  descriptor);
693 }
694 
695 bool ClLayerSupport::IsConcatSupported(const std::vector<const TensorInfo*> inputs,
696  const TensorInfo& output,
698  Optional<std::string&> reasonIfUnsupported) const
699 {
700  if (descriptor.GetNumDimensions() <= descriptor.GetConcatAxis())
701  {
702  SetValueChecked(reasonIfUnsupported, "Cl Concat: Concat axis > Number of dimensions.");
703  return false;
704  }
705 
706  unsigned int concatInnerAxis = (descriptor.GetNumDimensions() - descriptor.GetConcatAxis()) - 1;
707  if(concatInnerAxis < 3) // Width, height, or channels
708  {
710  reasonIfUnsupported,
711  inputs,
712  output,
713  descriptor);
714  }
715  else if (concatInnerAxis == 3)
716  {
717  // We rely on the sub-tensor optimization to handle the batch dimension for 4D tensors. If we can't use
718  // sub-tensors for this then we can't support it. Here is where we check that the sub-tensors will work.
719  for (auto& input : inputs)
720  {
721  if (input && !output.IsTypeSpaceMatch(*input)) // Cannot use sub-tensors if the types are not same space
722  {
723  SetValueChecked(reasonIfUnsupported, "Cl Concat: Types and quantization parameters must match.");
724  return false;
725  }
726  }
727  return true; // Sub-tensors support concat along batch
728  }
729  else // > 4 dimensions not supported.
730  {
731  SetValueChecked(reasonIfUnsupported, "Cl Concat: Maximum of 4 dimensions supported.");
732  return false;
733  }
734 }
735 
737  Optional<std::string&> reasonIfUnsupported) const
738 {
740  reasonIfUnsupported,
741  output);
742 }
743 
745  const TensorInfo& output,
746  Optional<std::string&> reasonIfUnsupported) const
747 {
749  reasonIfUnsupported,
750  input,
751  output);
752 }
753 
755  const TensorInfo& output,
756  Optional<std::string&> reasonIfUnsupported) const
757 {
759  reasonIfUnsupported,
760  input,
761  output);
762 }
763 
765  const TensorInfo& output,
767  const TensorInfo& weights,
769  Optional<std::string&> reasonIfUnsupported) const
770 {
771  bool isFastMathEnabled = false;
772 #if defined(ARMCOMPUTECL_ENABLED)
773  if (m_ModelContextPtr)
774  {
775  if (m_ModelContextPtr.get() != nullptr)
776  {
777  auto modelOptions = dynamic_cast<ClBackendModelContext*>(m_ModelContextPtr.get());
778  if (modelOptions)
779  {
780  isFastMathEnabled = modelOptions->IsFastMathEnabled();
781  }
782  }
783  }
784 #endif
785 
787  reasonIfUnsupported,
788  input,
789  output,
790  descriptor,
791  weights,
792  biases,
793  isFastMathEnabled,
794  nullptr);
795 }
796 
798  const TensorInfo& output,
800  const TensorInfo& weights,
802  Optional<std::string&> reasonIfUnsupported) const
803 {
804  bool isFastMathEnabled = false;
805 #if defined(ARMCOMPUTECL_ENABLED)
806  if (m_ModelContextPtr)
807 {
808  if (m_ModelContextPtr.get() != nullptr)
809  {
810  auto modelOptions = dynamic_cast<ClBackendModelContext*>(m_ModelContextPtr.get());
811  if (modelOptions)
812  {
813  isFastMathEnabled = modelOptions->IsFastMathEnabled();
814  }
815  }
816 }
817 #endif
818 
820  reasonIfUnsupported,
821  input,
822  output,
823  descriptor,
824  weights,
825  biases,
826  isFastMathEnabled,
827  nullptr);
828 }
829 
831  const TensorInfo& output,
832  Optional<std::string&> reasonIfUnsupported) const
833 {
835  reasonIfUnsupported,
836  input,
837  output);
838 }
839 
841  const TensorInfo& output,
843  Optional<std::string&> reasonIfUnsupported) const
844 {
846  reasonIfUnsupported,
847  input,
848  output,
849  descriptor);
850 }
851 
853  const TensorInfo& output,
855  const TensorInfo& weights,
857  Optional<std::string&> reasonIfUnsupported) const
858 {
860  reasonIfUnsupported,
861  input,
862  output,
863  descriptor,
864  weights,
865  biases,
866  nullptr);
867 }
868 
870  const TensorInfo& output,
872  const TensorInfo& weights,
874  Optional<std::string&> reasonIfUnsupported) const
875 {
877  reasonIfUnsupported,
878  input,
879  output,
880  descriptor,
881  weights,
882  biases,
883  nullptr);
884 }
885 
886 
888  const TensorInfo& input1,
889  const TensorInfo& output,
890  Optional<std::string&> reasonIfUnsupported) const
891 {
893  reasonIfUnsupported,
894  input0,
895  input1,
896  output,
897  nullptr);
898 }
899 
901  const TensorInfo& output,
903  Optional<std::string&> reasonIfUnsupported) const
904 {
905  switch(descriptor.m_Operation)
906  {
907  case UnaryOperation::Abs:
909  reasonIfUnsupported,
910  input,
911  output);
912  case UnaryOperation::Exp:
914  reasonIfUnsupported,
915  input,
916  output);
917  case UnaryOperation::Log:
919  reasonIfUnsupported,
920  input,
921  output);
924  reasonIfUnsupported,
925  input,
926  output);
927  case UnaryOperation::Neg:
929  reasonIfUnsupported,
930  input,
931  output);
934  reasonIfUnsupported,
935  input,
936  output);
937  case UnaryOperation::Sin:
939  reasonIfUnsupported,
940  input,
941  output);
942  default:
943  return false;
944  }
945 }
946 
948  const TensorInfo& output,
949  const FillDescriptor& descriptor,
950  Optional<std::string&> reasonIfUnsupported) const
951 {
952  armnn::IgnoreUnused(input);
953  armnn::IgnoreUnused(output);
954  armnn::IgnoreUnused(descriptor);
955 
956  return IsClBackendSupported(reasonIfUnsupported);
957 }
958 
960  const TensorInfo& output,
961  Optional<std::string&> reasonIfUnsupported) const
962 {
964  reasonIfUnsupported,
965  input,
966  output);
967 }
968 
970  const TensorInfo& output,
971  const TensorInfo& weights,
972  const TensorInfo& biases,
974  Optional<std::string&> reasonIfUnsupported) const
975 {
977  reasonIfUnsupported,
978  input,
979  output,
980  weights,
981  biases,
982  descriptor,
983  nullptr);
984 }
985 
987  const TensorInfo& input1,
988  const TensorInfo& output,
990  Optional<std::string&> reasonIfUnsupported) const
991 {
993  reasonIfUnsupported,
994  input0,
995  input1,
996  output,
997  descriptor);
998 }
999 
1001  Optional<std::string&> reasonIfUnsupported) const
1002 {
1003  return IsClBackendSupported(reasonIfUnsupported, input);
1004 }
1005 
1007  const TensorInfo& output,
1009  Optional<std::string&> reasonIfUnsupported) const
1010 {
1012  reasonIfUnsupported,
1013  input,
1014  output,
1015  descriptor);
1016 }
1017 
1019  const TensorInfo& output,
1021  Optional<std::string&> reasonIfUnsupported) const
1022 {
1024  reasonIfUnsupported,
1025  input,
1026  output,
1027  descriptor);
1028 }
1029 
1031  const TensorInfo& input1,
1032  const TensorInfo& output,
1034  Optional<std::string&> reasonIfUnsupported) const
1035 {
1036  IgnoreUnused(output);
1037 
1038  switch(descriptor.m_Operation)
1039  {
1042  reasonIfUnsupported,
1043  input0,
1044  input1,
1045  output);
1048  reasonIfUnsupported,
1049  input0,
1050  input1,
1051  output);
1052  default:
1053  return false;
1054  }
1055 }
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& outputStateIn,
1072  const TensorInfo& cellStateIn,
1073  const TensorInfo& scratchBuffer,
1074  const TensorInfo& outputStateOut,
1075  const TensorInfo& cellStateOut,
1076  const TensorInfo& output,
1077  const LstmDescriptor& descriptor,
1079  Optional<std::string&> reasonIfUnsupported) const
1080 {
1082  reasonIfUnsupported,
1083  input,
1084  outputStateIn,
1085  cellStateIn,
1086  scratchBuffer,
1087  outputStateOut,
1088  cellStateOut,
1089  output,
1090  descriptor,
1091  paramsInfo);
1092 }
1093 
1095  const TensorInfo& input1,
1096  const TensorInfo& output,
1097  Optional<std::string&> reasonIfUnsupported) const
1098 {
1100  reasonIfUnsupported,
1101  input0,
1102  input1,
1103  output);
1104 }
1105 
1107  const TensorInfo& output,
1108  const MeanDescriptor& descriptor,
1109  Optional<std::string&> reasonIfUnsupported) const
1110 {
1112  reasonIfUnsupported,
1113  input,
1114  output,
1115  descriptor);
1116 }
1117 
1119  const TensorInfo& input1,
1120  const TensorInfo& output,
1121  Optional<std::string&> reasonIfUnsupported) const
1122 {
1124  reasonIfUnsupported,
1125  input0,
1126  input1,
1127  output);
1128 }
1129 
1131  const TensorInfo& input1,
1132  const TensorInfo& output,
1133  Optional<std::string&> reasonIfUnsupported) const
1134 {
1136  reasonIfUnsupported,
1137  input0,
1138  input1,
1139  output,
1140  nullptr);
1141 }
1142 
1144  const TensorInfo& output,
1146  Optional<std::string&> reasonIfUnsupported) const
1147 {
1148  FORWARD_WORKLOAD_VALIDATE_FUNC(ClNormalizationWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
1149 }
1150 
1152  Optional<std::string&> reasonIfUnsupported) const
1153 {
1154  return IsClBackendSupported(reasonIfUnsupported, output);
1155 }
1156 
1158  const TensorInfo& output,
1159  const PadDescriptor& descriptor,
1160  Optional<std::string&> reasonIfUnsupported) const
1161 {
1163  reasonIfUnsupported,
1164  input,
1165  output,
1166  descriptor);
1167 }
1168 
1170  const TensorInfo& output,
1172  Optional<std::string&> reasonIfUnsupported) const
1173 {
1174  FORWARD_WORKLOAD_VALIDATE_FUNC(ClPermuteWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
1175 }
1176 
1178  const TensorInfo& output,
1180  Optional<std::string&> reasonIfUnsupported) const
1181 {
1182  FORWARD_WORKLOAD_VALIDATE_FUNC(ClPooling2dWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
1183 }
1184 
1186  const armnn::TensorInfo &alpha,
1187  const armnn::TensorInfo &output,
1188  armnn::Optional<std::string &> reasonIfUnsupported) const
1189 {
1190  FORWARD_WORKLOAD_VALIDATE_FUNC(ClPreluWorkloadValidate, reasonIfUnsupported, input, alpha, output);
1191 }
1192 
1196  const TensorInfo& outputStateOut,
1197  const TensorInfo& cellStateOut,
1198  const TensorInfo& output,
1199  const QLstmDescriptor& descriptor,
1201  Optional<std::string&> reasonIfUnsupported) const
1202 {
1203  if (input.GetDataType() == armnn::DataType::QAsymmS8 &&
1204  previousOutputIn.GetDataType() == armnn::DataType::QAsymmS8 &&
1205  previousCellStateIn.GetDataType() == armnn::DataType::QSymmS16 &&
1206  outputStateOut.GetDataType() == armnn::DataType::QAsymmS8 &&
1207  cellStateOut.GetDataType() == armnn::DataType::QSymmS16 &&
1209  {
1211  reasonIfUnsupported,
1212  input,
1213  previousCellStateIn,
1214  previousOutputIn,
1215  cellStateOut,
1216  outputStateOut,
1217  output,
1218  descriptor,
1219  paramsInfo);
1220  }
1221  else
1222  {
1223  return false;
1224  }
1225 }
1226 
1230  const TensorInfo& cellStateOut,
1231  const TensorInfo& output,
1233  Optional<std::string&> reasonIfUnsupported) const
1234 {
1236  reasonIfUnsupported,
1237  input,
1238  previousCellStateIn,
1239  previousOutputIn,
1240  cellStateOut,
1241  output,
1242  paramsInfo);
1243 }
1244 
1246  const TensorInfo& output,
1247  Optional<std::string&> reasonIfUnsupported) const
1248 {
1250  reasonIfUnsupported,
1251  input,
1252  output);
1253 }
1254 
1256  const TensorInfo& output,
1258  Optional<std::string&> reasonIfUnsupported) const
1259 {
1261  reasonIfUnsupported,
1262  input,
1263  output,
1264  descriptor);
1265 }
1266 
1268  const TensorInfo& output,
1270  Optional<std::string&> reasonIfUnsupported) const
1271 {
1272  IgnoreUnused(descriptor);
1273  FORWARD_WORKLOAD_VALIDATE_FUNC(ClReshapeWorkloadValidate, reasonIfUnsupported, input, output);
1274 }
1275 
1277  const TensorInfo& output,
1279  Optional<std::string&> reasonIfUnsupported) const
1280 {
1281  FORWARD_WORKLOAD_VALIDATE_FUNC(ClResizeWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
1282 }
1283 
1285  const TensorInfo& output,
1286  const SliceDescriptor& descriptor,
1287  Optional<std::string&> reasonIfUnsupported) const
1288 {
1289  FORWARD_WORKLOAD_VALIDATE_FUNC(ClSliceWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
1290 }
1291 
1293  const TensorInfo& output,
1295  Optional<std::string&> reasonIfUnsupported) const
1296 {
1297  FORWARD_WORKLOAD_VALIDATE_FUNC(ClSoftmaxWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
1298 }
1299 
1301  const TensorInfo& output,
1303  Optional<std::string&> reasonIfUnsupported) const
1304 {
1306  reasonIfUnsupported,
1307  input,
1308  output,
1309  descriptor);
1310 }
1311 
1313  const TensorInfo& output,
1315  Optional<std::string&> reasonIfUnsupported) const
1316 {
1318  reasonIfUnsupported,
1319  input,
1320  output,
1321  descriptor);
1322 }
1323 
1325  const std::vector<std::reference_wrapper<TensorInfo>>& outputs,
1326  const ViewsDescriptor& descriptor,
1327  Optional<std::string&> reasonIfUnsupported) const
1328 {
1329 #if defined(ARMCOMPUTECL_ENABLED)
1330  // Split along the last dimension, cannot use sub-tensors
1331  // as width and height of the sub-tensors do not match
1332  // the width and height of the parent tensor
1333  // in case of input with more than 2D.
1334  std::set<unsigned int> splitAxis = ComputeSplitAxis(descriptor, input.GetShape());
1335  if (descriptor.GetNumDimensions() > 2 && splitAxis.size() == 1 &&
1336  *splitAxis.begin() == descriptor.GetNumDimensions() - 1 )
1337  {
1339  reasonIfUnsupported,
1340  input,
1341  outputs,
1342  *splitAxis.begin());
1343  }
1344 #endif
1345  IgnoreUnused(descriptor);
1346  for (auto output : outputs)
1347  {
1348  if (!input.IsTypeSpaceMatch(output)) // Cannot use sub-tensors if the types are not same space
1349  {
1350  SetValueChecked(reasonIfUnsupported, "Cl Splitter: Types and quantization parameters must match.");
1351  return false;
1352  }
1353  }
1354  return true;
1355 }
1356 
1357 bool ClLayerSupport::IsStackSupported(const std::vector<const TensorInfo*>& inputs,
1358  const TensorInfo& output,
1359  const StackDescriptor& descriptor,
1360  Optional<std::string&> reasonIfUnsupported) const
1361 {
1363  reasonIfUnsupported,
1364  inputs,
1365  output,
1366  descriptor);
1367 }
1368 
1370  const TensorInfo& output,
1372  Optional<std::string&> reasonIfUnsupported) const
1373 {
1375  reasonIfUnsupported,
1376  input,
1377  output,
1378  descriptor);
1379 }
1380 
1382  const TensorInfo& input1,
1383  const TensorInfo& output,
1384  Optional<std::string&> reasonIfUnsupported) const
1385 {
1387  reasonIfUnsupported,
1388  input0,
1389  input1,
1390  output,
1391  nullptr);
1392 }
1393 
1395  const TensorInfo& output,
1397  const TensorInfo& weights,
1399  Optional<std::string&> reasonIfUnsupported) const
1400 {
1402  reasonIfUnsupported,
1403  input,
1404  output,
1405  descriptor,
1406  weights,
1407  biases);
1408 }
1409 
1411  const TensorInfo& output,
1413  Optional<std::string&> reasonIfUnsupported) const
1414 {
1415  FORWARD_WORKLOAD_VALIDATE_FUNC(ClTransposeWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
1416 }
1417 
1418 } // namespace armnn
bool IsMinimumSupported(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status ClAdditionValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ActivationDescriptor *activationDescriptor)
bool IsOutputSupported(const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsTransposeSupported(const TensorInfo &input, const TensorInfo &output, const TransposeDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status ClBatchToSpaceNdWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const BatchToSpaceNdDescriptor &descriptor)
arm_compute::Status ClLogicalOrWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output)
arm_compute::Status ClDequantizeWorkloadValidate(const TensorInfo &input, const TensorInfo &output)
bool IsFloorSupported(const TensorInfo &input, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status ClComparisonWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ComparisonDescriptor &descriptor)
UnaryOperation m_Operation
Specifies the elementwiseUnary operation to execute.
A ViewsDescriptor for the SplitterLayer.
arm_compute::Status ClL2NormalizationWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const L2NormalizationDescriptor &descriptor)
arm_compute::Status ClConvertFp32ToFp16WorkloadValidate(const TensorInfo &input, const TensorInfo &output)
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
arm_compute::Status ClDivisionWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ActivationDescriptor *activationDescriptor)
bool IsArgMinMaxSupported(const TensorInfo &input, const TensorInfo &output, const ArgMinMaxDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsReduceSupported(const TensorInfo &input, const TensorInfo &output, const ReduceDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
A TransposeConvolution2dDescriptor for the TransposeConvolution2dLayer.
arm_compute::Status ClConvolution3dWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const Convolution3dDescriptor &descriptor, const TensorInfo &weights, const Optional< TensorInfo > &biases, bool isFastMathEnabled, const ActivationDescriptor *activationDescriptor)
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 ClInstanceNormalizationWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const InstanceNormalizationDescriptor &descriptor)
arm_compute::Status ClLogSoftmaxWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const LogSoftmaxDescriptor &descriptor)
A ReshapeDescriptor for the ReshapeLayer.
bool IsMemImportSupported(const TensorInfo &input, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsSubtractionSupported(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
arm_compute::Status ClSplitterWorkloadValidate(const TensorInfo &input, const std::vector< std::reference_wrapper< TensorInfo >> &outputs, unsigned int splitAxis)
uint32_t GetNumDimensions() const
Get the number of dimensions.
A ComparisonDescriptor for the ComparisonLayer.
Definition: Descriptors.hpp:89
bool IsSliceSupported(const TensorInfo &input, const TensorInfo &output, const SliceDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
const TensorInfo const TensorInfo const TensorInfo const TensorInfo const TensorInfo & gamma
const std::vector< std::reference_wrapper< TensorInfo > > & outputs
arm_compute::Status ClSliceWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const SliceDescriptor &descriptor)
A Convolution2dDescriptor for the Convolution2dLayer.
bool IsQuantizeSupported(const TensorInfo &input, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status ClSubtractionValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ActivationDescriptor *activationDescriptor)
arm_compute::Status ClLstmFloatWorkloadValidate(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 IsPadSupported(const TensorInfo &input, const TensorInfo &output, const PadDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status ClPermuteWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const PermuteDescriptor &descriptor)
const TensorInfo const ActivationDescriptor Optional< std::string & > reasonIfUnsupported
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 ClTransposeWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const TransposeDescriptor &descriptor)
arm_compute::Status ClReshapeWorkloadValidate(const TensorInfo &input, const TensorInfo &output)
bool IsStridedSliceSupported(const TensorInfo &input, const TensorInfo &output, const StridedSliceDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsShapeSupported(const TensorInfo &input, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
const TensorInfo const TensorInfo const TensorInfo const TensorInfo & outputStateOut
A LogicalBinaryDescriptor for the LogicalBinaryLayer.
#define FORWARD_WORKLOAD_VALIDATE_FUNC(func, reasonIfUnsupported,...)
bool IsLogicalBinarySupported(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const LogicalBinaryDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported) const override
bool IsLogSoftmaxSupported(const TensorInfo &input, const TensorInfo &output, const LogSoftmaxDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
Copyright (c) 2021 ARM Limited and Contributors.
arm_compute::Status ClConvolution2dWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const Convolution2dDescriptor &descriptor, const TensorInfo &weights, const Optional< TensorInfo > &biases, bool isFastMathEnabled, const ActivationDescriptor *activationDescriptor)
void IgnoreUnused(Ts &&...)
const TensorInfo const ActivationDescriptor & descriptor
std::set< unsigned int > ComputeSplitAxis(const armnn::SplitterDescriptor &desc, const TensorShape &input)
bool IsPermuteSupported(const TensorInfo &input, const TensorInfo &output, const PermuteDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsConcatSupported(const std::vector< const TensorInfo *> inputs, const TensorInfo &output, const OriginsDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsComparisonSupported(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &ouput, const ComparisonDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
A SpaceToDepthDescriptor for the SpaceToDepthLayer.
bool IsNormalizationSupported(const TensorInfo &input, const TensorInfo &output, const NormalizationDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
LogicalBinaryOperation m_Operation
Specifies the logical operation to execute.
A BatchToSpaceNdDescriptor for the BatchToSpaceNdLayer.
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
const TensorInfo & outputStateIn
const TensorInfo const TensorInfo & previousCellStateIn
arm_compute::Status ClMeanValidate(const TensorInfo &input, const TensorInfo &output, const MeanDescriptor &descriptor)
arm_compute::Status ClSinWorkloadValidate(const TensorInfo &input, const TensorInfo &output)
arm_compute::Status ClChannelShuffleValidate(const TensorInfo &input, const TensorInfo &output, const ChannelShuffleDescriptor &descriptor)
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
A ResizeBilinearDescriptor for the ResizeBilinearLayer.
arm_compute::Status ClSoftmaxWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const SoftmaxDescriptor &descriptor)
const TensorInfo & alpha
Base class for all descriptors.
Definition: Descriptors.hpp:22
A StackDescriptor for the StackLayer.
bool IsQuantizedLstmSupported(const TensorInfo &input, const TensorInfo &previousCellStateIn, const TensorInfo &previousOutputIn, const TensorInfo &cellStateOut, const TensorInfo &output, const QuantizedLstmInputParamsInfo &paramsInfo, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status ClNormalizationWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const NormalizationDescriptor &descriptor)
arm_compute::Status ClPooling2dWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const Pooling2dDescriptor &descriptor)
A PadDescriptor for the PadLayer.
bool IsElementwiseUnarySupported(const TensorInfo &input, const TensorInfo &ouput, const ElementwiseUnaryDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status ClLogicalNotWorkloadValidate(const TensorInfo &input, const TensorInfo &output)
bool IsGatherSupported(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const GatherDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported) const override
arm_compute::Status ClDepthToSpaceWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const DepthToSpaceDescriptor &descriptor)
DataType
Definition: Types.hpp:35
const TensorInfo const TensorInfo & cellStateIn
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
An LstmDescriptor for the LstmLayer.
bool IsConvertFp16ToFp32Supported(const TensorInfo &input, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsDepthToSpaceSupported(const TensorInfo &input, const TensorInfo &output, const DepthToSpaceDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status ClStackWorkloadValidate(const std::vector< const TensorInfo *> &inputs, const TensorInfo &output, const StackDescriptor &descriptor)
arm_compute::Status ClConstantWorkloadValidate(const TensorInfo &output)
bool IsSpaceToBatchNdSupported(const TensorInfo &input, const TensorInfo &output, const SpaceToBatchNdDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsResizeSupported(const TensorInfo &input, const TensorInfo &output, const ResizeDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
std::shared_ptr< IBackendModelContext > IBackendSpecificModelContextPtr
arm_compute::Status ClPadValidate(const TensorInfo &input, const TensorInfo &output, const PadDescriptor &descriptor)
A L2NormalizationDescriptor for the L2NormalizationLayer.
const TensorInfo const TensorInfo const TensorInfo & var
arm_compute::Status ClSpaceToBatchNdWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const SpaceToBatchNdDescriptor &descriptor)
An ArgMinMaxDescriptor for ArgMinMaxLayer.
Definition: Descriptors.hpp:67
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 ClStridedSliceWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const StridedSliceDescriptor &descriptor)
arm_compute::Status ClMultiplicationWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ActivationDescriptor *activationDescriptor)
A GatherDescriptor for the GatherLayer.
arm_compute::Status ClConvertFp16ToFp32WorkloadValidate(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
Status
enumeration
Definition: Types.hpp:29
arm_compute::Status ClGatherWorkloadValidate(const TensorInfo &input, const TensorInfo &indices, const TensorInfo &output, const GatherDescriptor &descriptor)
bool IsFillSupported(const TensorInfo &input, const TensorInfo &output, const FillDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
const TensorInfo const TensorInfo const TensorInfo const TensorInfo & beta
bool IsStackSupported(const std::vector< const TensorInfo *> &inputs, const TensorInfo &output, const StackDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsReshapeSupported(const TensorInfo &input, const TensorInfo &output, const ReshapeDescriptor &descriptor, 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
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 ClFullyConnectedWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const TensorInfo &weights, const Optional< TensorInfo > &biases, const FullyConnectedDescriptor &descriptor, const ActivationDescriptor *activationDescriptor)
An ActivationDescriptor for the ActivationLayer.
Definition: Descriptors.hpp:36
arm_compute::Status ClSpaceToDepthWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const SpaceToDepthDescriptor &descriptor)
bool IsChannelShuffleSupported(const TensorInfo &input, const TensorInfo &output, const ChannelShuffleDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
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
arm_compute::Status ClBatchNormalizationValidate(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 IsMemCopySupported(const TensorInfo &input, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
A SliceDescriptor for the SliceLayer.
A Convolution3dDescriptor for the Convolution3dLayer.
bool IsDivisionSupported(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
const TensorInfo & previousOutputIn
bool IsMultiplicationSupported(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status ClResizeWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const ResizeDescriptor &descriptor)
bool IsFullyConnectedSupported(const TensorInfo &input, const TensorInfo &output, const TensorInfo &weights, const TensorInfo &biases, const FullyConnectedDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
void SetValueChecked(Optional< T &> optionalRef, V &&val)
bool IsDequantizeSupported(const TensorInfo &input, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
const TensorInfo & output
A SpaceToBatchNdDescriptor for the SpaceToBatchNdLayer.
bool IsConvertBf16ToFp32Supported(const TensorInfo &input, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
bool IsCastSupported(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
A ElementwiseUnaryDescriptor for the ElementwiseUnaryLayer.
bool IsAdditionSupported(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, 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 ClPreluWorkloadValidate(const TensorInfo &input, const TensorInfo &alpha, const TensorInfo &output)
arm_compute::Status ClCastValidate(const TensorInfo &input, const TensorInfo &output)
arm_compute::Status ClAbsWorkloadValidate(const TensorInfo &input, const TensorInfo &output)
bool IsMeanSupported(const TensorInfo &input, const TensorInfo &output, const MeanDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
const TensorInfo const Convolution2dDescriptor const TensorInfo const Optional< TensorInfo > & biases
arm_compute::Status ClMinimumWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output)
uint32_t GetNumDimensions() const
Get the number of dimensions.
A MeanDescriptor for the MeanLayer.
arm_compute::Status ClNegWorkloadValidate(const TensorInfo &input, const TensorInfo &output)
bool IsInputSupported(const TensorInfo &input, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status ClArgMinMaxWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const ArgMinMaxDescriptor &descriptor)
A TransposeDescriptor for the TransposeLayer.
A StridedSliceDescriptor for the StridedSliceLayer.
arm_compute::Status ClConcatWorkloadValidate(const std::vector< const TensorInfo *> &inputs, const TensorInfo &output, const OriginsDescriptor &descriptor)
bool IsSoftmaxSupported(const TensorInfo &input, const TensorInfo &output, const SoftmaxDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status ClExpWorkloadValidate(const TensorInfo &input, const TensorInfo &output)
arm_compute::Status ClQLstmWorkloadValidate(const TensorInfo &input, const TensorInfo &cellStateIn, const TensorInfo &outputStateIn, const TensorInfo &cellStateOut, const TensorInfo &outputStateOut, const TensorInfo &output, const QLstmDescriptor &descriptor, const LstmInputParamsInfo &paramsInfo)
const TensorInfo & input1
arm_compute::Status ClTransposeConvolution2dWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const TransposeConvolution2dDescriptor &descriptor, const TensorInfo &weights, const Optional< TensorInfo > &biases)
bool IsL2NormalizationSupported(const TensorInfo &input, const TensorInfo &output, const L2NormalizationDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status ClActivationWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const ActivationDescriptor &descriptor)
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
A Pooling2dDescriptor for the Pooling2dLayer.
A NormalizationDescriptor for the NormalizationLayer.
bool IsConvertFp32ToBf16Supported(const TensorInfo &input, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status ClLogWorkloadValidate(const TensorInfo &input, const TensorInfo &output)
The ClBackendModelContext is used to pass in CL specific backend ModelOptions.
const TensorInfo const TensorInfo const TensorInfo & scratchBuffer
An InstanceNormalizationDescriptor for InstanceNormalizationLayer.
bool IsConvertFp32ToFp16Supported(const TensorInfo &input, const TensorInfo &output, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
unsigned int GetConcatAxis() const
Get the concatenation axis value.
bool IsInstanceNormalizationSupported(const TensorInfo &input, const TensorInfo &output, const InstanceNormalizationDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
A ChannelShuffleDescriptor for the ChannelShuffle operator.
const TensorInfo const TensorInfo const TensorInfo const TensorInfo const TensorInfo & cellStateOut
bool IsPooling2dSupported(const TensorInfo &input, const TensorInfo &output, const Pooling2dDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
arm_compute::Status ClMaximumWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output)
bool IsActivationSupported(const TensorInfo &input, const TensorInfo &output, const ActivationDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
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 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 ClDepthwiseConvolutionWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const DepthwiseConvolution2dDescriptor &descriptor, const TensorInfo &weights, const Optional< TensorInfo > &biases, const ActivationDescriptor *activationDescriptor)
const TensorInfo const Convolution2dDescriptor const TensorInfo & weights
arm_compute::Status ClQuantizedLstmWorkloadValidate(const TensorInfo &input, const TensorInfo &previousCellStateIn, const TensorInfo &previousOutputIn, const TensorInfo &cellStateOut, const TensorInfo &output, const QuantizedLstmInputParamsInfo &paramsInfo)
arm_compute::Status ClFloorWorkloadValidate(const TensorInfo &input, const TensorInfo &output)
arm_compute::Status ClRsqrtWorkloadValidate(const TensorInfo &input, const TensorInfo &output)
bool IsSpaceToDepthSupported(const TensorInfo &input, const TensorInfo &output, const SpaceToDepthDescriptor &descriptor, 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 ClLogicalAndWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output)
arm_compute::Status ClQuantizeWorkloadValidate(const TensorInfo &input, const TensorInfo &output)
const TensorInfo const TensorInfo & mean
A PermuteDescriptor for the PermuteLayer.
bool IsBatchToSpaceNdSupported(const TensorInfo &input, const TensorInfo &output, const BatchToSpaceNdDescriptor &descriptor, Optional< std::string &> reasonIfUnsupported=EmptyOptional()) const override
LayerType
When adding a new layer, adapt also the LastLayer enum value in the enum class LayerType below...
Definition: Types.hpp:458
bool IsConstantSupported(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
arm_compute::Status ClReduceWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const ReduceDescriptor &descriptor)