ArmNN
 20.08
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 
106 std::unique_ptr<ITensorHandle> RefWorkloadFactory::CreateTensorHandle(const TensorInfo& tensorInfo,
107  const bool isMemoryManaged) const
108 {
109  // For Ref it is okay to make the TensorHandle memory managed as it can also store a pointer
110  // to unmanaged memory. This also ensures memory alignment.
111  IgnoreUnused(isMemoryManaged);
112  return std::make_unique<RefTensorHandle>(tensorInfo, m_MemoryManager);
113 }
114 
115 std::unique_ptr<ITensorHandle> RefWorkloadFactory::CreateTensorHandle(const TensorInfo& tensorInfo,
116  DataLayout dataLayout,
117  const bool isMemoryManaged) const
118 {
119  // For Ref it is okay to make the TensorHandle memory managed as it can also store a pointer
120  // to unmanaged memory. This also ensures memory alignment.
121  IgnoreUnused(isMemoryManaged, dataLayout);
122  return std::make_unique<RefTensorHandle>(tensorInfo, m_MemoryManager);
123 }
124 
125 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateAbs(const AbsQueueDescriptor& descriptor,
126  const WorkloadInfo& info) const
127 {
128  IgnoreUnused(descriptor);
129  ElementwiseUnaryQueueDescriptor elementwiseUnaryDescriptor;
130  elementwiseUnaryDescriptor.m_Parameters.m_Operation = UnaryOperation::Abs;
131 
132  return CreateElementwiseUnary(elementwiseUnaryDescriptor, info);
133 }
134 
135 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateActivation(const ActivationQueueDescriptor& descriptor,
136  const WorkloadInfo& info) const
137 {
138  return std::make_unique<RefActivationWorkload>(descriptor, info);
139 }
140 
141 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateAddition(const AdditionQueueDescriptor& descriptor,
142  const WorkloadInfo& info) const
143 {
144  if (info.m_InputTensorInfos[0].GetDataType() == armnn::DataType::Signed32)
145  {
146  return std::make_unique<RefAdditionWorkload<int32_t>>(descriptor, info);
147  }
148  else
149  {
150  return std::make_unique<RefAdditionWorkload<float>>(descriptor, info);
151  }
152 }
153 
154 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateArgMinMax(const ArgMinMaxQueueDescriptor& descriptor,
155  const WorkloadInfo& info) const
156 {
157  return std::make_unique<RefArgMinMaxWorkload>(descriptor, info);
158 }
159 
161  const BatchNormalizationQueueDescriptor& descriptor,
162  const WorkloadInfo& info) const
163 {
164  return std::make_unique<RefBatchNormalizationWorkload>(descriptor, info);
165 }
166 
167 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateBatchToSpaceNd(const BatchToSpaceNdQueueDescriptor& descriptor,
168  const WorkloadInfo& info) const
169 {
170  return std::make_unique<RefBatchToSpaceNdWorkload>(descriptor, info);
171 }
172 
173 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateComparison(const ComparisonQueueDescriptor& descriptor,
174  const WorkloadInfo& info) const
175 {
176  return std::make_unique<RefComparisonWorkload>(descriptor, info);
177 }
178 
179 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateConcat(const ConcatQueueDescriptor& descriptor,
180  const WorkloadInfo& info) const
181 {
182  return std::make_unique<RefConcatWorkload>(descriptor, info);
183 }
184 
185 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateConstant(const ConstantQueueDescriptor& descriptor,
186  const WorkloadInfo& info) const
187 {
188  return std::make_unique<RefConstantWorkload>(descriptor, info);
189 }
190 
192  const ConvertBf16ToFp32QueueDescriptor& descriptor,
193  const WorkloadInfo& info) const
194 {
195  return std::make_unique<RefConvertBf16ToFp32Workload>(descriptor, info);
196 }
197 
199  const ConvertFp16ToFp32QueueDescriptor& descriptor,
200  const WorkloadInfo& info) const
201 {
202  return std::make_unique<RefConvertFp16ToFp32Workload>(descriptor, info);
203 }
204 
206  const ConvertFp32ToBf16QueueDescriptor& descriptor,
207  const WorkloadInfo& info) const
208 {
209  return std::make_unique<RefConvertFp32ToBf16Workload>(descriptor, info);
210 }
211 
213  const ConvertFp32ToFp16QueueDescriptor& descriptor,
214  const WorkloadInfo& info) const
215 {
216  return std::make_unique<RefConvertFp32ToFp16Workload>(descriptor, info);
217 }
218 
219 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateConvolution2d(const Convolution2dQueueDescriptor& descriptor,
220  const WorkloadInfo& info) const
221 {
222  return std::make_unique<RefConvolution2dWorkload>(descriptor, info);
223 }
224 
225 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateDebug(const DebugQueueDescriptor& descriptor,
226  const WorkloadInfo& info) const
227 {
228  if (IsBFloat16(info))
229  {
230  return std::make_unique<RefDebugBFloat16Workload>(descriptor, info);
231  }
232  if (IsFloat16(info))
233  {
234  return std::make_unique<RefDebugFloat16Workload>(descriptor, info);
235  }
236  if (IsQSymmS16(info))
237  {
238  return std::make_unique<RefDebugQSymmS16Workload>(descriptor, info);
239  }
240  if (IsQSymmS8(info))
241  {
242  return std::make_unique<RefDebugQSymmS8Workload>(descriptor, info);
243  }
244  if (IsQAsymmU8(info))
245  {
246  return std::make_unique<RefDebugQAsymmU8Workload>(descriptor, info);
247  }
248  if (IsQAsymmS8(info))
249  {
250  return std::make_unique<RefDebugQAsymmS8Workload>(descriptor, info);
251  }
252  if (IsSigned32(info))
253  {
254  return std::make_unique<RefDebugSigned32Workload>(descriptor, info);
255  }
256 
257  return MakeWorkload<RefDebugFloat32Workload, RefDebugQAsymmU8Workload>(descriptor, info);
258 }
259 
260 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateDepthToSpace(const DepthToSpaceQueueDescriptor& descriptor,
261  const WorkloadInfo& info) const
262 {
263  return std::make_unique<RefDepthToSpaceWorkload>(descriptor, info);
264 }
265 
267  const DepthwiseConvolution2dQueueDescriptor& descriptor,
268  const WorkloadInfo& info) const
269 {
270  return std::make_unique<RefDepthwiseConvolution2dWorkload>(descriptor, info);
271 }
272 
273 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateDequantize(const DequantizeQueueDescriptor& descriptor,
274  const WorkloadInfo& info) const
275 {
276  return std::make_unique<RefDequantizeWorkload>(descriptor, info);
277 }
278 
280  const DetectionPostProcessQueueDescriptor& descriptor,
281  const WorkloadInfo& info) const
282 {
283  return std::make_unique<RefDetectionPostProcessWorkload>(descriptor, info);
284 }
285 
286 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateDivision(const DivisionQueueDescriptor& descriptor,
287  const WorkloadInfo& info) const
288 {
289  if (info.m_InputTensorInfos[0].GetDataType() == armnn::DataType::Signed32)
290  {
291  return std::make_unique<RefDivisionWorkload<int32_t>>(descriptor, info);
292  }
293  else
294  {
295  return std::make_unique<RefDivisionWorkload<float>>(descriptor, info);
296  }
297 }
298 
300  const WorkloadInfo& info) const
301 {
302  return std::make_unique<RefElementwiseUnaryWorkload>(descriptor, info);
303 }
304 
305 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateEqual(const EqualQueueDescriptor& descriptor,
306  const WorkloadInfo& info) const
307 {
308  IgnoreUnused(descriptor);
309  ComparisonQueueDescriptor comparisonDescriptor;
310  comparisonDescriptor.m_Parameters.m_Operation = ComparisonOperation::Equal;
311 
312  return CreateComparison(comparisonDescriptor, info);
313 }
314 
316  const WorkloadInfo& info) const
317 {
318  return MakeWorkload<RefFakeQuantizationFloat32Workload, NullWorkload>(descriptor, info);
319 }
320 
321 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateFill(const FillQueueDescriptor& descriptor,
322  const WorkloadInfo& info) const
323 {
324  return std::make_unique<RefFillWorkload>(descriptor, info);
325 }
326 
327 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateFloor(const FloorQueueDescriptor& descriptor,
328  const WorkloadInfo& info) const
329 {
330  if(IsQuantizedType(info.m_InputTensorInfos[0].GetDataType()))
331  {
332  return nullptr;
333  }
334  else
335  {
336  return std::make_unique<RefFloorWorkload>(descriptor, info);
337  }
338 }
339 
340 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateFullyConnected(
341  const FullyConnectedQueueDescriptor& descriptor,
342  const WorkloadInfo& info) const
343 {
344  return std::make_unique<RefFullyConnectedWorkload>(descriptor, info);
345 }
346 
347 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateGather(const GatherQueueDescriptor& descriptor,
348  const WorkloadInfo& info) const
349 {
350  return std::make_unique<RefGatherWorkload>(descriptor, info);
351 }
352 
353 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateGreater(const GreaterQueueDescriptor& descriptor,
354  const WorkloadInfo& info) const
355 {
356  IgnoreUnused(descriptor);
357  ComparisonQueueDescriptor comparisonDescriptor;
359 
360  return CreateComparison(comparisonDescriptor, info);
361 }
362 
363 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateInput(const InputQueueDescriptor& descriptor,
364  const WorkloadInfo& info) const
365 {
366  if (info.m_InputTensorInfos.empty() )
367  {
368  throw InvalidArgumentException("RefWorkloadFactory::CreateInput: Input cannot be zero length");
369  }
370  if (info.m_OutputTensorInfos.empty())
371  {
372  throw InvalidArgumentException("RefWorkloadFactory::CreateInput: Output cannot be zero length");
373  }
374 
375  if (info.m_InputTensorInfos[0].GetNumBytes() != info.m_OutputTensorInfos[0].GetNumBytes())
376  {
377  throw InvalidArgumentException("RefWorkloadFactory::CreateInput: data input and output differ in byte count.");
378  }
379 
380  return std::make_unique<CopyMemGenericWorkload>(descriptor, info);
381 }
382 
384  const InstanceNormalizationQueueDescriptor& descriptor,
385  const WorkloadInfo& info) const
386 {
387  return std::make_unique<RefInstanceNormalizationWorkload>(descriptor, info);
388 }
389 
391  const WorkloadInfo& info) const
392 {
393  return std::make_unique<RefL2NormalizationWorkload>(descriptor, info);
394 }
395 
396 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateLogSoftmax(const LogSoftmaxQueueDescriptor& descriptor,
397  const WorkloadInfo& info) const
398 {
399  return std::make_unique<RefLogSoftmaxWorkload>(descriptor, info);
400 }
401 
402 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateLstm(const LstmQueueDescriptor& descriptor,
403  const WorkloadInfo& info) const
404 {
405  return std::make_unique<RefLstmWorkload>(descriptor, info);
406 }
407 
408 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateMaximum(const MaximumQueueDescriptor& descriptor,
409  const WorkloadInfo& info) const
410 {
411  if (info.m_InputTensorInfos[0].GetDataType() == armnn::DataType::Signed32)
412  {
413  return std::make_unique<RefMaximumWorkload<int32_t>>(descriptor, info);
414  }
415  else
416  {
417  return std::make_unique<RefMaximumWorkload<float>>(descriptor, info);
418  }
419 }
420 
421 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateMean(const MeanQueueDescriptor& descriptor,
422  const WorkloadInfo& info) const
423 {
424  return std::make_unique<RefMeanWorkload>(descriptor, info);
425 }
426 
427 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateMemCopy(const MemCopyQueueDescriptor& descriptor,
428  const WorkloadInfo& info) const
429 {
430  if (descriptor.m_Inputs.empty())
431  {
432  throw InvalidArgumentException("RefWorkloadFactory: CreateMemCopy() expected an input tensor.");
433  }
434  return std::make_unique<CopyMemGenericWorkload>(descriptor, info);
435 }
436 
437 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateMemImport(const MemImportQueueDescriptor& descriptor,
438  const WorkloadInfo& info) const
439 {
440  if (descriptor.m_Inputs.empty())
441  {
442  throw InvalidArgumentException("RefWorkloadFactory: CreateMemImport() expected an input tensor.");
443  }
444  return std::make_unique<ImportMemGenericWorkload>(descriptor, info);
445 }
446 
447 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateMerger(const MergerQueueDescriptor& descriptor,
448  const WorkloadInfo& info) const
449 {
450  return CreateConcat(descriptor, info);
451 }
452 
453 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateMinimum(const MinimumQueueDescriptor& descriptor,
454  const WorkloadInfo& info) const
455 {
456  if (info.m_InputTensorInfos[0].GetDataType() == armnn::DataType::Signed32)
457  {
458  return std::make_unique<RefMinimumWorkload<int32_t>>(descriptor, info);
459  }
460  else
461  {
462  return std::make_unique<RefMinimumWorkload<float>>(descriptor, info);
463  }
464 }
465 
466 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateMultiplication(const MultiplicationQueueDescriptor& descriptor,
467  const WorkloadInfo& info) const
468 {
469  if (info.m_InputTensorInfos[0].GetDataType() == armnn::DataType::Signed32)
470  {
471  return std::make_unique<RefMultiplicationWorkload<int32_t>>(descriptor, info);
472  }
473  else
474  {
475  return std::make_unique<RefMultiplicationWorkload<float>>(descriptor, info);
476  }
477 }
478 
479 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateNormalization(const NormalizationQueueDescriptor& descriptor,
480  const WorkloadInfo& info) const
481 {
482  return std::make_unique<RefNormalizationWorkload>(descriptor, info);
483 }
484 
485 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateOutput(const OutputQueueDescriptor& descriptor,
486  const WorkloadInfo& info) const
487 {
488  if (info.m_InputTensorInfos.empty() )
489  {
490  throw InvalidArgumentException("RefWorkloadFactory::CreateOutput: Input cannot be zero length");
491  }
492  if (info.m_OutputTensorInfos.empty())
493  {
494  throw InvalidArgumentException("RefWorkloadFactory::CreateOutput: Output cannot be zero length");
495  }
496  if (info.m_InputTensorInfos[0].GetNumBytes() != info.m_OutputTensorInfos[0].GetNumBytes())
497  {
498  throw InvalidArgumentException("RefWorkloadFactory::CreateOutput: data input and output differ in byte count.");
499  }
500 
501  return std::make_unique<CopyMemGenericWorkload>(descriptor, info);
502 }
503 
504 std::unique_ptr<IWorkload> RefWorkloadFactory::CreatePad(const PadQueueDescriptor& descriptor,
505  const WorkloadInfo& info) const
506 {
507  return std::make_unique<RefPadWorkload>(descriptor, info);
508 }
509 
510 std::unique_ptr<IWorkload> RefWorkloadFactory::CreatePermute(const PermuteQueueDescriptor& descriptor,
511  const WorkloadInfo& info) const
512 {
513  if (IsQSymmS16(info))
514  {
515  return std::make_unique<RefPermuteQSymm16Workload>(descriptor, info);
516  }
517  else if (IsBFloat16(info))
518  {
519  return std::make_unique<RefPermuteBFloat16Workload>(descriptor, info);
520  }
521  else if (IsQAsymmS8(info))
522  {
523  return std::make_unique<RefPermuteQAsymmS8Workload>(descriptor, info);
524  }
526  NullWorkload, NullWorkload, NullWorkload>(descriptor, info);
527 }
528 
529 std::unique_ptr<IWorkload> RefWorkloadFactory::CreatePooling2d(const Pooling2dQueueDescriptor& descriptor,
530  const WorkloadInfo& info) const
531 {
532  return std::make_unique<RefPooling2dWorkload>(descriptor, info);
533 }
534 
535 std::unique_ptr<IWorkload> RefWorkloadFactory::CreatePreCompiled(const PreCompiledQueueDescriptor& /*descriptor*/,
536  const WorkloadInfo& /*info*/) const
537 {
538  return nullptr;
539 }
540 
541 std::unique_ptr<IWorkload> RefWorkloadFactory::CreatePrelu(const PreluQueueDescriptor& descriptor,
542  const WorkloadInfo& info) const
543 {
544  return std::make_unique<RefPreluWorkload>(descriptor, info);
545 }
546 
547 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateQLstm(const QLstmQueueDescriptor& descriptor,
548  const WorkloadInfo& info) const
549 {
550  return std::make_unique<RefQLstmWorkload>(descriptor, info);
551 }
552 
553 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateQuantize(const QuantizeQueueDescriptor& descriptor,
554  const WorkloadInfo& info) const
555 {
556  return std::make_unique<RefQuantizeWorkload>(descriptor, info);
557 }
558 
559 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateRank(const RankQueueDescriptor& descriptor,
560  const WorkloadInfo& info) const
561 {
562  return std::make_unique<RefRankWorkload>(descriptor, info);
563 }
564 
565 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateReshape(const ReshapeQueueDescriptor& descriptor,
566  const WorkloadInfo& info) const
567 {
568  return std::make_unique<RefReshapeWorkload>(descriptor, info);
569 }
570 
571 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateResize(const ResizeQueueDescriptor& descriptor,
572  const WorkloadInfo& info) const
573 {
574  return std::make_unique<RefResizeWorkload>(descriptor, info);
575 }
576 
577 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateResizeBilinear(const ResizeBilinearQueueDescriptor& descriptor,
578  const WorkloadInfo& info) const
579 {
580  ResizeQueueDescriptor resizeDescriptor;
581  resizeDescriptor.m_Parameters.m_Method = ResizeMethod::Bilinear;
582  resizeDescriptor.m_Parameters.m_DataLayout = descriptor.m_Parameters.m_DataLayout;
583  resizeDescriptor.m_Parameters.m_TargetWidth = descriptor.m_Parameters.m_TargetWidth;
584  resizeDescriptor.m_Parameters.m_TargetHeight = descriptor.m_Parameters.m_TargetHeight;
585 
586  return CreateResize(resizeDescriptor, info);
587 }
588 
589 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateRsqrt(const RsqrtQueueDescriptor& descriptor,
590  const WorkloadInfo& info) const
591 {
592  IgnoreUnused(descriptor);
593  ElementwiseUnaryQueueDescriptor elementwiseUnaryDescriptor;
594  elementwiseUnaryDescriptor.m_Parameters.m_Operation = UnaryOperation::Rsqrt;
595 
596  return CreateElementwiseUnary(elementwiseUnaryDescriptor, info);
597 }
598 
599 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateSlice(const SliceQueueDescriptor& descriptor,
600  const WorkloadInfo& info) const
601 {
602  return std::make_unique<RefSliceWorkload>(descriptor, info);
603 }
604 
605 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateSoftmax(const SoftmaxQueueDescriptor& descriptor,
606  const WorkloadInfo& info) const
607 {
608  return std::make_unique<RefSoftmaxWorkload>(descriptor, info);
609 }
610 
611 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateSpaceToBatchNd(const SpaceToBatchNdQueueDescriptor& descriptor,
612  const WorkloadInfo& info) const
613 {
614  return std::make_unique<RefSpaceToBatchNdWorkload>(descriptor, info);
615 }
616 
617 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateSpaceToDepth(const SpaceToDepthQueueDescriptor& descriptor,
618  const WorkloadInfo& info) const
619 {
620  return std::make_unique<RefSpaceToDepthWorkload>(descriptor, info);
621 }
622 
623 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateSplitter(const SplitterQueueDescriptor& descriptor,
624  const WorkloadInfo& info) const
625 {
626  return std::make_unique<RefSplitterWorkload>(descriptor, info);
627 }
628 
629 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateStack(const StackQueueDescriptor& descriptor,
630  const WorkloadInfo& info) const
631 {
632  return std::make_unique<RefStackWorkload>(descriptor, info);
633 }
634 
635 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateStridedSlice(const StridedSliceQueueDescriptor& descriptor,
636  const WorkloadInfo& info) const
637 {
638  return std::make_unique<RefStridedSliceWorkload>(descriptor, info);
639 }
640 
641 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateSubtraction(const SubtractionQueueDescriptor& descriptor,
642  const WorkloadInfo& info) const
643 {
644  if (info.m_InputTensorInfos[0].GetDataType() == armnn::DataType::Signed32)
645  {
646  return std::make_unique<RefSubtractionWorkload<int32_t>>(descriptor, info);
647  }
648  else
649  {
650  return std::make_unique<RefSubtractionWorkload<float>>(descriptor, info);
651  }
652 }
653 
654 std::unique_ptr<IWorkload> RefWorkloadFactory::CreateTranspose(const TransposeQueueDescriptor& descriptor,
655  const WorkloadInfo& info) const
656 {
657  if (IsQSymmS16(info))
658  {
659  return std::make_unique<RefTransposeQSymm16Workload>(descriptor, info);
660  }
661  else if (IsBFloat16(info))
662  {
663  return std::make_unique<RefTransposeBFloat16Workload>(descriptor, info);
664  }
665  else if (IsQAsymmS8(info))
666  {
667  return std::make_unique<RefTransposeQAsymmS8Workload>(descriptor, info);
668  }
670  NullWorkload, NullWorkload, NullWorkload>(descriptor, info);
671 }
672 
674  const TransposeConvolution2dQueueDescriptor& descriptor,
675  const WorkloadInfo& info) const
676 {
677  return std::make_unique<RefTransposeConvolution2dWorkload>(descriptor, info);
678 }
679 
680 } // 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
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:49
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:236
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::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) 2020 ARM Limited.
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
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:86
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 > 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::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