ArmNN
 26.07
NeonWorkloadFactory Class Reference

#include <NeonWorkloadFactory.hpp>

Inheritance diagram for NeonWorkloadFactory:
[legend]
Collaboration diagram for NeonWorkloadFactory:
[legend]

Public Member Functions

 NeonWorkloadFactory (const std::shared_ptr< NeonMemoryManager > &memoryManager)
 
 NeonWorkloadFactory (const std::shared_ptr< NeonMemoryManager > &memoryManager, const IBackendInternal::IBackendSpecificModelContextPtr &modelContextPtr)
 
const BackendIdGetBackendId () const override
 
bool SupportsSubTensors () const override
 
std::unique_ptr< ITensorHandleCreateSubTensorHandle (ITensorHandle &parent, TensorShape const &subTensorShape, unsigned int const *subTensorOrigin) const override
 
std::unique_ptr< ITensorHandleCreateTensorHandle (const TensorInfo &tensorInfo, const bool IsMemoryManaged=true) const override
 
std::unique_ptr< ITensorHandleCreateTensorHandle (const TensorInfo &tensorInfo, DataLayout dataLayout, const bool IsMemoryManaged=true) const override
 
std::unique_ptr< IWorkloadCreateWorkload (LayerType type, const QueueDescriptor &descriptor, const WorkloadInfo &info) const override
 Backends should implement their own CreateWorkload function with a switch statement. More...
 
- Public Member Functions inherited from IWorkloadFactory
virtual ~IWorkloadFactory ()
 
virtual void AfterWorkloadsCreated ()
 

Static Public Member Functions

static bool IsLayerSupported (const Layer &layer, Optional< DataType > dataType, std::string &outReasonIfUnsupported)
 
static bool IsLayerSupported (const IConnectableLayer &layer, Optional< DataType > dataType, std::string &outReasonIfUnsupported, const ModelOptions &modelOptions)
 
- Static Public Member Functions inherited from IWorkloadFactory
static bool IsLayerSupported (const BackendId &backendId, const IConnectableLayer &layer, Optional< DataType > dataType, std::string &outReasonIfUnsupported)
 
static bool IsLayerSupported (const IConnectableLayer &layer, Optional< DataType > dataType, std::string &outReasonIfUnsupported)
 
static bool IsLayerSupported (const IConnectableLayer &layer, Optional< DataType > dataType, std::string &outReasonIfUnsupported, const ModelOptions &modelOptions)
 
static bool IsLayerSupported (const BackendId &backendId, const IConnectableLayer &layer, Optional< DataType > dataType, std::string &outReasonIfUnsupported, const ModelOptions &modelOptions)
 

Detailed Description

Definition at line 20 of file NeonWorkloadFactory.hpp.

Constructor & Destructor Documentation

◆ NeonWorkloadFactory() [1/2]

NeonWorkloadFactory ( const std::shared_ptr< NeonMemoryManager > &  memoryManager)

Definition at line 75 of file NeonWorkloadFactory.cpp.

76  : m_MemoryManager(memoryManager), m_ModelContextPtr(IBackendInternal::IBackendSpecificModelContextPtr{})
77 {
78  SetNumberOfThreads();
79 }
std::shared_ptr< IBackendModelContext > IBackendSpecificModelContextPtr

◆ NeonWorkloadFactory() [2/2]

NeonWorkloadFactory ( const std::shared_ptr< NeonMemoryManager > &  memoryManager,
const IBackendInternal::IBackendSpecificModelContextPtr modelContextPtr 
)

Definition at line 81 of file NeonWorkloadFactory.cpp.

83  : m_MemoryManager(memoryManager), m_ModelContextPtr(modelContextPtr)
84 {
85  SetNumberOfThreads();
86 }

Member Function Documentation

◆ CreateSubTensorHandle()

std::unique_ptr< ITensorHandle > CreateSubTensorHandle ( ITensorHandle parent,
TensorShape const &  subTensorShape,
unsigned int const *  subTensorOrigin 
) const
overridevirtual

Reimplemented from WorkloadFactoryBase.

Definition at line 88 of file NeonWorkloadFactory.cpp.

91 {
92  const arm_compute::TensorShape shape = armcomputetensorutils::BuildArmComputeTensorShape(subTensorShape);
93 
95  coords.set_num_dimensions(subTensorShape.GetNumDimensions());
96  for (unsigned int i = 0; i < subTensorShape.GetNumDimensions(); i++)
97  {
98  // Arm compute indexes tensor coords in reverse order.
99  unsigned int revertedIndex = subTensorShape.GetNumDimensions() - i - 1;
100  coords.set(i, armnn::numeric_cast<int>(subTensorOrigin[revertedIndex]));
101  }
102 
103  const arm_compute::TensorShape parentShape = armcomputetensorutils::BuildArmComputeTensorShape(parent.GetShape());
104  if (!::arm_compute::error_on_invalid_subtensor(__func__, __FILE__, __LINE__, parentShape, coords, shape))
105  {
106  return nullptr;
107  }
108 
109  return std::make_unique<NeonSubTensorHandle>(
110  PolymorphicDowncast<IAclTensorHandle*>(&parent), shape, coords);
111 }
std::array< unsigned int, MaxNumOfTensorDimensions > Coordinates

