ArmNN
 25.11
Loading...
Searching...
No Matches
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.
Public Member Functions inherited from WorkloadFactoryBase
bool SupportsSubTensors () const override
std::unique_ptr< ITensorHandleCreateSubTensorHandle (ITensorHandle &, TensorShape const &, unsigned int const *) const override
std::unique_ptr< ITensorHandleCreateTensorHandle (const TensorInfo &, const bool) const override
std::unique_ptr< ITensorHandleCreateTensorHandle (const TensorInfo &, DataLayout, const bool) const override
std::unique_ptr< IWorkloadCreateWorkload (LayerType, const QueueDescriptor &, const WorkloadInfo &) const override
 Backends should implement their own CreateWorkload function with a switch statement.
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 73 of file NeonWorkloadFactory.cpp.

74 : m_MemoryManager(memoryManager), m_ModelContextPtr(IBackendInternal::IBackendSpecificModelContextPtr{})
75{
76 SetNumberOfThreads();
77}

◆ NeonWorkloadFactory() [2/2]

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

Definition at line 79 of file NeonWorkloadFactory.cpp.

81 : m_MemoryManager(memoryManager), m_ModelContextPtr(modelContextPtr)
82{
83 SetNumberOfThreads();
84}

Member Function Documentation

◆ CreateSubTensorHandle()

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

Implements IWorkloadFactory.

Definition at line 86 of file NeonWorkloadFactory.cpp.

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

References TensorShape::GetNumDimensions(), ITensorHandle::GetShape(), armnn::numeric_cast(), and armnn::PolymorphicDowncast().

◆ CreateTensorHandle() [1/2]

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

Implements IWorkloadFactory.

Definition at line 111 of file NeonWorkloadFactory.cpp.

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

◆ CreateTensorHandle() [2/2]

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

Implements IWorkloadFactory.

Definition at line 122 of file NeonWorkloadFactory.cpp.

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

◆ 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.

Implements IWorkloadFactory.

Definition at line 134 of file NeonWorkloadFactory.cpp.

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

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, 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::PolymorphicDowncast(), 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}

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

Implements IWorkloadFactory.

Definition at line 39 of file NeonWorkloadFactory.hpp.

39{ return true; }

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