ArmNN
 21.05
RefWorkloadFactory.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 #include <Layer.hpp>
11 #include "RefWorkloadFactory.hpp"
12 #include "RefBackendId.hpp"
14 #include "RefTensorHandle.hpp"
15 
16 
17 namespace armnn
18 {
19 
20 namespace
21 {
22 static const BackendId s_Id{RefBackendId()};
23 }
24 template <typename F32Workload, typename U8Workload, typename QueueDescriptorType>
25 std::unique_ptr<IWorkload> RefWorkloadFactory::MakeWorkload(const QueueDescriptorType& descriptor,
26  const WorkloadInfo& info) const
27 {
28  return MakeWorkloadHelper<NullWorkload, F32Workload, U8Workload, NullWorkload, NullWorkload, NullWorkload>
29  (descriptor, info);
30 }
31 
32 template <DataType ArmnnType>
34 {
35  auto checkType = [](const TensorInfo& tensorInfo) {return tensorInfo.GetDataType() == ArmnnType;};
36  auto it = std::find_if(std::begin(info.m_InputTensorInfos), std::end(info.m_InputTensorInfos), checkType);
37  if (it != std::end(info.m_InputTensorInfos))
38  {
39  return true;
40  }
41  it = std::find_if(std::begin(info.m_OutputTensorInfos), std::end(info.m_OutputTensorInfos), checkType);
42  if (it != std::end(info.m_OutputTensorInfos))
43  {
44  return true;
45  }
46  return false;
47 }
48 
50 {
51  return IsDataType<DataType::Signed32>(info);
52 }
53 
55 {
56  return IsDataType<DataType::BFloat16>(info);
57 }
58 
60 {
61  return IsDataType<DataType::Float16>(info);
62 }
63 
65 {
66  return IsDataType<DataType::QSymmS16>(info);
67 }
68 
70 {
71  return IsDataType<DataType::QSymmS8>(info);
72 }
73 
75 {
76  return IsDataType<DataType::QAsymmS8>(info);
77 }
78 
80 {
81  return IsDataType<DataType::QAsymmU8>(info);
82 }
83 
84 RefWorkloadFactory::RefWorkloadFactory(const std::shared_ptr<RefMemoryManager>& memoryManager)
85  : m_MemoryManager(memoryManager)
86 {
87 }
88 
90  : m_MemoryManager(new RefMemoryManager())
91 {
92 }
93 
95 {
96  return s_Id;
97 }
98 
100  Optional<DataType> dataType,
101  std::string& outReasonIfUnsupported)
102 {
103  return IWorkloadFactory::IsLayerSupported(s_Id, layer, dataType, outReasonIfUnsupported);
104 }
105 
107  Optional<DataType> dataType,
108  std::string& outReasonIfUnsupported,
109  const ModelOptions& modelOptions)
110 {
111  return IWorkloadFactory::IsLayerSupported(s_Id, layer, dataType, outReasonIfUnsupported, modelOptions);
112 }
113 
114 std::unique_ptr<ITensorHandle> RefWorkloadFactory::CreateTensorHandle(const TensorInfo& tensorInfo,
115  const bool isMemoryManaged) const
116 {
117  // For Ref it is okay to make the TensorHandle memory managed as it can also store a pointer
118  // to unmanaged memory. This also ensures memory alignment.
119  IgnoreUnused(isMemoryManaged);
120  return std::make_unique<RefTensorHandle>(tensorInfo, m_MemoryManager);
121 }
122 
123 std::unique_ptr<ITensorHandle> RefWorkloadFactory::CreateTensorHandle(const TensorInfo& tensorInfo,
124  DataLayout dataLayout,
125  const bool isMemoryManaged) const
126 {
127  // For Ref it is okay to make the TensorHandle memory managed as it can also store a pointer
128  // to unmanaged memory. This also ensures memory alignment.
129  IgnoreUnused(isMemoryManaged, dataLayout);
130  return std::make_unique<RefTensorHandle>(tensorInfo, m_MemoryManager);
131 }
132 
133 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateAbs(const AbsQueueDescriptor& descriptor,
134  const WorkloadInfo& info) const
135 {
136  IgnoreUnused(descriptor);
137  ElementwiseUnaryQueueDescriptor elementwiseUnaryDescriptor;
138  elementwiseUnaryDescriptor.m_Parameters.m_Operation = UnaryOperation::Abs;
139 
140  return CreateElementwiseUnary(elementwiseUnaryDescriptor, info);
141 }
142 
143 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateActivation(const ActivationQueueDescriptor& descriptor,
144  const WorkloadInfo& info) const
145 {
146  return std::make_unique<RefActivationWorkload>(descriptor, info);
147 }
148 
149 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateAddition(const AdditionQueueDescriptor& descriptor,
150  const WorkloadInfo& info) const
151 {
152  if (info.m_InputTensorInfos[0].GetDataType() == armnn::DataType::Signed32)
153  {
154  return std::make_unique<RefAdditionWorkload<int32_t>>(descriptor, info);
155  }
156  else
157  {
158  return std::make_unique<RefAdditionWorkload<float>>(descriptor, info);
159  }
160 }
161 
162 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateArgMinMax(const ArgMinMaxQueueDescriptor& descriptor,
163  const WorkloadInfo& info) const
164 {
165  return std::make_unique<RefArgMinMaxWorkload>(descriptor, info);
166 }
167 
169  const BatchNormalizationQueueDescriptor& descriptor,
170  const WorkloadInfo& info) const
171 {
172  return std::make_unique<RefBatchNormalizationWorkload>(descriptor, info);
173 }
174 
175 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateBatchToSpaceNd(const BatchToSpaceNdQueueDescriptor& descriptor,
176  const WorkloadInfo& info) const
177 {
178  return std::make_unique<RefBatchToSpaceNdWorkload>(descriptor, info);
179 }
180 
181 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateCast(const CastQueueDescriptor& descriptor,
182  const WorkloadInfo& info) const
183 {
184  return std::make_unique<RefCastWorkload>(descriptor, info);
185 }
186 
187 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateComparison(const ComparisonQueueDescriptor& descriptor,
188  const WorkloadInfo& info) const
189 {
190  return std::make_unique<RefComparisonWorkload>(descriptor, info);
191 }
192 
193 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateConcat(const ConcatQueueDescriptor& descriptor,
194  const WorkloadInfo& info) const
195 {
196  return std::make_unique<RefConcatWorkload>(descriptor, info);
197 }
198 
199 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateConstant(const ConstantQueueDescriptor& descriptor,
200  const WorkloadInfo& info) const
201 {
202  return std::make_unique<RefConstantWorkload>(descriptor, info);
203 }
204 
206  const ConvertBf16ToFp32QueueDescriptor& descriptor,
207  const WorkloadInfo& info) const
208 {
209  return std::make_unique<RefConvertBf16ToFp32Workload>(descriptor, info);
210 }
211 
213  const ConvertFp16ToFp32QueueDescriptor& descriptor,
214  const WorkloadInfo& info) const
215 {
216  return std::make_unique<RefConvertFp16ToFp32Workload>(descriptor, info);
217 }
218 
220  const ConvertFp32ToBf16QueueDescriptor& descriptor,
221  const WorkloadInfo& info) const
222 {
223  return std::make_unique<RefConvertFp32ToBf16Workload>(descriptor, info);
224 }
225 
227  const ConvertFp32ToFp16QueueDescriptor& descriptor,
228  const WorkloadInfo& info) const
229 {
230  return std::make_unique<RefConvertFp32ToFp16Workload>(descriptor, info);
231 }
232 
233 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateConvolution2d(const Convolution2dQueueDescriptor& descriptor,
234  const WorkloadInfo& info) const
235 {
236  return std::make_unique<RefConvolution2dWorkload>(descriptor, info);
237 }
238 
239 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateDebug(const DebugQueueDescriptor& descriptor,
240  const WorkloadInfo& info) const
241 {
242  if (IsBFloat16(info))
243  {
244  return std::make_unique<RefDebugBFloat16Workload>(descriptor, info);
245  }
246  if (IsFloat16(info))
247  {
248  return std::make_unique<RefDebugFloat16Workload>(descriptor, info);
249  }
250  if (IsQSymmS16(info))
251  {
252  return std::make_unique<RefDebugQSymmS16Workload>(descriptor, info);
253  }
254  if (IsQSymmS8(info))
255  {
256  return std::make_unique<RefDebugQSymmS8Workload>(descriptor, info);
257  }
258  if (IsQAsymmU8(info))
259  {
260  return std::make_unique<RefDebugQAsymmU8Workload>(descriptor, info);
261  }
262  if (IsQAsymmS8(info))
263  {
264  return std::make_unique<RefDebugQAsymmS8Workload>(descriptor, info);
265  }
266  if (IsSigned32(info))
267  {
268  return std::make_unique<RefDebugSigned32Workload>(descriptor, info);
269  }
270 
271  return MakeWorkload<RefDebugFloat32Workload, RefDebugQAsymmU8Workload>(descriptor, info);
272 }
273 
274 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateDepthToSpace(const DepthToSpaceQueueDescriptor& descriptor,
275  const WorkloadInfo& info) const
276 {
277  return std::make_unique<RefDepthToSpaceWorkload>(descriptor, info);
278 }
279 
281  const DepthwiseConvolution2dQueueDescriptor& descriptor,
282  const WorkloadInfo& info) const
283 {
284  return std::make_unique<RefDepthwiseConvolution2dWorkload>(descriptor, info);
285 }
286 
287 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateDequantize(const DequantizeQueueDescriptor& descriptor,
288  const WorkloadInfo& info) const
289 {
290  return std::make_unique<RefDequantizeWorkload>(descriptor, info);
291 }
292 
294  const DetectionPostProcessQueueDescriptor& descriptor,
295  const WorkloadInfo& info) const
296 {
297  return std::make_unique<RefDetectionPostProcessWorkload>(descriptor, info);
298 }
299 
300 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateDivision(const DivisionQueueDescriptor& descriptor,
301  const WorkloadInfo& info) const
302 {
303  if (info.m_InputTensorInfos[0].GetDataType() == armnn::DataType::Signed32)
304  {
305  return std::make_unique<RefDivisionWorkload<int32_t>>(descriptor, info);
306  }
307  else
308  {
309  return std::make_unique<RefDivisionWorkload<float>>(descriptor, info);
310  }
311 }
312 
314  const WorkloadInfo& info) const
315 {
317  {
318  return std::make_unique<RefLogicalUnaryWorkload>(descriptor, info);
319  }
320  return std::make_unique<RefElementwiseUnaryWorkload>(descriptor, info);
321 }
322 
323 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateEqual(const EqualQueueDescriptor& descriptor,
324  const WorkloadInfo& info) const
325 {
326  IgnoreUnused(descriptor);
327  ComparisonQueueDescriptor comparisonDescriptor;
328  comparisonDescriptor.m_Parameters.m_Operation = ComparisonOperation::Equal;
329 
330  return CreateComparison(comparisonDescriptor, info);
331 }
332 
334  const WorkloadInfo& info) const
335 {
336  return MakeWorkload<RefFakeQuantizationFloat32Workload, NullWorkload>(descriptor, info);
337 }
338 
339 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateFill(const FillQueueDescriptor& descriptor,
340  const WorkloadInfo& info) const
341 {
342  return std::make_unique<RefFillWorkload>(descriptor, info);
343 }
344 
345 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateFloor(const FloorQueueDescriptor& descriptor,
346  const WorkloadInfo& info) const
347 {
348  if(IsQuantizedType(info.m_InputTensorInfos[0].GetDataType()))
349  {
350  return nullptr;
351  }
352  else
353  {
354  return std::make_unique<RefFloorWorkload>(descriptor, info);
355  }
356 }
357 
358 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateFullyConnected(
359  const FullyConnectedQueueDescriptor& descriptor,
360  const WorkloadInfo& info) const
361 {
362  return std::make_unique<RefFullyConnectedWorkload>(descriptor, info);
363 }
364 
365 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateGather(const GatherQueueDescriptor& descriptor,
366  const WorkloadInfo& info) const
367 {
368  return std::make_unique<RefGatherWorkload>(descriptor, info);
369 }
370 
371 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateGreater(const GreaterQueueDescriptor& descriptor,
372  const WorkloadInfo& info) const
373 {
374  IgnoreUnused(descriptor);
375  ComparisonQueueDescriptor comparisonDescriptor;
377 
378  return CreateComparison(comparisonDescriptor, info);
379 }
380 
381 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateInput(const InputQueueDescriptor& descriptor,
382  const WorkloadInfo& info) const
383 {
384  if (info.m_InputTensorInfos.empty() )
385  {
386  throw InvalidArgumentException("RefWorkloadFactory::CreateInput: Input cannot be zero length");
387  }
388  if (info.m_OutputTensorInfos.empty())
389  {
390  throw InvalidArgumentException("RefWorkloadFactory::CreateInput: Output cannot be zero length");
391  }
392 
393  if (info.m_InputTensorInfos[0].GetNumBytes() != info.m_OutputTensorInfos[0].GetNumBytes())
394  {
395  throw InvalidArgumentException("RefWorkloadFactory::CreateInput: data input and output differ in byte count.");
396  }
397 
398  return std::make_unique<CopyMemGenericWorkload>(descriptor, info);
399 }
400 
402  const InstanceNormalizationQueueDescriptor& descriptor,
403  const WorkloadInfo& info) const
404 {
405  return std::make_unique<RefInstanceNormalizationWorkload>(descriptor, info);
406 }
407 
409  const WorkloadInfo& info) const
410 {
411  return std::make_unique<RefL2NormalizationWorkload>(descriptor, info);
412 }
413 
414 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateLogicalBinary(const LogicalBinaryQueueDescriptor& descriptor,
415  const WorkloadInfo& info) const
416 {
417  return std::make_unique<RefLogicalBinaryWorkload>(descriptor, info);
418 }
419 
420 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateLogSoftmax(const LogSoftmaxQueueDescriptor& descriptor,
421  const WorkloadInfo& info) const
422 {
423  return std::make_unique<RefLogSoftmaxWorkload>(descriptor, info);
424 }
425 
426 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateLstm(const LstmQueueDescriptor& descriptor,
427  const WorkloadInfo& info) const
428 {
429  return std::make_unique<RefLstmWorkload>(descriptor, info);
430 }
431 
432 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateMaximum(const MaximumQueueDescriptor& descriptor,
433  const WorkloadInfo& info) const
434 {
435  if (info.m_InputTensorInfos[0].GetDataType() == armnn::DataType::Signed32)
436  {
437  return std::make_unique<RefMaximumWorkload<int32_t>>(descriptor, info);
438  }
439  else
440  {
441  return std::make_unique<RefMaximumWorkload<float>>(descriptor, info);
442  }
443 }
444 
445 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateMean(const MeanQueueDescriptor& descriptor,
446  const WorkloadInfo& info) const
447 {
448  return std::make_unique<RefMeanWorkload>(descriptor, info);
449 }
450 
451 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateMemCopy(const MemCopyQueueDescriptor& descriptor,
452  const WorkloadInfo& info) const
453 {
454  if (descriptor.m_Inputs.empty())
455  {
456  throw InvalidArgumentException("RefWorkloadFactory: CreateMemCopy() expected an input tensor.");
457  }
458  return std::make_unique<CopyMemGenericWorkload>(descriptor, info);
459 }
460 
461 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateMemImport(const MemImportQueueDescriptor& descriptor,
462  const WorkloadInfo& info) const
463 {
464  if (descriptor.m_Inputs.empty())
465  {
466  throw InvalidArgumentException("RefWorkloadFactory: CreateMemImport() expected an input tensor.");
467  }
468  return std::make_unique<ImportMemGenericWorkload>(descriptor, info);
469 }
470 
471 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateMerger(const MergerQueueDescriptor& descriptor,
472  const WorkloadInfo& info) const
473 {
474  return CreateConcat(descriptor, info);
475 }
476 
477 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateMinimum(const MinimumQueueDescriptor& descriptor,
478  const WorkloadInfo& info) const
479 {
480  if (info.m_InputTensorInfos[0].GetDataType() == armnn::DataType::Signed32)
481  {
482  return std::make_unique<RefMinimumWorkload<int32_t>>(descriptor, info);
483  }
484  else
485  {
486  return std::make_unique<RefMinimumWorkload<float>>(descriptor, info);
487  }
488 }
489 
490 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateMultiplication(const MultiplicationQueueDescriptor& descriptor,
491  const WorkloadInfo& info) const
492 {
493  if (info.m_InputTensorInfos[0].GetDataType() == armnn::DataType::Signed32)
494  {
495  return std::make_unique<RefMultiplicationWorkload<int32_t>>(descriptor, info);
496  }
497  else
498  {
499  return std::make_unique<RefMultiplicationWorkload<float>>(descriptor, info);
500  }
501 }
502 
503 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateNormalization(const NormalizationQueueDescriptor& descriptor,
504  const WorkloadInfo& info) const
505 {
506  return std::make_unique<RefNormalizationWorkload>(descriptor, info);
507 }
508 
509 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateOutput(const OutputQueueDescriptor& descriptor,
510  const WorkloadInfo& info) const
511 {
512  if (info.m_InputTensorInfos.empty() )
513  {
514  throw InvalidArgumentException("RefWorkloadFactory::CreateOutput: Input cannot be zero length");
515  }
516  if (info.m_OutputTensorInfos.empty())
517  {
518  throw InvalidArgumentException("RefWorkloadFactory::CreateOutput: Output cannot be zero length");
519  }
520  if (info.m_InputTensorInfos[0].GetNumBytes() != info.m_OutputTensorInfos[0].GetNumBytes())
521  {
522  throw InvalidArgumentException("RefWorkloadFactory::CreateOutput: data input and output differ in byte count.");
523  }
524 
525  return std::make_unique<CopyMemGenericWorkload>(descriptor, info);
526 }
527 
528 std::unique_ptr<IWorkload> RefWorkloadFactory::CreatePad(const PadQueueDescriptor& descriptor,
529  const WorkloadInfo& info) const
530 {
531  return std::make_unique<RefPadWorkload>(descriptor, info);
532 }
533 
534 std::unique_ptr<IWorkload> RefWorkloadFactory::CreatePermute(const PermuteQueueDescriptor& descriptor,
535  const WorkloadInfo& info) const
536 {
537  if (IsQSymmS16(info))
538  {
539  return std::make_unique<RefPermuteQSymm16Workload>(descriptor, info);
540  }
541  else if (IsBFloat16(info))
542  {
543  return std::make_unique<RefPermuteBFloat16Workload>(descriptor, info);
544  }
545  else if (IsQAsymmS8(info))
546  {
547  return std::make_unique<RefPermuteQAsymmS8Workload>(descriptor, info);
548  }
550  NullWorkload, NullWorkload, NullWorkload>(descriptor, info);
551 }
552 
553 std::unique_ptr<IWorkload> RefWorkloadFactory::CreatePooling2d(const Pooling2dQueueDescriptor& descriptor,
554  const WorkloadInfo& info) const
555 {
556  return std::make_unique<RefPooling2dWorkload>(descriptor, info);
557 }
558 
559 std::unique_ptr<IWorkload> RefWorkloadFactory::CreatePreCompiled(const PreCompiledQueueDescriptor& /*descriptor*/,
560  const WorkloadInfo& /*info*/) const
561 {
562  return nullptr;
563 }
564 
565 std::unique_ptr<IWorkload> RefWorkloadFactory::CreatePrelu(const PreluQueueDescriptor& descriptor,
566  const WorkloadInfo& info) const
567 {
568  return std::make_unique<RefPreluWorkload>(descriptor, info);
569 }
570 
571 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateQLstm(const QLstmQueueDescriptor& descriptor,
572  const WorkloadInfo& info) const
573 {
574  return std::make_unique<RefQLstmWorkload>(descriptor, info);
575 }
576 
577 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateQuantize(const QuantizeQueueDescriptor& descriptor,
578  const WorkloadInfo& info) const
579 {
580  return std::make_unique<RefQuantizeWorkload>(descriptor, info);
581 }
582 
583 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateRank(const RankQueueDescriptor& descriptor,
584  const WorkloadInfo& info) const
585 {
586  return std::make_unique<RefRankWorkload>(descriptor, info);
587 }
588 
589 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateReduce(const ReduceQueueDescriptor& descriptor,
590  const WorkloadInfo& info) const
591 {
592  return std::make_unique<RefReduceWorkload>(descriptor, info);
593 }
594 
595 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateReshape(const ReshapeQueueDescriptor& descriptor,
596  const WorkloadInfo& info) const
597 {
598  return std::make_unique<RefReshapeWorkload>(descriptor, info);
599 }
600 
601 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateResize(const ResizeQueueDescriptor& descriptor,
602  const WorkloadInfo& info) const
603 {
604  return std::make_unique<RefResizeWorkload>(descriptor, info);
605 }
606 
607 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateResizeBilinear(const ResizeBilinearQueueDescriptor& descriptor,
608  const WorkloadInfo& info) const
609 {
610  ResizeQueueDescriptor resizeDescriptor;
611  resizeDescriptor.m_Parameters.m_Method = ResizeMethod::Bilinear;
612  resizeDescriptor.m_Parameters.m_DataLayout = descriptor.m_Parameters.m_DataLayout;
613  resizeDescriptor.m_Parameters.m_TargetWidth = descriptor.m_Parameters.m_TargetWidth;
614  resizeDescriptor.m_Parameters.m_TargetHeight = descriptor.m_Parameters.m_TargetHeight;
615 
616  return CreateResize(resizeDescriptor, info);
617 }
618 
619 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateRsqrt(const RsqrtQueueDescriptor& descriptor,
620  const WorkloadInfo& info) const
621 {
622  IgnoreUnused(descriptor);
623  ElementwiseUnaryQueueDescriptor elementwiseUnaryDescriptor;
624  elementwiseUnaryDescriptor.m_Parameters.m_Operation = UnaryOperation::Rsqrt;
625 
626  return CreateElementwiseUnary(elementwiseUnaryDescriptor, info);
627 }
628 
629 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateSlice(const SliceQueueDescriptor& descriptor,
630  const WorkloadInfo& info) const
631 {
632  return std::make_unique<RefSliceWorkload>(descriptor, info);
633 }
634 
635 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateSoftmax(const SoftmaxQueueDescriptor& descriptor,
636  const WorkloadInfo& info) const
637 {
638  return std::make_unique<RefSoftmaxWorkload>(descriptor, info);
639 }
640 
641 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateSpaceToBatchNd(const SpaceToBatchNdQueueDescriptor& descriptor,
642  const WorkloadInfo& info) const
643 {
644  return std::make_unique<RefSpaceToBatchNdWorkload>(descriptor, info);
645 }
646 
647 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateSpaceToDepth(const SpaceToDepthQueueDescriptor& descriptor,
648  const WorkloadInfo& info) const
649 {
650  return std::make_unique<RefSpaceToDepthWorkload>(descriptor, info);
651 }
652 
653 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateSplitter(const SplitterQueueDescriptor& descriptor,
654  const WorkloadInfo& info) const
655 {
656  return std::make_unique<RefSplitterWorkload>(descriptor, info);
657 }
658 
659 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateStack(const StackQueueDescriptor& descriptor,
660  const WorkloadInfo& info) const
661 {
662  return std::make_unique<RefStackWorkload>(descriptor, info);
663 }
664 
665 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateStridedSlice(const StridedSliceQueueDescriptor& descriptor,
666  const WorkloadInfo& info) const
667 {
668  return std::make_unique<RefStridedSliceWorkload>(descriptor, info);
669 }
670 
671 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateSubtraction(const SubtractionQueueDescriptor& descriptor,
672  const WorkloadInfo& info) const
673 {
674  if (info.m_InputTensorInfos[0].GetDataType() == armnn::DataType::Signed32)
675  {
676  return std::make_unique<RefSubtractionWorkload<int32_t>>(descriptor, info);
677  }
678  else
679  {
680  return std::make_unique<RefSubtractionWorkload<float>>(descriptor, info);
681  }
682 }
683 
684 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateTranspose(const TransposeQueueDescriptor& descriptor,
685  const WorkloadInfo& info) const
686 {
687  if (IsQSymmS16(info))
688  {
689  return std::make_unique<RefTransposeQSymm16Workload>(descriptor, info);
690  }
691  else if (IsBFloat16(info))
692  {
693  return std::make_unique<RefTransposeBFloat16Workload>(descriptor, info);
694  }
695  else if (IsQAsymmS8(info))
696  {
697  return std::make_unique<RefTransposeQAsymmS8Workload>(descriptor, info);
698  }
700  NullWorkload, NullWorkload, NullWorkload>(descriptor, info);
701 }
702 
704  const TransposeConvolution2dQueueDescriptor& descriptor,
705  const WorkloadInfo& info) const
706 {
707  return std::make_unique<RefTransposeConvolution2dWorkload>(descriptor, info);
708 }
709 
710 } // namespace armnn
std::unique_ptr< IWorkload > CreateMemCopy(const MemCopyQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateRsqrt(const RsqrtQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateNormalization(const NormalizationQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateArgMinMax(const ArgMinMaxQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateReshape(const ReshapeQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateResize(const ResizeQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateFakeQuantization(const FakeQuantizationQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateConvolution2d(const Convolution2dQueueDescriptor &descriptor, const WorkloadInfo &info) const override
UnaryOperation m_Operation
Specifies the elementwiseUnary operation to execute.
std::unique_ptr< IWorkload > CreateConstant(const ConstantQueueDescriptor &descriptor, const WorkloadInfo &info) const override
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
Definition: INetwork.hpp:62
std::unique_ptr< IWorkload > CreateEqual(const EqualQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateInput(const InputQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateMaximum(const MaximumQueueDescriptor &descriptor, const WorkloadInfo &info) const override
DataLayout
Definition: Types.hpp:54
std::unique_ptr< IWorkload > CreateGather(const GatherQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateQuantize(const QuantizeQueueDescriptor &descriptor, const WorkloadInfo &info) const override
constexpr bool IsQuantizedType()
Definition: TypesUtils.hpp:260
std::unique_ptr< IWorkload > CreateTransposeConvolution2d(const TransposeConvolution2dQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateStridedSlice(const StridedSliceQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateConvertFp32ToBf16(const ConvertFp32ToBf16QueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateSoftmax(const SoftmaxQueueDescriptor &descriptor, const WorkloadInfo &info) const override
uint32_t m_TargetWidth
Target width value.
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
constexpr const char * RefBackendId()
std::vector< BackendOptions > ModelOptions
std::unique_ptr< IWorkload > CreateMultiplication(const MultiplicationQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateSpaceToDepth(const SpaceToDepthQueueDescriptor &descriptor, const WorkloadInfo &info) const override
ResizeMethod m_Method
The Interpolation method to use (Bilinear, NearestNeighbor).
std::unique_ptr< IWorkload > CreatePad(const PadQueueDescriptor &descriptor, const WorkloadInfo &info) const override
RefPermuteWorkload< DataType::Float16 > RefPermuteFloat16Workload
RefTransposeWorkload< DataType::Float16 > RefTransposeFloat16Workload
std::unique_ptr< IWorkload > CreateMerger(const MergerQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateComparison(const ComparisonQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateSpaceToBatchNd(const SpaceToBatchNdQueueDescriptor &descriptor, const WorkloadInfo &info) const override
bool IsQAsymmS8(const WorkloadInfo &info)
std::unique_ptr< IWorkload > CreateLogSoftmax(const LogSoftmaxQueueDescriptor &descriptor, const WorkloadInfo &info) const override
RefPermuteWorkload< DataType::Float32 > RefPermuteFloat32Workload
std::unique_ptr< IWorkload > CreateElementwiseUnary(const ElementwiseUnaryQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateConvertFp16ToFp32(const ConvertFp16ToFp32QueueDescriptor &descriptor, const WorkloadInfo &info) const override
Copyright (c) 2021 ARM Limited and Contributors.
std::unique_ptr< IWorkload > CreateRank(const RankQueueDescriptor &descriptor, const WorkloadInfo &info) const override
void IgnoreUnused(Ts &&...)
bool IsQAsymmU8(const WorkloadInfo &info)
bool IsQSymmS8(const WorkloadInfo &info)
bool IsDataType(const WorkloadInfo &info)
bool IsBFloat16(const WorkloadInfo &info)
std::unique_ptr< IWorkload > CreateConvertFp32ToFp16(const ConvertFp32ToFp16QueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateFill(const FillQueueDescriptor &descriptor, const WorkloadInfo &info) const override
const BackendId & GetBackendId() const override
std::unique_ptr< IWorkload > CreateBatchNormalization(const BatchNormalizationQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateL2Normalization(const L2NormalizationQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateLstm(const LstmQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateConcat(const ConcatQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::vector< TensorInfo > m_InputTensorInfos
bool IsFloat16(const WorkloadInfo &info)
std::unique_ptr< IWorkload > CreateSubtraction(const SubtractionQueueDescriptor &descriptor, const WorkloadInfo &info) const override
RefTransposeWorkload< DataType::Float32 > RefTransposeFloat32Workload
std::unique_ptr< IWorkload > CreateReduce(const ReduceQueueDescriptor &descriptor, const WorkloadInfo &info) const override
RefTransposeWorkload< DataType::QAsymmU8 > RefTransposeQAsymm8Workload
static bool IsLayerSupported(const Layer &layer, Optional< DataType > dataType, std::string &outReasonIfUnsupported)
std::unique_ptr< IWorkload > CreateDebug(const DebugQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateAddition(const AdditionQueueDescriptor &descriptor, const WorkloadInfo &info) const override
uint32_t m_TargetWidth
Target width value.
bool IsSigned32(const WorkloadInfo &info)
std::vector< TensorInfo > m_OutputTensorInfos
static bool IsLayerSupported(const BackendId &backendId, const IConnectableLayer &layer, Optional< DataType > dataType, std::string &outReasonIfUnsupported)
std::unique_ptr< IWorkload > CreatePooling2d(const Pooling2dQueueDescriptor &descriptor, const WorkloadInfo &info) const override
uint32_t m_TargetHeight
Target height value.
uint32_t m_TargetHeight
Target height value.
std::unique_ptr< IWorkload > CreatePrelu(const PreluQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateSplitter(const SplitterQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateDequantize(const DequantizeQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateFloor(const FloorQueueDescriptor &descriptor, const WorkloadInfo &info) const override
ComparisonOperation m_Operation
Specifies the comparison operation to execute.
Definition: Descriptors.hpp:94
std::unique_ptr< IWorkload > CreateSlice(const SliceQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateFullyConnected(const FullyConnectedQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateBatchToSpaceNd(const BatchToSpaceNdQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateInstanceNormalization(const InstanceNormalizationQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateMean(const MeanQueueDescriptor &descriptor, const WorkloadInfo &Info) const override
std::unique_ptr< IWorkload > CreateConvertBf16ToFp32(const ConvertBf16ToFp32QueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateStack(const StackQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateDivision(const DivisionQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateGreater(const GreaterQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< ITensorHandle > CreateTensorHandle(const TensorInfo &tensorInfo, const bool IsMemoryManaged=true) const override
std::unique_ptr< IWorkload > CreateLogicalBinary(const LogicalBinaryQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateAbs(const AbsQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateResizeBilinear(const ResizeBilinearQueueDescriptor &descriptor, const WorkloadInfo &info) const override
Contains information about inputs and outputs to a layer.
std::unique_ptr< IWorkload > CreatePermute(const PermuteQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateActivation(const ActivationQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateCast(const CastQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::vector< ITensorHandle * > m_Inputs
RefPermuteWorkload< DataType::QAsymmU8 > RefPermuteQAsymm8Workload
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
std::unique_ptr< IWorkload > CreateMinimum(const MinimumQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateOutput(const OutputQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreatePreCompiled(const PreCompiledQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateTranspose(const TransposeQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateDetectionPostProcess(const DetectionPostProcessQueueDescriptor &descriptor, const WorkloadInfo &info) const override
bool IsQSymmS16(const WorkloadInfo &info)
std::unique_ptr< IWorkload > CreateDepthwiseConvolution2d(const DepthwiseConvolution2dQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateQLstm(const QLstmQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateMemImport(const MemImportQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateDepthToSpace(const DepthToSpaceQueueDescriptor &descriptor, const WorkloadInfo &info) const override