◆ CreateTensorHandle() [1/2]

std::unique_ptr< ITensorHandle > CreateTensorHandle ( const TensorInfo tensorInfo,
const bool  IsMemoryManaged = true 
) const
overridevirtual

Reimplemented from WorkloadFactoryBase.

Definition at line 113 of file NeonWorkloadFactory.cpp.

115 {
116  auto tensorHandle = std::make_unique<NeonTensorHandle>(tensorInfo);
117  if (IsMemoryManaged)
118  {
119  tensorHandle->SetMemoryGroup(m_MemoryManager->GetInterLayerMemoryGroup());
120  }
121  return tensorHandle;
122 }

◆ CreateTensorHandle() [2/2]

std::unique_ptr< ITensorHandle > CreateTensorHandle ( const TensorInfo tensorInfo,
DataLayout  dataLayout,
const bool  IsMemoryManaged = true 
) const
overridevirtual

Reimplemented from WorkloadFactoryBase.

Definition at line 124 of file NeonWorkloadFactory.cpp.

127 {
128  auto tensorHandle = std::make_unique<NeonTensorHandle>(tensorInfo, dataLayout);
129  if (IsMemoryManaged)
130  {
131  tensorHandle->SetMemoryGroup(m_MemoryManager->GetInterLayerMemoryGroup());
132  }
133  return tensorHandle;
134 }

◆ CreateWorkload()

std::unique_ptr< IWorkload > CreateWorkload ( LayerType  type,
const QueueDescriptor descriptor,
const WorkloadInfo info 
) const
overridevirtual

Backends should implement their own CreateWorkload function with a switch statement.

The case for the switch should be the LayerType and based on that they will call their specific workload creation functionality.

Reimplemented from WorkloadFactoryBase.

Definition at line 136 of file NeonWorkloadFactory.cpp.

