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.
142 auto activationQueueDescriptor = PolymorphicDowncast<const ActivationQueueDescriptor*>(&descriptor);
143 return std::make_unique<NeonActivationWorkload>(*activationQueueDescriptor, info);
147 auto additionQueueDescriptor = PolymorphicDowncast<const AdditionQueueDescriptor*>(&descriptor);
148 return std::make_unique<NeonAdditionWorkload>(*additionQueueDescriptor, info);
152 auto argMinMaxQueueDescriptor = PolymorphicDowncast<const ArgMinMaxQueueDescriptor*>(&descriptor);
153 return std::make_unique<NeonArgMinMaxWorkload>(*argMinMaxQueueDescriptor, info);
157 auto batchMatMulQueueDescriptor = PolymorphicDowncast<const BatchMatMulQueueDescriptor*>(&descriptor);
158 bool isFastMathEnabled =
false;
159 if (m_ModelContextPtr)
161 if (m_ModelContextPtr.get() !=
nullptr)
163 auto modelOptions =
dynamic_cast<NeonBackendModelContext*
>(m_ModelContextPtr.get());
166 isFastMathEnabled = modelOptions->IsFastMathEnabled();
170 return std::make_unique<NeonBatchMatMulWorkload>(*batchMatMulQueueDescriptor, info, isFastMathEnabled);
174 auto batchNormalizationQueueDescriptor
175 = PolymorphicDowncast<const BatchNormalizationQueueDescriptor*>(&descriptor);
176 return std::make_unique<NeonBatchNormalizationWorkload>(*batchNormalizationQueueDescriptor, info);
180 auto batchToSpaceNdQueueDescriptor
181 = PolymorphicDowncast<const BatchToSpaceNdQueueDescriptor*>(&descriptor);
182 return std::make_unique<NeonBatchToSpaceNdWorkload>(*batchToSpaceNdQueueDescriptor, info);
186 auto castQueueDescriptor = PolymorphicDowncast<const CastQueueDescriptor*>(&descriptor);
187 return std::make_unique<NeonCastWorkload>(*castQueueDescriptor, info);
191 auto channelShuffleQueueDescriptor = PolymorphicDowncast<const ChannelShuffleQueueDescriptor*>(&descriptor);
192 return std::make_unique<NeonChannelShuffleWorkload>(*channelShuffleQueueDescriptor, info);
196 auto comparisonQueueDescriptor = PolymorphicDowncast<const ComparisonQueueDescriptor*>(&descriptor);
197 return std::make_unique<NeonComparisonWorkload>(*comparisonQueueDescriptor, info);
201 auto concatQueueDescriptor = PolymorphicDowncast<const ConcatQueueDescriptor*>(&descriptor);
202 return std::make_unique<NeonConcatWorkload>(*concatQueueDescriptor, info);
206 auto constantQueueDescriptor = PolymorphicDowncast<const ConstantQueueDescriptor*>(&descriptor);
207 return std::make_unique<NeonConstantWorkload>(*constantQueueDescriptor, info);
211 auto convertFp16ToFp32QueueDescriptor
212 = PolymorphicDowncast<const ConvertFp16ToFp32QueueDescriptor*>(&descriptor);
213 return std::make_unique<NeonConvertFp16ToFp32Workload>(*convertFp16ToFp32QueueDescriptor, info);
217 auto convertFp32ToFp16QueueDescriptor
218 = PolymorphicDowncast<const ConvertFp32ToFp16QueueDescriptor*>(&descriptor);
219 return std::make_unique<NeonConvertFp32ToFp16Workload>(*convertFp32ToFp16QueueDescriptor, info);
223 auto convolution2dQueueDescriptor = PolymorphicDowncast<const Convolution2dQueueDescriptor*>(&descriptor);
224 bool isFastMathEnabled =
false;
225 if (m_ModelContextPtr)
227 if (m_ModelContextPtr.get() !=
nullptr)
229 auto modelOptions =
dynamic_cast<NeonBackendModelContext*
>(m_ModelContextPtr.get());
232 isFastMathEnabled = modelOptions->IsFastMathEnabled();
236 return std::make_unique<NeonConvolution2dWorkload>(*convolution2dQueueDescriptor,
238 m_MemoryManager->GetIntraLayerManager(),
243 auto convolution3dQueueDescriptor = PolymorphicDowncast<const Convolution3dQueueDescriptor*>(&descriptor);
244 bool isFastMathEnabled =
false;
245 if (m_ModelContextPtr)
247 if (m_ModelContextPtr.get() !=
nullptr)
249 auto modelOptions =
dynamic_cast<NeonBackendModelContext*
>(m_ModelContextPtr.get());
252 isFastMathEnabled = modelOptions->IsFastMathEnabled();
256 return std::make_unique<NeonConvolution3dWorkload>(*convolution3dQueueDescriptor,
258 m_MemoryManager->GetIntraLayerManager(),
263 auto debugQueueDescriptor = PolymorphicDowncast<const DebugQueueDescriptor*>(&descriptor);
264 return MakeWorkloadHelper<NullWorkload, NullWorkload>(*debugQueueDescriptor, info);
268 auto depthToSpaceQueueDescriptor = PolymorphicDowncast<const DepthToSpaceQueueDescriptor*>(&descriptor);
269 return std::make_unique<NeonDepthToSpaceWorkload>(*depthToSpaceQueueDescriptor, info);
273 auto depthwiseConvolution2dQueueDescriptor
274 = PolymorphicDowncast<const DepthwiseConvolution2dQueueDescriptor*>(&descriptor);
275 return std::make_unique<NeonDepthwiseConvolutionWorkload>(*depthwiseConvolution2dQueueDescriptor, info);
279 auto dequantizeQueueDescriptor = PolymorphicDowncast<const DequantizeQueueDescriptor*>(&descriptor);
280 return std::make_unique<NeonDequantizeWorkload>(*dequantizeQueueDescriptor, info);
284 auto detectionPostProcessQueueDescriptor
285 = PolymorphicDowncast<const DetectionPostProcessQueueDescriptor*>(&descriptor);
286 return MakeWorkloadHelper<NullWorkload, NullWorkload>(*detectionPostProcessQueueDescriptor, info);
290 auto divisionQueueDescriptor = PolymorphicDowncast<const DivisionQueueDescriptor*>(&descriptor);
291 return std::make_unique<NeonDivisionWorkload>(*divisionQueueDescriptor, info);
295 auto elementwiseBinaryQueueDescriptor
296 = PolymorphicDowncast<const ElementwiseBinaryQueueDescriptor*>(&descriptor);
297 switch (elementwiseBinaryQueueDescriptor->m_Parameters.m_Operation)
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);
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);
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);
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);
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);
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);
344 return std::make_unique<NeonElementwiseBinaryWorkload>(*elementwiseBinaryQueueDescriptor, info);
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);
359 auto elementwiseUnaryQueueDescriptor
360 = PolymorphicDowncast<const ElementwiseUnaryQueueDescriptor*>(&descriptor);
361 switch(elementwiseUnaryQueueDescriptor->m_Parameters.m_Operation)
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);
371 return std::make_unique<NeonExpWorkload>(*elementwiseUnaryQueueDescriptor, info);
373 return std::make_unique<NeonLogicalNotWorkload>(*elementwiseUnaryQueueDescriptor, info);
375 return std::make_unique<NeonLogWorkload>(*elementwiseUnaryQueueDescriptor, info);
377 return std::make_unique<NeonNegWorkload>(*elementwiseUnaryQueueDescriptor, info);
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);
386 return std::make_unique<NeonSinWorkload>(*elementwiseUnaryQueueDescriptor, info);
388 return std::make_unique<NeonSqrtWorkload>(*elementwiseUnaryQueueDescriptor, info);
395 auto fillQueueDescriptor = PolymorphicDowncast<const FillQueueDescriptor*>(&descriptor);
396 return std::make_unique<NeonFillWorkload>(*fillQueueDescriptor, info);
400 auto floorQueueDescriptor = PolymorphicDowncast<const FloorQueueDescriptor*>(&descriptor);
401 return MakeWorkloadHelper<NeonFloorFloatWorkload, NullWorkload>(*floorQueueDescriptor, info);
405 auto fullyConnectedQueueDescriptor = PolymorphicDowncast<const FullyConnectedQueueDescriptor*>(&descriptor);
406 return std::make_unique<NeonFullyConnectedWorkload>(*fullyConnectedQueueDescriptor,
408 m_MemoryManager->GetIntraLayerManager());
412 auto fusedQueueDescriptor = PolymorphicDowncast<const FusedQueueDescriptor*>(&descriptor);
413 return std::make_unique<NeonFusedWorkload>(*fusedQueueDescriptor, info);
417 auto gatherQueueDescriptor = PolymorphicDowncast<const GatherQueueDescriptor*>(&descriptor);
418 return std::make_unique<NeonGatherWorkload>(*gatherQueueDescriptor, info);
422 auto gatherNdQueueDescriptor = PolymorphicDowncast<const GatherNdQueueDescriptor*>(&descriptor);
423 return std::make_unique<NeonGatherNdWorkload>(*gatherNdQueueDescriptor, info);
427 auto inputQueueDescriptor = PolymorphicDowncast<const InputQueueDescriptor*>(&descriptor);
428 return std::make_unique<CopyMemGenericWorkload>(*inputQueueDescriptor, info);
432 auto instanceNormalizationQueueDescriptor
433 = PolymorphicDowncast<const InstanceNormalizationQueueDescriptor*>(&descriptor);
434 return std::make_unique<NeonInstanceNormalizationWorkload>(*instanceNormalizationQueueDescriptor, info);
438 auto l2NormalizationQueueDescriptor
439 = PolymorphicDowncast<const L2NormalizationQueueDescriptor*>(&descriptor);
440 return MakeWorkloadHelper<NeonL2NormalizationFloatWorkload, NullWorkload>
441 (*l2NormalizationQueueDescriptor, info, m_MemoryManager->GetIntraLayerManager());
445 auto logSoftmaxQueueDescriptor = PolymorphicDowncast<const LogSoftmaxQueueDescriptor*>(&descriptor);
446 return std::make_unique<NeonLogSoftmaxWorkload>(*logSoftmaxQueueDescriptor,
448 m_MemoryManager->GetIntraLayerManager());
452 auto logicalBinaryQueueDescriptor = PolymorphicDowncast<const LogicalBinaryQueueDescriptor*>(&descriptor);
453 switch(logicalBinaryQueueDescriptor->m_Parameters.m_Operation)
456 return std::make_unique<NeonLogicalAndWorkload>(*logicalBinaryQueueDescriptor, info);
458 return std::make_unique<NeonLogicalOrWorkload>(*logicalBinaryQueueDescriptor, info);
465 auto lstmQueueDescriptor = PolymorphicDowncast<const LstmQueueDescriptor*>(&descriptor);
466 return MakeWorkloadHelper<NeonLstmFloatWorkload, NullWorkload>(*lstmQueueDescriptor, info);
470 auto maximumQueueDescriptor = PolymorphicDowncast<const MaximumQueueDescriptor*>(&descriptor);
471 return std::make_unique<NeonMaximumWorkload>(*maximumQueueDescriptor, info);
475 auto meanQueueDescriptor = PolymorphicDowncast<const MeanQueueDescriptor*>(&descriptor);
476 return std::make_unique<NeonMeanWorkload>(*meanQueueDescriptor, info);
480 auto memCopyQueueDescriptor = PolymorphicDowncast<const MemCopyQueueDescriptor*>(&descriptor);
481 if (memCopyQueueDescriptor->m_Inputs.empty() || !memCopyQueueDescriptor->m_Inputs[0])
483 throw InvalidArgumentException(
"NeonWorkloadFactory: Invalid null input for MemCopy workload");
485 return MakeWorkloadHelper<CopyMemGenericWorkload, CopyMemGenericWorkload>(*memCopyQueueDescriptor, info);
489 auto memImportQueueDescriptor = PolymorphicDowncast<const MemImportQueueDescriptor*>(&descriptor);
490 if (memImportQueueDescriptor->m_Inputs.empty() || !memImportQueueDescriptor->m_Inputs[0])
492 throw InvalidArgumentException(
"NeonWorkloadFactory: Invalid null input for MemImport workload");
494 return std::make_unique<ImportMemGenericWorkload>(*memImportQueueDescriptor, info);
498 auto minimumQueueDescriptor = PolymorphicDowncast<const MinimumQueueDescriptor*>(&descriptor);
499 return std::make_unique<NeonMinimumWorkload>(*minimumQueueDescriptor, info);
503 auto multiplicationQueueDescriptor = PolymorphicDowncast<const MultiplicationQueueDescriptor*>(&descriptor);
504 return std::make_unique<NeonMultiplicationWorkload>(*multiplicationQueueDescriptor, info);
508 auto normalizationQueueDescriptor = PolymorphicDowncast<const NormalizationQueueDescriptor*>(&descriptor);
509 return MakeWorkloadHelper<NeonNormalizationFloatWorkload, NullWorkload>
510 (*normalizationQueueDescriptor, info, m_MemoryManager->GetIntraLayerManager());
514 auto outputQueueDescriptor = PolymorphicDowncast<const OutputQueueDescriptor*>(&descriptor);
515 return std::make_unique<CopyMemGenericWorkload>(*outputQueueDescriptor, info);
519 auto padQueueDescriptor = PolymorphicDowncast<const PadQueueDescriptor*>(&descriptor);
520 return std::make_unique<NeonPadWorkload>(*padQueueDescriptor, info);
524 auto permuteQueueDescriptor = PolymorphicDowncast<const PermuteQueueDescriptor*>(&descriptor);
525 return std::make_unique<NeonPermuteWorkload>(*permuteQueueDescriptor, info);
529 auto pooling2dQueueDescriptor = PolymorphicDowncast<const Pooling2dQueueDescriptor*>(&descriptor);
530 return std::make_unique<NeonPooling2dWorkload>(*pooling2dQueueDescriptor, info);
534 auto pooling3dQueueDescriptor = PolymorphicDowncast<const Pooling3dQueueDescriptor*>(&descriptor);
535 return std::make_unique<NeonPooling3dWorkload>(*pooling3dQueueDescriptor, info);
539 auto preCompiledQueueDescriptor = PolymorphicDowncast<const PreCompiledQueueDescriptor*>(&descriptor);
540 return MakeWorkloadHelper<NullWorkload, NullWorkload>(*preCompiledQueueDescriptor, info);
544 auto preluQueueDescriptor = PolymorphicDowncast<const PreluQueueDescriptor*>(&descriptor);
545 return std::make_unique<NeonPreluWorkload>(*preluQueueDescriptor, info);
549 auto qLstmQueueDescriptor = PolymorphicDowncast<const QLstmQueueDescriptor*>(&descriptor);
550 return std::make_unique<NeonQLstmWorkload>(*qLstmQueueDescriptor, info);
554 auto quantizeQueueDescriptor = PolymorphicDowncast<const QuantizeQueueDescriptor*>(&descriptor);
555 return std::make_unique<NeonQuantizeWorkload>(*quantizeQueueDescriptor, info);
559 auto quantizedLstmQueueDescriptor = PolymorphicDowncast<const QuantizedLstmQueueDescriptor*>(&descriptor);
560 return std::make_unique<NeonQuantizedLstmWorkload>(*quantizedLstmQueueDescriptor, info);
564 auto rankQueueDescriptor = PolymorphicDowncast<const RankQueueDescriptor*>(&descriptor);
565 return std::make_unique<NeonRankWorkload>(*rankQueueDescriptor, info);
569 auto reduceQueueDescriptor = PolymorphicDowncast<const ReduceQueueDescriptor*>(&descriptor);
570 return std::make_unique<NeonReduceWorkload>(*reduceQueueDescriptor, info);
574 auto reshapeQueueDescriptor = PolymorphicDowncast<const ReshapeQueueDescriptor*>(&descriptor);
575 return std::make_unique<NeonReshapeWorkload>(*reshapeQueueDescriptor, info);
579 auto resizeQueueDescriptor = PolymorphicDowncast<const ResizeQueueDescriptor*>(&descriptor);
580 return std::make_unique<NeonResizeWorkload>(*resizeQueueDescriptor, info);
584 auto reverseV2QueueDescriptor = PolymorphicDowncast<const ReverseV2QueueDescriptor*>(&descriptor);
585 return std::make_unique<NeonReverseV2Workload>(*reverseV2QueueDescriptor, info);
589 auto sliceQueueDescriptor = PolymorphicDowncast<const SliceQueueDescriptor*>(&descriptor);
590 return std::make_unique<NeonSliceWorkload>(*sliceQueueDescriptor, info);
594 auto softmaxQueueDescriptor = PolymorphicDowncast<const SoftmaxQueueDescriptor*>(&descriptor);
595 return std::make_unique<NeonSoftmaxWorkload>(*softmaxQueueDescriptor,
597 m_MemoryManager->GetIntraLayerManager());
601 auto spaceToBatchNdQueueDescriptor
602 = PolymorphicDowncast<const SpaceToBatchNdQueueDescriptor*>(&descriptor);
603 return std::make_unique<NeonSpaceToBatchNdWorkload>(*spaceToBatchNdQueueDescriptor, info);
607 auto spaceToDepthQueueDescriptor = PolymorphicDowncast<const SpaceToDepthQueueDescriptor*>(&descriptor);
608 return std::make_unique<NeonSpaceToDepthWorkload>(*spaceToDepthQueueDescriptor, info);
612 auto splitterQueueDescriptor = PolymorphicDowncast<const SplitterQueueDescriptor*>(&descriptor);
613 return std::make_unique<NeonSplitterWorkload>(*splitterQueueDescriptor, info);
617 auto stackQueueDescriptor = PolymorphicDowncast<const StackQueueDescriptor*>(&descriptor);
618 return std::make_unique<NeonStackWorkload>(*stackQueueDescriptor, info);
622 auto stridedSliceQueueDescriptor = PolymorphicDowncast<const StridedSliceQueueDescriptor*>(&descriptor);
623 return std::make_unique<NeonStridedSliceWorkload>(*stridedSliceQueueDescriptor, info);
627 auto subtractionQueueDescriptor = PolymorphicDowncast<const SubtractionQueueDescriptor*>(&descriptor);
628 return std::make_unique<NeonSubtractionWorkload>(*subtractionQueueDescriptor, info);
632 auto tileQueueDescriptor = PolymorphicDowncast<const TileQueueDescriptor*>(&descriptor);
633 return std::make_unique<NeonTileWorkload>(*tileQueueDescriptor, info);
637 auto transposeQueueDescriptor = PolymorphicDowncast<const TransposeQueueDescriptor*>(&descriptor);
638 return std::make_unique<NeonTransposeWorkload>(*transposeQueueDescriptor, info);
642 auto transposeConvolution2dQueueDescriptor
643 = PolymorphicDowncast<const TransposeConvolution2dQueueDescriptor*>(&descriptor);
644 return std::make_unique<NeonTransposeConvolution2dWorkload>(*transposeConvolution2dQueueDescriptor,
646 m_MemoryManager->GetIntraLayerManager());
650 auto desc = PolymorphicDowncast<const UnidirectionalSequenceLstmQueueDescriptor*>(&descriptor);
658 return std::make_unique<NeonUnidirectionalSequenceLstmFloatWorkload>(*desc, info);
662 return std::make_unique<NeonUnidirectionalSequenceLstmWorkload>(*desc, info);
@ UnidirectionalSequenceLstm