36 std::string& outReasonIfUnsupported)
43 std::string& outReasonIfUnsupported,
54 void NeonWorkloadFactory::SetNumberOfThreads()
56 if (m_ModelContextPtr)
58 const unsigned int MIN_THREADS = 1;
59 const unsigned int MAX_THREADS = 64;
66 modelOptions->ApplyAclIsaPolicy();
68 if (numberOfThreads != 0 && numberOfThreads >= MIN_THREADS && numberOfThreads <= MAX_THREADS)
70 arm_compute::Scheduler::get().set_num_threads(numberOfThreads);
76 : m_MemoryManager(memoryManager), m_ModelContextPtr(
IBackendInternal::IBackendSpecificModelContextPtr{})
83 : m_MemoryManager(memoryManager), m_ModelContextPtr(modelContextPtr)
90 unsigned int const* subTensorOrigin)
const
92 const arm_compute::TensorShape shape = armcomputetensorutils::BuildArmComputeTensorShape(subTensorShape);
100 coords.set(i, armnn::numeric_cast<int>(subTensorOrigin[revertedIndex]));
103 const arm_compute::TensorShape parentShape = armcomputetensorutils::BuildArmComputeTensorShape(parent.
GetShape());
104 if (!::arm_compute::error_on_invalid_subtensor(__func__, __FILE__, __LINE__, parentShape, coords, shape))
109 return std::make_unique<NeonSubTensorHandle>(
110 PolymorphicDowncast<IAclTensorHandle*>(&parent), shape, coords);
114 const bool IsMemoryManaged)
const
116 auto tensorHandle = std::make_unique<NeonTensorHandle>(tensorInfo);
119 tensorHandle->SetMemoryGroup(m_MemoryManager->GetInterLayerMemoryGroup());
126 const bool IsMemoryManaged)
const
128 auto tensorHandle = std::make_unique<NeonTensorHandle>(tensorInfo, dataLayout);
131 tensorHandle->SetMemoryGroup(m_MemoryManager->GetInterLayerMemoryGroup());
144 auto activationQueueDescriptor = PolymorphicDowncast<const ActivationQueueDescriptor*>(&descriptor);
145 return std::make_unique<NeonActivationWorkload>(*activationQueueDescriptor,
info);
149 auto additionQueueDescriptor = PolymorphicDowncast<const AdditionQueueDescriptor*>(&descriptor);
150 return std::make_unique<NeonAdditionWorkload>(*additionQueueDescriptor,
info);
154 auto argMinMaxQueueDescriptor = PolymorphicDowncast<const ArgMinMaxQueueDescriptor*>(&descriptor);
155 return std::make_unique<NeonArgMinMaxWorkload>(*argMinMaxQueueDescriptor,
info);
159 auto batchMatMulQueueDescriptor = PolymorphicDowncast<const BatchMatMulQueueDescriptor*>(&descriptor);
160 bool isFastMathEnabled =
false;
161 if (m_ModelContextPtr)
163 if (m_ModelContextPtr.get() !=
nullptr)
172 return std::make_unique<NeonBatchMatMulWorkload>(*batchMatMulQueueDescriptor,
info, isFastMathEnabled);
176 auto batchNormalizationQueueDescriptor
177 = PolymorphicDowncast<const BatchNormalizationQueueDescriptor*>(&descriptor);
178 return std::make_unique<NeonBatchNormalizationWorkload>(*batchNormalizationQueueDescriptor,
info);
182 auto batchToSpaceNdQueueDescriptor
183 = PolymorphicDowncast<const BatchToSpaceNdQueueDescriptor*>(&descriptor);
184 return std::make_unique<NeonBatchToSpaceNdWorkload>(*batchToSpaceNdQueueDescriptor,
info);
188 auto castQueueDescriptor = PolymorphicDowncast<const CastQueueDescriptor*>(&descriptor);
189 return std::make_unique<NeonCastWorkload>(*castQueueDescriptor,
info);
193 auto channelShuffleQueueDescriptor = PolymorphicDowncast<const ChannelShuffleQueueDescriptor*>(&descriptor);
194 return std::make_unique<NeonChannelShuffleWorkload>(*channelShuffleQueueDescriptor,
info);
198 auto comparisonQueueDescriptor = PolymorphicDowncast<const ComparisonQueueDescriptor*>(&descriptor);
199 return std::make_unique<NeonComparisonWorkload>(*comparisonQueueDescriptor,
info);
203 auto concatQueueDescriptor = PolymorphicDowncast<const ConcatQueueDescriptor*>(&descriptor);
204 return std::make_unique<NeonConcatWorkload>(*concatQueueDescriptor,
info);
208 auto constantQueueDescriptor = PolymorphicDowncast<const ConstantQueueDescriptor*>(&descriptor);
209 return std::make_unique<NeonConstantWorkload>(*constantQueueDescriptor,
info);
213 auto convertFp16ToFp32QueueDescriptor
214 = PolymorphicDowncast<const ConvertFp16ToFp32QueueDescriptor*>(&descriptor);
215 return std::make_unique<NeonConvertFp16ToFp32Workload>(*convertFp16ToFp32QueueDescriptor,
info);
219 auto convertFp32ToFp16QueueDescriptor
220 = PolymorphicDowncast<const ConvertFp32ToFp16QueueDescriptor*>(&descriptor);
221 return std::make_unique<NeonConvertFp32ToFp16Workload>(*convertFp32ToFp16QueueDescriptor,
info);
225 auto convolution2dQueueDescriptor = PolymorphicDowncast<const Convolution2dQueueDescriptor*>(&descriptor);
226 bool isFastMathEnabled =
false;
227 if (m_ModelContextPtr)
229 if (m_ModelContextPtr.get() !=
nullptr)
238 return std::make_unique<NeonConvolution2dWorkload>(*convolution2dQueueDescriptor,
240 m_MemoryManager->GetIntraLayerManager(),
245 auto convolution3dQueueDescriptor = PolymorphicDowncast<const Convolution3dQueueDescriptor*>(&descriptor);
246 bool isFastMathEnabled =
false;
247 if (m_ModelContextPtr)
249 if (m_ModelContextPtr.get() !=
nullptr)
258 return std::make_unique<NeonConvolution3dWorkload>(*convolution3dQueueDescriptor,
260 m_MemoryManager->GetIntraLayerManager(),
265 auto debugQueueDescriptor = PolymorphicDowncast<const DebugQueueDescriptor*>(&descriptor);
266 return MakeWorkloadHelper<NullWorkload, NullWorkload>(*debugQueueDescriptor,
info);
270 auto depthToSpaceQueueDescriptor = PolymorphicDowncast<const DepthToSpaceQueueDescriptor*>(&descriptor);
271 return std::make_unique<NeonDepthToSpaceWorkload>(*depthToSpaceQueueDescriptor,
info);
275 auto depthwiseConvolution2dQueueDescriptor
276 = PolymorphicDowncast<const DepthwiseConvolution2dQueueDescriptor*>(&descriptor);
277 return std::make_unique<NeonDepthwiseConvolutionWorkload>(*depthwiseConvolution2dQueueDescriptor,
info);
281 auto dequantizeQueueDescriptor = PolymorphicDowncast<const DequantizeQueueDescriptor*>(&descriptor);
282 return std::make_unique<NeonDequantizeWorkload>(*dequantizeQueueDescriptor,
info);
286 auto detectionPostProcessQueueDescriptor
287 = PolymorphicDowncast<const DetectionPostProcessQueueDescriptor*>(&descriptor);
288 return MakeWorkloadHelper<NullWorkload, NullWorkload>(*detectionPostProcessQueueDescriptor,
info);
292 auto divisionQueueDescriptor = PolymorphicDowncast<const DivisionQueueDescriptor*>(&descriptor);
293 return std::make_unique<NeonDivisionWorkload>(*divisionQueueDescriptor,
info);
297 auto elementwiseBinaryQueueDescriptor
298 = PolymorphicDowncast<const ElementwiseBinaryQueueDescriptor*>(&descriptor);
299 switch (elementwiseBinaryQueueDescriptor->m_Parameters.m_Operation)
306 return std::make_unique<NeonAdditionWorkload>(additionQueueDescriptor,
info);
313 return std::make_unique<NeonDivisionWorkload>(divisionQueueDescriptor,
info);
320 return std::make_unique<NeonFloorDivWorkload>(floorDivQueueDescriptor,
info);
327 return std::make_unique<NeonMaximumWorkload>(maximumQueueDescriptor,
info);
334 return std::make_unique<NeonMinimumWorkload>(minimumQueueDescriptor,
info);
341 return std::make_unique<NeonMultiplicationWorkload>(multiplicationQueueDescriptor,
info);
346 return std::make_unique<NeonElementwiseBinaryWorkload>(*elementwiseBinaryQueueDescriptor,
info);
353 return std::make_unique<NeonSubtractionWorkload>(subtractionQueueDescriptor,
info);
361 auto elementwiseUnaryQueueDescriptor
362 = PolymorphicDowncast<const ElementwiseUnaryQueueDescriptor*>(&descriptor);
363 switch(elementwiseUnaryQueueDescriptor->m_Parameters.m_Operation)
368 absQueueDescriptor.
m_Inputs = elementwiseUnaryQueueDescriptor->m_Inputs;
369 absQueueDescriptor.
m_Outputs = elementwiseUnaryQueueDescriptor->m_Outputs;
370 return std::make_unique<NeonAbsWorkload>(absQueueDescriptor,
info);
373 return std::make_unique<NeonExpWorkload>(*elementwiseUnaryQueueDescriptor,
info);
375 return std::make_unique<NeonLogicalNotWorkload>(*elementwiseUnaryQueueDescriptor,
info);
377 return std::make_unique<NeonLogWorkload>(*elementwiseUnaryQueueDescriptor,
info);
379 return std::make_unique<NeonNegWorkload>(*elementwiseUnaryQueueDescriptor,
info);
383 rsqrtQueueDescriptor.
m_Inputs = elementwiseUnaryQueueDescriptor->m_Inputs;
384 rsqrtQueueDescriptor.
m_Outputs = elementwiseUnaryQueueDescriptor->m_Outputs;
385 return std::make_unique<NeonRsqrtWorkload>(rsqrtQueueDescriptor,
info);
388 return std::make_unique<NeonSinWorkload>(*elementwiseUnaryQueueDescriptor,
info);
390 return std::make_unique<NeonSqrtWorkload>(*elementwiseUnaryQueueDescriptor,
info);
397 auto fillQueueDescriptor = PolymorphicDowncast<const FillQueueDescriptor*>(&descriptor);
398 return std::make_unique<NeonFillWorkload>(*fillQueueDescriptor,
info);
402 auto floorQueueDescriptor = PolymorphicDowncast<const FloorQueueDescriptor*>(&descriptor);
403 return MakeWorkloadHelper<NeonFloorFloatWorkload, NullWorkload>(*floorQueueDescriptor,
info);
407 auto fullyConnectedQueueDescriptor = PolymorphicDowncast<const FullyConnectedQueueDescriptor*>(&descriptor);
408 return std::make_unique<NeonFullyConnectedWorkload>(*fullyConnectedQueueDescriptor,
410 m_MemoryManager->GetIntraLayerManager());
414 auto fusedQueueDescriptor = PolymorphicDowncast<const FusedQueueDescriptor*>(&descriptor);
415 return std::make_unique<NeonFusedWorkload>(*fusedQueueDescriptor,
info);
419 auto gatherQueueDescriptor = PolymorphicDowncast<const GatherQueueDescriptor*>(&descriptor);
420 return std::make_unique<NeonGatherWorkload>(*gatherQueueDescriptor,
info);
424 auto gatherNdQueueDescriptor = PolymorphicDowncast<const GatherNdQueueDescriptor*>(&descriptor);
425 return std::make_unique<NeonGatherNdWorkload>(*gatherNdQueueDescriptor,
info);
429 auto inputQueueDescriptor = PolymorphicDowncast<const InputQueueDescriptor*>(&descriptor);
430 return std::make_unique<CopyMemGenericWorkload>(*inputQueueDescriptor,
info);
434 auto instanceNormalizationQueueDescriptor
435 = PolymorphicDowncast<const InstanceNormalizationQueueDescriptor*>(&descriptor);
436 return std::make_unique<NeonInstanceNormalizationWorkload>(*instanceNormalizationQueueDescriptor,
info);
440 auto l2NormalizationQueueDescriptor
441 = PolymorphicDowncast<const L2NormalizationQueueDescriptor*>(&descriptor);
442 return MakeWorkloadHelper<NeonL2NormalizationFloatWorkload, NullWorkload>
443 (*l2NormalizationQueueDescriptor,
info, m_MemoryManager->GetIntraLayerManager());
447 auto logSoftmaxQueueDescriptor = PolymorphicDowncast<const LogSoftmaxQueueDescriptor*>(&descriptor);
448 return std::make_unique<NeonLogSoftmaxWorkload>(*logSoftmaxQueueDescriptor,
450 m_MemoryManager->GetIntraLayerManager());
454 auto logicalBinaryQueueDescriptor = PolymorphicDowncast<const LogicalBinaryQueueDescriptor*>(&descriptor);
455 switch(logicalBinaryQueueDescriptor->m_Parameters.m_Operation)
458 return std::make_unique<NeonLogicalAndWorkload>(*logicalBinaryQueueDescriptor,
info);
460 return std::make_unique<NeonLogicalOrWorkload>(*logicalBinaryQueueDescriptor,
info);
467 auto lstmQueueDescriptor = PolymorphicDowncast<const LstmQueueDescriptor*>(&descriptor);
468 return MakeWorkloadHelper<NeonLstmFloatWorkload, NullWorkload>(*lstmQueueDescriptor,
info);
472 auto maximumQueueDescriptor = PolymorphicDowncast<const MaximumQueueDescriptor*>(&descriptor);
473 return std::make_unique<NeonMaximumWorkload>(*maximumQueueDescriptor,
info);
477 auto meanQueueDescriptor = PolymorphicDowncast<const MeanQueueDescriptor*>(&descriptor);
478 return std::make_unique<NeonMeanWorkload>(*meanQueueDescriptor,
info);
482 auto memCopyQueueDescriptor = PolymorphicDowncast<const MemCopyQueueDescriptor*>(&descriptor);
483 if (memCopyQueueDescriptor->m_Inputs.empty() || !memCopyQueueDescriptor->m_Inputs[0])
487 return MakeWorkloadHelper<CopyMemGenericWorkload, CopyMemGenericWorkload>(*memCopyQueueDescriptor,
info);
491 auto memImportQueueDescriptor = PolymorphicDowncast<const MemImportQueueDescriptor*>(&descriptor);
492 if (memImportQueueDescriptor->m_Inputs.empty() || !memImportQueueDescriptor->m_Inputs[0])
496 return std::make_unique<ImportMemGenericWorkload>(*memImportQueueDescriptor,
info);
500 auto minimumQueueDescriptor = PolymorphicDowncast<const MinimumQueueDescriptor*>(&descriptor);
501 return std::make_unique<NeonMinimumWorkload>(*minimumQueueDescriptor,
info);
505 auto multiplicationQueueDescriptor = PolymorphicDowncast<const MultiplicationQueueDescriptor*>(&descriptor);
506 return std::make_unique<NeonMultiplicationWorkload>(*multiplicationQueueDescriptor,
info);
510 auto normalizationQueueDescriptor = PolymorphicDowncast<const NormalizationQueueDescriptor*>(&descriptor);
511 return MakeWorkloadHelper<NeonNormalizationFloatWorkload, NullWorkload>
512 (*normalizationQueueDescriptor,
info, m_MemoryManager->GetIntraLayerManager());
516 auto outputQueueDescriptor = PolymorphicDowncast<const OutputQueueDescriptor*>(&descriptor);
517 return std::make_unique<CopyMemGenericWorkload>(*outputQueueDescriptor,
info);
521 auto padQueueDescriptor = PolymorphicDowncast<const PadQueueDescriptor*>(&descriptor);
522 return std::make_unique<NeonPadWorkload>(*padQueueDescriptor,
info);
526 auto permuteQueueDescriptor = PolymorphicDowncast<const PermuteQueueDescriptor*>(&descriptor);
527 return std::make_unique<NeonPermuteWorkload>(*permuteQueueDescriptor,
info);
531 auto pooling2dQueueDescriptor = PolymorphicDowncast<const Pooling2dQueueDescriptor*>(&descriptor);
532 return std::make_unique<NeonPooling2dWorkload>(*pooling2dQueueDescriptor,
info);
536 auto pooling3dQueueDescriptor = PolymorphicDowncast<const Pooling3dQueueDescriptor*>(&descriptor);
537 return std::make_unique<NeonPooling3dWorkload>(*pooling3dQueueDescriptor,
info);
541 auto preCompiledQueueDescriptor = PolymorphicDowncast<const PreCompiledQueueDescriptor*>(&descriptor);
542 return MakeWorkloadHelper<NullWorkload, NullWorkload>(*preCompiledQueueDescriptor,
info);
546 auto preluQueueDescriptor = PolymorphicDowncast<const PreluQueueDescriptor*>(&descriptor);
547 return std::make_unique<NeonPreluWorkload>(*preluQueueDescriptor,
info);
551 auto qLstmQueueDescriptor = PolymorphicDowncast<const QLstmQueueDescriptor*>(&descriptor);
552 return std::make_unique<NeonQLstmWorkload>(*qLstmQueueDescriptor,
info);
556 auto quantizeQueueDescriptor = PolymorphicDowncast<const QuantizeQueueDescriptor*>(&descriptor);
557 return std::make_unique<NeonQuantizeWorkload>(*quantizeQueueDescriptor,
info);
561 auto quantizedLstmQueueDescriptor = PolymorphicDowncast<const QuantizedLstmQueueDescriptor*>(&descriptor);
562 return std::make_unique<NeonQuantizedLstmWorkload>(*quantizedLstmQueueDescriptor,
info);
566 auto rankQueueDescriptor = PolymorphicDowncast<const RankQueueDescriptor*>(&descriptor);
567 return std::make_unique<NeonRankWorkload>(*rankQueueDescriptor,
info);
571 auto reduceQueueDescriptor = PolymorphicDowncast<const ReduceQueueDescriptor*>(&descriptor);
572 return std::make_unique<NeonReduceWorkload>(*reduceQueueDescriptor,
info);
576 auto reshapeQueueDescriptor = PolymorphicDowncast<const ReshapeQueueDescriptor*>(&descriptor);
577 return std::make_unique<NeonReshapeWorkload>(*reshapeQueueDescriptor,
info);
581 auto resizeQueueDescriptor = PolymorphicDowncast<const ResizeQueueDescriptor*>(&descriptor);
582 return std::make_unique<NeonResizeWorkload>(*resizeQueueDescriptor,
info);
586 auto reverseV2QueueDescriptor = PolymorphicDowncast<const ReverseV2QueueDescriptor*>(&descriptor);
587 return std::make_unique<NeonReverseV2Workload>(*reverseV2QueueDescriptor,
info);
591 auto sliceQueueDescriptor = PolymorphicDowncast<const SliceQueueDescriptor*>(&descriptor);
592 return std::make_unique<NeonSliceWorkload>(*sliceQueueDescriptor,
info);
596 auto softmaxQueueDescriptor = PolymorphicDowncast<const SoftmaxQueueDescriptor*>(&descriptor);
597 return std::make_unique<NeonSoftmaxWorkload>(*softmaxQueueDescriptor,
599 m_MemoryManager->GetIntraLayerManager());
603 auto spaceToBatchNdQueueDescriptor
604 = PolymorphicDowncast<const SpaceToBatchNdQueueDescriptor*>(&descriptor);
605 return std::make_unique<NeonSpaceToBatchNdWorkload>(*spaceToBatchNdQueueDescriptor,
info);
609 auto spaceToDepthQueueDescriptor = PolymorphicDowncast<const SpaceToDepthQueueDescriptor*>(&descriptor);
610 return std::make_unique<NeonSpaceToDepthWorkload>(*spaceToDepthQueueDescriptor,
info);
614 auto splitterQueueDescriptor = PolymorphicDowncast<const SplitterQueueDescriptor*>(&descriptor);
615 return std::make_unique<NeonSplitterWorkload>(*splitterQueueDescriptor,
info);
619 auto stackQueueDescriptor = PolymorphicDowncast<const StackQueueDescriptor*>(&descriptor);
620 return std::make_unique<NeonStackWorkload>(*stackQueueDescriptor,
info);
624 auto stridedSliceQueueDescriptor = PolymorphicDowncast<const StridedSliceQueueDescriptor*>(&descriptor);
625 return std::make_unique<NeonStridedSliceWorkload>(*stridedSliceQueueDescriptor,
info);
629 auto subtractionQueueDescriptor = PolymorphicDowncast<const SubtractionQueueDescriptor*>(&descriptor);
630 return std::make_unique<NeonSubtractionWorkload>(*subtractionQueueDescriptor,
info);
634 auto tileQueueDescriptor = PolymorphicDowncast<const TileQueueDescriptor*>(&descriptor);
635 return std::make_unique<NeonTileWorkload>(*tileQueueDescriptor,
info);
639 auto transposeQueueDescriptor = PolymorphicDowncast<const TransposeQueueDescriptor*>(&descriptor);
640 return std::make_unique<NeonTransposeWorkload>(*transposeQueueDescriptor,
info);
644 auto transposeConvolution2dQueueDescriptor
645 = PolymorphicDowncast<const TransposeConvolution2dQueueDescriptor*>(&descriptor);
646 return std::make_unique<NeonTransposeConvolution2dWorkload>(*transposeConvolution2dQueueDescriptor,
648 m_MemoryManager->GetIntraLayerManager());
652 auto desc = PolymorphicDowncast<const UnidirectionalSequenceLstmQueueDescriptor*>(&descriptor);
660 return std::make_unique<NeonUnidirectionalSequenceLstmFloatWorkload>(*desc,
info);
664 return std::make_unique<NeonUnidirectionalSequenceLstmWorkload>(*desc,
info);
std::shared_ptr< IBackendModelContext > IBackendSpecificModelContextPtr
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
virtual TensorShape GetShape() const =0
Get the number of elements for each dimension ordered from slowest iterating dimension to fastest ite...
static bool IsLayerSupported(const BackendId &backendId, const IConnectableLayer &layer, Optional< DataType > dataType, std::string &outReasonIfUnsupported)
The NeonBackendModelContext is used to pass in Neon specific backend ModelOptions.
unsigned int GetNumberOfThreads() const
bool IsFastMathEnabled() const
NeonWorkloadFactory(const std::shared_ptr< NeonMemoryManager > &memoryManager)
std::unique_ptr< ITensorHandle > CreateTensorHandle(const TensorInfo &tensorInfo, const bool IsMemoryManaged=true) const override
std::unique_ptr< IWorkload > CreateWorkload(LayerType type, const QueueDescriptor &descriptor, const WorkloadInfo &info) const override
Backends should implement their own CreateWorkload function with a switch statement.
static bool IsLayerSupported(const Layer &layer, Optional< DataType > dataType, std::string &outReasonIfUnsupported)
std::unique_ptr< ITensorHandle > CreateSubTensorHandle(ITensorHandle &parent, TensorShape const &subTensorShape, unsigned int const *subTensorOrigin) const override
const BackendId & GetBackendId() const override
unsigned int GetNumDimensions() const
Function that returns the tensor rank.
Copyright (c) 2021 ARM Limited and Contributors.
constexpr const char * NeonBackendId()
LayerType
When adding a new layer, adapt also the LastLayer enum value in the enum class LayerType below.
@ UnidirectionalSequenceLstm
std::vector< BackendOptions > ModelOptions
std::array< unsigned int, MaxNumOfTensorDimensions > Coordinates
std::vector< ITensorHandle * > m_Inputs
std::vector< ITensorHandle * > m_Outputs
Contains information about TensorInfos of a layer.