139 {
140  switch(type)
141  {
142  case LayerType::Activation :
143  {
144  auto activationQueueDescriptor = PolymorphicDowncast<const ActivationQueueDescriptor*>(&descriptor);
145  return std::make_unique<NeonActivationWorkload>(*activationQueueDescriptor, info);
146  }
147  case LayerType::Addition :
148  {
149  auto additionQueueDescriptor = PolymorphicDowncast<const AdditionQueueDescriptor*>(&descriptor);
150  return std::make_unique<NeonAdditionWorkload>(*additionQueueDescriptor, info);
151  }
152  case LayerType::ArgMinMax :
153  {
154  auto argMinMaxQueueDescriptor = PolymorphicDowncast<const ArgMinMaxQueueDescriptor*>(&descriptor);
155  return std::make_unique<NeonArgMinMaxWorkload>(*argMinMaxQueueDescriptor, info);
156  }
158  {
159  auto batchMatMulQueueDescriptor = PolymorphicDowncast<const BatchMatMulQueueDescriptor*>(&descriptor);
160  bool isFastMathEnabled = false;
161  if (m_ModelContextPtr)
162  {
163  if (m_ModelContextPtr.get() != nullptr)
164  {
165  auto modelOptions = dynamic_cast<NeonBackendModelContext*>(m_ModelContextPtr.get());
166  if (modelOptions)
167  {
168  isFastMathEnabled = modelOptions->IsFastMathEnabled();
169  }
170  }
171  }
172  return std::make_unique<NeonBatchMatMulWorkload>(*batchMatMulQueueDescriptor, info, isFastMathEnabled);
173  }
175  {
176  auto batchNormalizationQueueDescriptor
177  = PolymorphicDowncast<const BatchNormalizationQueueDescriptor*>(&descriptor);
178  return std::make_unique<NeonBatchNormalizationWorkload>(*batchNormalizationQueueDescriptor, info);
179  }
181  {
182  auto batchToSpaceNdQueueDescriptor
183  = PolymorphicDowncast<const BatchToSpaceNdQueueDescriptor*>(&descriptor);
184  return std::make_unique<NeonBatchToSpaceNdWorkload>(*batchToSpaceNdQueueDescriptor, info);
185  }
186  case LayerType::Cast :
187  {
188  auto castQueueDescriptor = PolymorphicDowncast<const CastQueueDescriptor*>(&descriptor);
189  return std::make_unique<NeonCastWorkload>(*castQueueDescriptor, info);
190  }
192  {
193  auto channelShuffleQueueDescriptor = PolymorphicDowncast<const ChannelShuffleQueueDescriptor*>(&descriptor);
194  return std::make_unique<NeonChannelShuffleWorkload>(*channelShuffleQueueDescriptor, info);
195  }
196  case LayerType::Comparison :
197  {
198  auto comparisonQueueDescriptor = PolymorphicDowncast<const ComparisonQueueDescriptor*>(&descriptor);
199  return std::make_unique<NeonComparisonWorkload>(*comparisonQueueDescriptor, info);
200  }
201  case LayerType::Concat :
202  {
203  auto concatQueueDescriptor = PolymorphicDowncast<const ConcatQueueDescriptor*>(&descriptor);
204  return std::make_unique<NeonConcatWorkload>(*concatQueueDescriptor, info);
205  }
206  case LayerType::Constant :
207  {
208  auto constantQueueDescriptor = PolymorphicDowncast<const ConstantQueueDescriptor*>(&descriptor);
209  return std::make_unique<NeonConstantWorkload>(*constantQueueDescriptor, info);
210  }
212  {
213  auto convertFp16ToFp32QueueDescriptor
214  = PolymorphicDowncast<const ConvertFp16ToFp32QueueDescriptor*>(&descriptor);
215  return std::make_unique<NeonConvertFp16ToFp32Workload>(*convertFp16ToFp32QueueDescriptor, info);
216  }
218  {
219  auto convertFp32ToFp16QueueDescriptor
220  = PolymorphicDowncast<const ConvertFp32ToFp16QueueDescriptor*>(&descriptor);
221  return std::make_unique<NeonConvertFp32ToFp16Workload>(*convertFp32ToFp16QueueDescriptor, info);
222  }
224  {
225  auto convolution2dQueueDescriptor = PolymorphicDowncast<const Convolution2dQueueDescriptor*>(&descriptor);
226  bool isFastMathEnabled = false;
227  if (m_ModelContextPtr)
228  {
229  if (m_ModelContextPtr.get() != nullptr)
230  {
231  auto modelOptions = dynamic_cast<NeonBackendModelContext*>(m_ModelContextPtr.get());
232  if (modelOptions)
233  {
234  isFastMathEnabled = modelOptions->IsFastMathEnabled();
235  }
236  }
237  }
238  return std::make_unique<NeonConvolution2dWorkload>(*convolution2dQueueDescriptor,
239  info,
240  m_MemoryManager->GetIntraLayerManager(),
241  isFastMathEnabled);
242  }
244  {
245  auto convolution3dQueueDescriptor = PolymorphicDowncast<const Convolution3dQueueDescriptor*>(&descriptor);
246  bool isFastMathEnabled = false;
247  if (m_ModelContextPtr)
248  {
249  if (m_ModelContextPtr.get() != nullptr)
250  {
251  auto modelOptions = dynamic_cast<NeonBackendModelContext*>(m_ModelContextPtr.get());
252  if (modelOptions)
253  {
254  isFastMathEnabled = modelOptions->IsFastMathEnabled();
255  }
256  }
257  }
258  return std::make_unique<NeonConvolution3dWorkload>(*convolution3dQueueDescriptor,
259  info,
260  m_MemoryManager->GetIntraLayerManager(),
261  isFastMathEnabled);
262  }
263  case LayerType::Debug :
264  {
265  auto debugQueueDescriptor = PolymorphicDowncast<const DebugQueueDescriptor*>(&descriptor);
266  return MakeWorkloadHelper<NullWorkload, NullWorkload>(*debugQueueDescriptor, info);
267  }
269  {
270  auto depthToSpaceQueueDescriptor = PolymorphicDowncast<const DepthToSpaceQueueDescriptor*>(&descriptor);
271  return std::make_unique<NeonDepthToSpaceWorkload>(*depthToSpaceQueueDescriptor, info);
272  }
274  {
275  auto depthwiseConvolution2dQueueDescriptor
276  = PolymorphicDowncast<const DepthwiseConvolution2dQueueDescriptor*>(&descriptor);
277  return std::make_unique<NeonDepthwiseConvolutionWorkload>(*depthwiseConvolution2dQueueDescriptor, info);
278  }
279  case LayerType::Dequantize :
280  {
281  auto dequantizeQueueDescriptor = PolymorphicDowncast<const DequantizeQueueDescriptor*>(&descriptor);
282  return std::make_unique<NeonDequantizeWorkload>(*dequantizeQueueDescriptor, info);
283  }
285  {
286  auto detectionPostProcessQueueDescriptor
287  = PolymorphicDowncast<const DetectionPostProcessQueueDescriptor*>(&descriptor);
288  return MakeWorkloadHelper<NullWorkload, NullWorkload>(*detectionPostProcessQueueDescriptor, info);
289  }
290  case LayerType::Division :
291  {
292  auto divisionQueueDescriptor = PolymorphicDowncast<const DivisionQueueDescriptor*>(&descriptor);
293  return std::make_unique<NeonDivisionWorkload>(*divisionQueueDescriptor, info);
294  }
296  {
297  auto elementwiseBinaryQueueDescriptor
298  = PolymorphicDowncast<const ElementwiseBinaryQueueDescriptor*>(&descriptor);
299  switch (elementwiseBinaryQueueDescriptor->m_Parameters.m_Operation)
300  {
302  {
303  AdditionQueueDescriptor additionQueueDescriptor;
304  additionQueueDescriptor.m_Inputs = descriptor.m_Inputs;
305  additionQueueDescriptor.m_Outputs = descriptor.m_Outputs;
306  return std::make_unique<NeonAdditionWorkload>(additionQueueDescriptor, info);
307  }
309  {
310  DivisionQueueDescriptor divisionQueueDescriptor;
311  divisionQueueDescriptor.m_Inputs = descriptor.m_Inputs;
312  divisionQueueDescriptor.m_Outputs = descriptor.m_Outputs;
313  return std::make_unique<NeonDivisionWorkload>(divisionQueueDescriptor, info);
314  }
316  {
317  DivisionQueueDescriptor floorDivQueueDescriptor;
318  floorDivQueueDescriptor.m_Inputs = descriptor.m_Inputs;
319  floorDivQueueDescriptor.m_Outputs = descriptor.m_Outputs;
320  return std::make_unique<NeonFloorDivWorkload>(floorDivQueueDescriptor, info);
321  }
323  {
324  MaximumQueueDescriptor maximumQueueDescriptor;
325  maximumQueueDescriptor.m_Inputs = descriptor.m_Inputs;
326  maximumQueueDescriptor.m_Outputs = descriptor.m_Outputs;
327  return std::make_unique<NeonMaximumWorkload>(maximumQueueDescriptor, info);
328  }
330  {
331  MinimumQueueDescriptor minimumQueueDescriptor;
332  minimumQueueDescriptor.m_Inputs = descriptor.m_Inputs;
333  minimumQueueDescriptor.m_Outputs = descriptor.m_Outputs;
334  return std::make_unique<NeonMinimumWorkload>(minimumQueueDescriptor, info);
335  }
337  {
338  MultiplicationQueueDescriptor multiplicationQueueDescriptor;
339  multiplicationQueueDescriptor.m_Inputs = descriptor.m_Inputs;
340  multiplicationQueueDescriptor.m_Outputs = descriptor.m_Outputs;
341  return std::make_unique<NeonMultiplicationWorkload>(multiplicationQueueDescriptor, info);
342  }
345  {
346  return std::make_unique<NeonElementwiseBinaryWorkload>(*elementwiseBinaryQueueDescriptor, info);
347  }
349  {
350  SubtractionQueueDescriptor subtractionQueueDescriptor;
351  subtractionQueueDescriptor.m_Inputs = descriptor.m_Inputs;
352  subtractionQueueDescriptor.m_Outputs = descriptor.m_Outputs;
353  return std::make_unique<NeonSubtractionWorkload>(subtractionQueueDescriptor, info);
354  }
355  default:
356  return nullptr;
357  }
358  }
360  {
361  auto elementwiseUnaryQueueDescriptor
362  = PolymorphicDowncast<const ElementwiseUnaryQueueDescriptor*>(&descriptor);
363  switch(elementwiseUnaryQueueDescriptor->m_Parameters.m_Operation)
364  {
365  case UnaryOperation::Abs:
366  {
367  AbsQueueDescriptor absQueueDescriptor;
368  absQueueDescriptor.m_Inputs = elementwiseUnaryQueueDescriptor->m_Inputs;
369  absQueueDescriptor.m_Outputs = elementwiseUnaryQueueDescriptor->m_Outputs;
370  return std::make_unique<NeonAbsWorkload>(absQueueDescriptor, info);
371  }
372  case UnaryOperation::Exp:
373  return std::make_unique<NeonExpWorkload>(*elementwiseUnaryQueueDescriptor, info);
375  return std::make_unique<NeonLogicalNotWorkload>(*elementwiseUnaryQueueDescriptor, info);
376  case UnaryOperation::Log:
377  return std::make_unique<NeonLogWorkload>(*elementwiseUnaryQueueDescriptor, info);
378  case UnaryOperation::Neg:
379  return std::make_unique<NeonNegWorkload>(*elementwiseUnaryQueueDescriptor, info);
381  {
382  RsqrtQueueDescriptor rsqrtQueueDescriptor;
383  rsqrtQueueDescriptor.m_Inputs = elementwiseUnaryQueueDescriptor->m_Inputs;
384  rsqrtQueueDescriptor.m_Outputs = elementwiseUnaryQueueDescriptor->m_Outputs;
385  return std::make_unique<NeonRsqrtWorkload>(rsqrtQueueDescriptor, info);
386  }
387  case UnaryOperation::Sin:
388  return std::make_unique<NeonSinWorkload>(*elementwiseUnaryQueueDescriptor, info);
390  return std::make_unique<NeonSqrtWorkload>(*elementwiseUnaryQueueDescriptor, info);
391  default:
392  return nullptr;
393  }
394  }
395  case LayerType::Fill :
396  {
397  auto fillQueueDescriptor = PolymorphicDowncast<const FillQueueDescriptor*>(&descriptor);
398  return std::make_unique<NeonFillWorkload>(*fillQueueDescriptor, info);
399  }
400  case LayerType::Floor :
401  {
402  auto floorQueueDescriptor = PolymorphicDowncast<const FloorQueueDescriptor*>(&descriptor);
403  return MakeWorkloadHelper<NeonFloorFloatWorkload, NullWorkload>(*floorQueueDescriptor, info);
404  }
406  {
407  auto fullyConnectedQueueDescriptor = PolymorphicDowncast<const FullyConnectedQueueDescriptor*>(&descriptor);
408  return std::make_unique<NeonFullyConnectedWorkload>(*fullyConnectedQueueDescriptor,
409  info,
410  m_MemoryManager->GetIntraLayerManager());
411  }
412  case LayerType::Fused :
413  {
414  auto fusedQueueDescriptor = PolymorphicDowncast<const FusedQueueDescriptor*>(&descriptor);
415  return std::make_unique<NeonFusedWorkload>(*fusedQueueDescriptor, info);
416  }
417  case LayerType::Gather :
418  {
419  auto gatherQueueDescriptor = PolymorphicDowncast<const GatherQueueDescriptor*>(&descriptor);
420  return std::make_unique<NeonGatherWorkload>(*gatherQueueDescriptor, info);
421  }
422  case LayerType::GatherNd :
423  {
424  auto gatherNdQueueDescriptor = PolymorphicDowncast<const GatherNdQueueDescriptor*>(&descriptor);
425  return std::make_unique<NeonGatherNdWorkload>(*gatherNdQueueDescriptor, info);
426  }
427  case LayerType::Input :
428  {
429  auto inputQueueDescriptor = PolymorphicDowncast<const InputQueueDescriptor*>(&descriptor);
430  return std::make_unique<CopyMemGenericWorkload>(*inputQueueDescriptor, info);
431  }
433  {
434  auto instanceNormalizationQueueDescriptor
435  = PolymorphicDowncast<const InstanceNormalizationQueueDescriptor*>(&descriptor);
436  return std::make_unique<NeonInstanceNormalizationWorkload>(*instanceNormalizationQueueDescriptor, info);
437  }
439  {
440  auto l2NormalizationQueueDescriptor
441  = PolymorphicDowncast<const L2NormalizationQueueDescriptor*>(&descriptor);
442  return MakeWorkloadHelper<NeonL2NormalizationFloatWorkload, NullWorkload>
443  (*l2NormalizationQueueDescriptor, info, m_MemoryManager->GetIntraLayerManager());
444  }
445  case LayerType::LogSoftmax :
446  {
447  auto logSoftmaxQueueDescriptor = PolymorphicDowncast<const LogSoftmaxQueueDescriptor*>(&descriptor);
448  return std::make_unique<NeonLogSoftmaxWorkload>(*logSoftmaxQueueDescriptor,
449  info,
450  m_MemoryManager->GetIntraLayerManager());
451  }
453  {
454  auto logicalBinaryQueueDescriptor = PolymorphicDowncast<const LogicalBinaryQueueDescriptor*>(&descriptor);
455  switch(logicalBinaryQueueDescriptor->m_Parameters.m_Operation)
456  {
458  return std::make_unique<NeonLogicalAndWorkload>(*logicalBinaryQueueDescriptor, info);
460  return std::make_unique<NeonLogicalOrWorkload>(*logicalBinaryQueueDescriptor, info);
461  default:
462  return nullptr;
463  }
464  }
465  case LayerType::Lstm :
466  {
467  auto lstmQueueDescriptor = PolymorphicDowncast<const LstmQueueDescriptor*>(&descriptor);
468  return MakeWorkloadHelper<NeonLstmFloatWorkload, NullWorkload>(*lstmQueueDescriptor, info);
469  }
470  case LayerType::Maximum :
471  {
472  auto maximumQueueDescriptor = PolymorphicDowncast<const MaximumQueueDescriptor*>(&descriptor);
473  return std::make_unique<NeonMaximumWorkload>(*maximumQueueDescriptor, info);
474  }
475  case LayerType::Mean :
476  {
477  auto meanQueueDescriptor = PolymorphicDowncast<const MeanQueueDescriptor*>(&descriptor);
478  return std::make_unique<NeonMeanWorkload>(*meanQueueDescriptor, info);
479  }
480  case LayerType::MemCopy :
481  {
482  auto memCopyQueueDescriptor = PolymorphicDowncast<const MemCopyQueueDescriptor*>(&descriptor);
483  if (memCopyQueueDescriptor->m_Inputs.empty() || !memCopyQueueDescriptor->m_Inputs[0])
484  {
485  throw InvalidArgumentException("NeonWorkloadFactory: Invalid null input for MemCopy workload");
486  }
487  return MakeWorkloadHelper<CopyMemGenericWorkload, CopyMemGenericWorkload>(*memCopyQueueDescriptor, info);
488  }
489  case LayerType::MemImport :
490  {
491  auto memImportQueueDescriptor = PolymorphicDowncast<const MemImportQueueDescriptor*>(&descriptor);
492  if (memImportQueueDescriptor->m_Inputs.empty() || !memImportQueueDescriptor->m_Inputs[0])
493  {
494  throw InvalidArgumentException("NeonWorkloadFactory: Invalid null input for MemImport workload");
495  }
496  return std::make_unique<ImportMemGenericWorkload>(*memImportQueueDescriptor, info);
497  }
498  case LayerType::Minimum :
499  {
500  auto minimumQueueDescriptor = PolymorphicDowncast<const MinimumQueueDescriptor*>(&descriptor);
501  return std::make_unique<NeonMinimumWorkload>(*minimumQueueDescriptor, info);
502  }
504  {
505  auto multiplicationQueueDescriptor = PolymorphicDowncast<const MultiplicationQueueDescriptor*>(&descriptor);
506  return std::make_unique<NeonMultiplicationWorkload>(*multiplicationQueueDescriptor, info);
507  }
509  {
510  auto normalizationQueueDescriptor = PolymorphicDowncast<const NormalizationQueueDescriptor*>(&descriptor);
511  return MakeWorkloadHelper<NeonNormalizationFloatWorkload, NullWorkload>
512  (*normalizationQueueDescriptor, info, m_MemoryManager->GetIntraLayerManager());
513  }
514  case LayerType::Output :
515  {
516  auto outputQueueDescriptor = PolymorphicDowncast<const OutputQueueDescriptor*>(&descriptor);
517  return std::make_unique<CopyMemGenericWorkload>(*outputQueueDescriptor, info);
518  }
519  case LayerType::Pad :
520  {
521  auto padQueueDescriptor = PolymorphicDowncast<const PadQueueDescriptor*>(&descriptor);
522  return std::make_unique<NeonPadWorkload>(*padQueueDescriptor, info);
523  }
524  case LayerType::Permute :
525  {
526  auto permuteQueueDescriptor = PolymorphicDowncast<const PermuteQueueDescriptor*>(&descriptor);
527  return std::make_unique<NeonPermuteWorkload>(*permuteQueueDescriptor, info);
528  }
529  case LayerType::Pooling2d :
530  {
531  auto pooling2dQueueDescriptor = PolymorphicDowncast<const Pooling2dQueueDescriptor*>(&descriptor);
532  return std::make_unique<NeonPooling2dWorkload>(*pooling2dQueueDescriptor, info);
533  }
534  case LayerType::Pooling3d :
535  {
536  auto pooling3dQueueDescriptor = PolymorphicDowncast<const Pooling3dQueueDescriptor*>(&descriptor);
537  return std::make_unique<NeonPooling3dWorkload>(*pooling3dQueueDescriptor, info);
538  }
540  {
541  auto preCompiledQueueDescriptor = PolymorphicDowncast<const PreCompiledQueueDescriptor*>(&descriptor);
542  return MakeWorkloadHelper<NullWorkload, NullWorkload>(*preCompiledQueueDescriptor, info);
543  }
544  case LayerType::Prelu :
545  {
546  auto preluQueueDescriptor = PolymorphicDowncast<const PreluQueueDescriptor*>(&descriptor);
547  return std::make_unique<NeonPreluWorkload>(*preluQueueDescriptor, info);
548  }
549  case LayerType::QLstm :
550  {
551  auto qLstmQueueDescriptor = PolymorphicDowncast<const QLstmQueueDescriptor*>(&descriptor);
552  return std::make_unique<NeonQLstmWorkload>(*qLstmQueueDescriptor, info);
553  }
554  case LayerType::Quantize :
555  {
556  auto quantizeQueueDescriptor = PolymorphicDowncast<const QuantizeQueueDescriptor*>(&descriptor);
557  return std::make_unique<NeonQuantizeWorkload>(*quantizeQueueDescriptor, info);
558  }
560  {
561  auto quantizedLstmQueueDescriptor = PolymorphicDowncast<const QuantizedLstmQueueDescriptor*>(&descriptor);
562  return std::make_unique<NeonQuantizedLstmWorkload>(*quantizedLstmQueueDescriptor, info);
563  }
564  case LayerType::Rank :
565  {
566  auto rankQueueDescriptor = PolymorphicDowncast<const RankQueueDescriptor*>(&descriptor);
567  return std::make_unique<NeonRankWorkload>(*rankQueueDescriptor, info);
568  }
569  case LayerType::Reduce :
570  {
571  auto reduceQueueDescriptor = PolymorphicDowncast<const ReduceQueueDescriptor*>(&descriptor);
572  return std::make_unique<NeonReduceWorkload>(*reduceQueueDescriptor, info);
573  }
574  case LayerType::Reshape :
575  {
576  auto reshapeQueueDescriptor = PolymorphicDowncast<const ReshapeQueueDescriptor*>(&descriptor);
577  return std::make_unique<NeonReshapeWorkload>(*reshapeQueueDescriptor, info);
578  }
579  case LayerType::Resize :
580  {
581  auto resizeQueueDescriptor = PolymorphicDowncast<const ResizeQueueDescriptor*>(&descriptor);
582  return std::make_unique<NeonResizeWorkload>(*resizeQueueDescriptor, info);
583  }
584  case LayerType::ReverseV2 :
585  {
586  auto reverseV2QueueDescriptor = PolymorphicDowncast<const ReverseV2QueueDescriptor*>(&descriptor);
587  return std::make_unique<NeonReverseV2Workload>(*reverseV2QueueDescriptor, info);
588  }
589  case LayerType::Slice :
590  {
591  auto sliceQueueDescriptor = PolymorphicDowncast<const SliceQueueDescriptor*>(&descriptor);
592  return std::make_unique<NeonSliceWorkload>(*sliceQueueDescriptor, info);
593  }
594  case LayerType::Softmax :
595  {
596  auto softmaxQueueDescriptor = PolymorphicDowncast<const SoftmaxQueueDescriptor*>(&descriptor);
597  return std::make_unique<NeonSoftmaxWorkload>(*softmaxQueueDescriptor,
598  info,
599  m_MemoryManager->GetIntraLayerManager());
600  }
602  {
603  auto spaceToBatchNdQueueDescriptor
604  = PolymorphicDowncast<const SpaceToBatchNdQueueDescriptor*>(&descriptor);
605  return std::make_unique<NeonSpaceToBatchNdWorkload>(*spaceToBatchNdQueueDescriptor, info);
606  }
608  {
609  auto spaceToDepthQueueDescriptor = PolymorphicDowncast<const SpaceToDepthQueueDescriptor*>(&descriptor);
610  return std::make_unique<NeonSpaceToDepthWorkload>(*spaceToDepthQueueDescriptor, info);
611  }
612  case LayerType::Splitter :
613  {
614  auto splitterQueueDescriptor = PolymorphicDowncast<const SplitterQueueDescriptor*>(&descriptor);
615  return std::make_unique<NeonSplitterWorkload>(*splitterQueueDescriptor, info);
616  }
617  case LayerType::Stack :
618  {
619  auto stackQueueDescriptor = PolymorphicDowncast<const StackQueueDescriptor*>(&descriptor);
620  return std::make_unique<NeonStackWorkload>(*stackQueueDescriptor, info);
621  }
623  {
624  auto stridedSliceQueueDescriptor = PolymorphicDowncast<const StridedSliceQueueDescriptor*>(&descriptor);
625  return std::make_unique<NeonStridedSliceWorkload>(*stridedSliceQueueDescriptor, info);
626  }
628  {
629  auto subtractionQueueDescriptor = PolymorphicDowncast<const SubtractionQueueDescriptor*>(&descriptor);
630  return std::make_unique<NeonSubtractionWorkload>(*subtractionQueueDescriptor, info);
631  }
632  case LayerType::Tile:
633  {
634  auto tileQueueDescriptor = PolymorphicDowncast<const TileQueueDescriptor*>(&descriptor);
635  return std::make_unique<NeonTileWorkload>(*tileQueueDescriptor, info);
636  }
637  case LayerType::Transpose :
638  {
639  auto transposeQueueDescriptor = PolymorphicDowncast<const TransposeQueueDescriptor*>(&descriptor);
640  return std::make_unique<NeonTransposeWorkload>(*transposeQueueDescriptor, info);
641  }
643  {
644  auto transposeConvolution2dQueueDescriptor
645  = PolymorphicDowncast<const TransposeConvolution2dQueueDescriptor*>(&descriptor);
646  return std::make_unique<NeonTransposeConvolution2dWorkload>(*transposeConvolution2dQueueDescriptor,
647  info,
648  m_MemoryManager->GetIntraLayerManager());
649  }
651  {
652  auto desc = PolymorphicDowncast<const UnidirectionalSequenceLstmQueueDescriptor*>(&descriptor);
653  if ((info.m_InputTensorInfos[0].GetDataType() == armnn::DataType::Float32) &&
654  (info.m_InputTensorInfos[1].GetDataType() == armnn::DataType::Float32) &&
655  (info.m_InputTensorInfos[2].GetDataType() == armnn::DataType::Float32) &&
656  (info.m_OutputTensorInfos[0].GetDataType() == armnn::DataType::Float32) &&
657  (info.m_OutputTensorInfos[1].GetDataType() == armnn::DataType::Float32) &&
658  (info.m_OutputTensorInfos[2].GetDataType() == armnn::DataType::Float32))
659  {
660  return std::make_unique<NeonUnidirectionalSequenceLstmFloatWorkload>(*desc, info);
661  }
662  else
663  {
664  return std::make_unique<NeonUnidirectionalSequenceLstmWorkload>(*desc, info);
665  }
666  }
667  default:
668  return nullptr;
669  }
670 }

References armnn::Abs, armnn::Activation, armnn::Add, armnn::Addition, armnn::ArgMinMax, armnn::BatchMatMul, armnn::BatchNormalization, armnn::BatchToSpaceNd, armnn::Cast, armnn::ChannelShuffle, armnn::Comparison, armnn::Concat, armnn::Constant, armnn::ConvertFp16ToFp32, armnn::ConvertFp32ToFp16, armnn::Convolution2d, armnn::Convolution3d, armnn::Debug, armnn::DepthToSpace, armnn::DepthwiseConvolution2d, armnn::Dequantize, armnn::DetectionPostProcess, armnn::Div, armnn::Division, armnn::ElementwiseBinary, armnn::ElementwiseUnary, armnn::Exp, armnn::Fill, armnn::Float32, armnn::Floor, armnn::FloorDiv, armnn::FullyConnected, armnn::Fused, armnn::Gather, armnn::GatherNd, armnn::info, armnn::Input, armnn::InstanceNormalization, NeonBackendModelContext::IsFastMathEnabled(), armnn::L2Normalization, armnn::Log, armnn::LogicalAnd, armnn::LogicalBinary, armnn::LogicalNot, armnn::LogicalOr, armnn::LogSoftmax, armnn::Lstm, QueueDescriptor::m_Inputs, QueueDescriptor::m_Outputs, armnn::Maximum, armnn::Mean, armnn::MemCopy, armnn::MemImport, armnn::Minimum, armnn::Mul, armnn::Multiplication, armnn::Neg, armnn::Normalization, armnn::Output, armnn::Pad, armnn::Permute, armnn::Pooling2d, armnn::Pooling3d, armnn::Power, armnn::PreCompiled, armnn::Prelu, armnn::QLstm, armnn::Quantize, armnn::QuantizedLstm, armnn::Rank, armnn::Reduce, armnn::Reshape, armnn::Resize, armnn::ReverseV2, armnn::Rsqrt, armnn::Sin, armnn::Slice, armnn::Softmax, armnn::SpaceToBatchNd, armnn::SpaceToDepth, armnn::Splitter, armnn::SqDiff, armnn::Sqrt, armnn::Stack, armnn::StridedSlice, armnn::Sub, armnn::Subtraction, armnn::Tile, armnn::Transpose, armnn::TransposeConvolution2d, and armnn::UnidirectionalSequenceLstm.

◆ GetBackendId()

const BackendId & GetBackendId ( ) const
overridevirtual

Implements IWorkloadFactory.

Definition at line 49 of file NeonWorkloadFactory.cpp.

50 {
51  return s_Id;
52 }

◆ IsLayerSupported() [1/2]

bool IsLayerSupported ( const IConnectableLayer layer,
Optional< DataType dataType,
std::string &  outReasonIfUnsupported,
const ModelOptions modelOptions 
)
static

Definition at line 41 of file NeonWorkloadFactory.cpp.

45 {
46  return IWorkloadFactory::IsLayerSupported(s_Id, layer, dataType, outReasonIfUnsupported, modelOptions);
47 }
static bool IsLayerSupported(const BackendId &backendId, const IConnectableLayer &layer, Optional< DataType > dataType, std::string &outReasonIfUnsupported)

References IWorkloadFactory::IsLayerSupported().

◆ IsLayerSupported() [2/2]

bool IsLayerSupported ( const Layer layer,
Optional< DataType dataType,
std::string &  outReasonIfUnsupported 
)
static

Definition at line 34 of file NeonWorkloadFactory.cpp.

37 {
38  return IWorkloadFactory::IsLayerSupported(s_Id, layer, dataType, outReasonIfUnsupported);
39 }

References IWorkloadFactory::IsLayerSupported().

◆ SupportsSubTensors()

bool SupportsSubTensors ( ) const
inlineoverridevirtual

Reimplemented from WorkloadFactoryBase.

Definition at line 39 of file NeonWorkloadFactory.hpp.

39 { return true; }

The documentation for this class was generated from the following files: