ArmNN
 20.11
NeonWorkloadFactory.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "NeonBackendId.hpp"
8 #include "NeonTensorHandle.hpp"
10 
11 #include <Layer.hpp>
12 
13 #include <armnn/Utils.hpp>
17 
22 
25 
26 namespace armnn
27 {
28 
29 namespace
30 {
31 static const BackendId s_Id{NeonBackendId()};
32 }
33 
35  Optional<DataType> dataType,
36  std::string& outReasonIfUnsupported)
37 {
38  return IWorkloadFactory::IsLayerSupported(s_Id, layer, dataType, outReasonIfUnsupported);
39 }
40 
42  Optional<DataType> dataType,
43  std::string& outReasonIfUnsupported,
44  const ModelOptions& modelOptions)
45 {
46  return IWorkloadFactory::IsLayerSupported(s_Id, layer, dataType, outReasonIfUnsupported, modelOptions);
47 }
48 
50 {
51  return s_Id;
52 }
53 
54 NeonWorkloadFactory::NeonWorkloadFactory(const std::shared_ptr<NeonMemoryManager>& memoryManager)
55  : m_MemoryManager(memoryManager), m_ModelContextPtr(IBackendInternal::IBackendSpecificModelContextPtr{})
56 {
57 }
58 
59 NeonWorkloadFactory::NeonWorkloadFactory(const std::shared_ptr<NeonMemoryManager>& memoryManager,
61  : m_MemoryManager(memoryManager), m_ModelContextPtr(modelContextPtr)
62 {
63 }
64 
65 std::unique_ptr<ITensorHandle> NeonWorkloadFactory::CreateSubTensorHandle(ITensorHandle& parent,
66  TensorShape const& subTensorShape,
67  unsigned int const* subTensorOrigin) const
68 {
69  const arm_compute::TensorShape shape = armcomputetensorutils::BuildArmComputeTensorShape(subTensorShape);
70 
72  coords.set_num_dimensions(subTensorShape.GetNumDimensions());
73  for (unsigned int i = 0; i < subTensorShape.GetNumDimensions(); i++)
74  {
75  // Arm compute indexes tensor coords in reverse order.
76  unsigned int revertedIndex = subTensorShape.GetNumDimensions() - i - 1;
77  coords.set(i, armnn::numeric_cast<int>(subTensorOrigin[revertedIndex]));
78  }
79 
80  const arm_compute::TensorShape parentShape = armcomputetensorutils::BuildArmComputeTensorShape(parent.GetShape());
81  if (!::arm_compute::error_on_invalid_subtensor(__func__, __FILE__, __LINE__, parentShape, coords, shape))
82  {
83  return nullptr;
84  }
85 
86  return std::make_unique<NeonSubTensorHandle>(
87  PolymorphicDowncast<IAclTensorHandle*>(&parent), shape, coords);
88 }
89 
90 std::unique_ptr<ITensorHandle> NeonWorkloadFactory::CreateTensorHandle(const TensorInfo& tensorInfo,
91  const bool IsMemoryManaged) const
92 {
93  auto tensorHandle = std::make_unique<NeonTensorHandle>(tensorInfo);
94  if (IsMemoryManaged)
95  {
96  tensorHandle->SetMemoryGroup(m_MemoryManager->GetInterLayerMemoryGroup());
97  }
98  return tensorHandle;
99 }
100 
101 std::unique_ptr<ITensorHandle> NeonWorkloadFactory::CreateTensorHandle(const TensorInfo& tensorInfo,
102  DataLayout dataLayout,
103  const bool IsMemoryManaged) const
104 {
105  auto tensorHandle = std::make_unique<NeonTensorHandle>(tensorInfo, dataLayout);
106  if (IsMemoryManaged)
107  {
108  tensorHandle->SetMemoryGroup(m_MemoryManager->GetInterLayerMemoryGroup());
109  }
110  return tensorHandle;
111 }
112 
113 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateAbs(const AbsQueueDescriptor& descriptor,
114  const WorkloadInfo& info) const
115 {
116  IgnoreUnused(descriptor);
117 
118  ElementwiseUnaryQueueDescriptor elementwiseUnaryDescriptor;
119  elementwiseUnaryDescriptor.m_Parameters = ElementwiseUnaryDescriptor(UnaryOperation::Abs);
120 
121  return CreateElementwiseUnary(elementwiseUnaryDescriptor, info);
122 }
123 
124 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateActivation(const ActivationQueueDescriptor& descriptor,
125  const WorkloadInfo& info) const
126 {
127  return std::make_unique<NeonActivationWorkload>(descriptor, info);
128 }
129 
130 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateAddition(const AdditionQueueDescriptor& descriptor,
131  const WorkloadInfo& info) const
132 {
133  return std::make_unique<NeonAdditionWorkload>(descriptor, info);
134 }
135 
136 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateArgMinMax(const ArgMinMaxQueueDescriptor& descriptor,
137  const WorkloadInfo& info) const
138 {
139  return std::make_unique<NeonArgMinMaxWorkload>(descriptor, info);
140 }
141 
142 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateBatchNormalization(
143  const BatchNormalizationQueueDescriptor& descriptor, const WorkloadInfo& info) const
144 {
145  return std::make_unique<NeonBatchNormalizationWorkload>(descriptor, info);
146 }
147 
149  const WorkloadInfo& info) const
150 {
151  return std::make_unique<NeonBatchToSpaceNdWorkload>(descriptor, info);
152 }
153 
154 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateComparison(const ComparisonQueueDescriptor& descriptor,
155  const WorkloadInfo& info) const
156 {
157  return std::make_unique<NeonComparisonWorkload>(descriptor, info);
158 }
159 
160 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateConcat(const ConcatQueueDescriptor& descriptor,
161  const WorkloadInfo& info) const
162 {
163  return std::make_unique<NeonConcatWorkload>(descriptor, info);
164 }
165 
166 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateConstant(const ConstantQueueDescriptor& descriptor,
167  const WorkloadInfo& info) const
168 {
169  return std::make_unique<NeonConstantWorkload>(descriptor, info);
170 }
171 
173  const ConvertBf16ToFp32QueueDescriptor& descriptor,
174  const WorkloadInfo& info) const
175 {
176  return std::make_unique<NeonConvertBf16ToFp32Workload>(descriptor, info);
177 }
178 
180  const ConvertFp16ToFp32QueueDescriptor& descriptor,
181  const WorkloadInfo& info) const
182 {
183  return std::make_unique<NeonConvertFp16ToFp32Workload>(descriptor, info);
184 }
185 
187  const ConvertFp32ToBf16QueueDescriptor& descriptor,
188  const WorkloadInfo& info) const
189 {
190  return std::make_unique<NeonConvertFp32ToBf16Workload>(descriptor, info);
191 }
192 
194  const ConvertFp32ToFp16QueueDescriptor& descriptor,
195  const WorkloadInfo& info) const
196 {
197  return std::make_unique<NeonConvertFp32ToFp16Workload>(descriptor, info);
198 }
199 
200 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateConvolution2d(
201  const Convolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) const
202 {
203  bool isFastMathEnabled = false;
204  if (m_ModelContextPtr)
205  {
206  if (m_ModelContextPtr.get() != nullptr)
207  {
208  auto modelOptions = dynamic_cast<NeonBackendModelContext*>(m_ModelContextPtr.get());
209  if (modelOptions)
210  {
211  isFastMathEnabled = modelOptions->IsFastMathEnabled();
212  }
213  }
214  }
215  return std::make_unique<NeonConvolution2dWorkload>(descriptor,
216  info,
217  m_MemoryManager->GetIntraLayerManager(),
218  isFastMathEnabled);
219 }
220 
221 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateDebug(const DebugQueueDescriptor& descriptor,
222  const WorkloadInfo& info) const
223 {
224  return MakeWorkloadHelper<NullWorkload, NullWorkload>(descriptor, info);
225 }
226 
227 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateDepthToSpace(const DepthToSpaceQueueDescriptor& descriptor,
228  const WorkloadInfo& info) const
229 {
230  return std::make_unique<NeonDepthToSpaceWorkload>(descriptor, info);
231 }
232 
234  const DepthwiseConvolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) const
235 {
236  return std::make_unique<NeonDepthwiseConvolutionWorkload>(descriptor, info);
237 }
238 
239 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateDequantize(const DequantizeQueueDescriptor& descriptor,
240  const WorkloadInfo& info) const
241 {
242  return std::make_unique<NeonDequantizeWorkload>(descriptor, info);
243 }
244 
247 {
248  return MakeWorkloadHelper<NullWorkload, NullWorkload>(descriptor, info);
249 }
250 
251 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateDivision(
252  const DivisionQueueDescriptor& descriptor, const WorkloadInfo& info) const
253 {
254  return std::make_unique<NeonDivisionWorkload>(descriptor, info);
255 }
256 
258  const ElementwiseUnaryQueueDescriptor& descriptor, const WorkloadInfo& info) const
259 {
260  switch(descriptor.m_Parameters.m_Operation)
261  {
262  case UnaryOperation::Abs:
263  {
264  AbsQueueDescriptor absQueueDescriptor;
265  absQueueDescriptor.m_Inputs = descriptor.m_Inputs;
266  absQueueDescriptor.m_Outputs = descriptor.m_Outputs;
267 
268  return std::make_unique<NeonAbsWorkload>(absQueueDescriptor, info);
269  }
271  {
272  RsqrtQueueDescriptor rsqrtQueueDescriptor;
273  rsqrtQueueDescriptor.m_Inputs = descriptor.m_Inputs;
274  rsqrtQueueDescriptor.m_Outputs = descriptor.m_Outputs;
275 
276  return std::make_unique<NeonRsqrtWorkload>(rsqrtQueueDescriptor, info);
277  }
278  case UnaryOperation::Neg:
279  return std::make_unique<NeonNegWorkload>(descriptor, info);
280  case UnaryOperation::Exp:
281  return std::make_unique<NeonExpWorkload>(descriptor, info);
283  return std::make_unique<NeonLogicalNotWorkload>(descriptor, info);
284  default:
285  return nullptr;
286  }
287 }
288 
289 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateEqual(const EqualQueueDescriptor& descriptor,
290  const WorkloadInfo& info) const
291 {
292  IgnoreUnused(descriptor);
293 
294  ComparisonQueueDescriptor comparisonDescriptor;
296 
297  return CreateComparison(comparisonDescriptor, info);
298 }
299 
300 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateFill(const FillQueueDescriptor& descriptor,
301  const WorkloadInfo& info) const
302 {
303  return std::make_unique<NeonFillWorkload>(descriptor, info);
304 }
305 
306 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateFloor(const FloorQueueDescriptor& descriptor,
307  const WorkloadInfo& info) const
308 {
309  return MakeWorkloadHelper<NeonFloorFloatWorkload, NullWorkload>(descriptor, info);
310 }
311 
312 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateFullyConnected(
313  const FullyConnectedQueueDescriptor& descriptor, const WorkloadInfo& info) const
314 {
315  return std::make_unique<NeonFullyConnectedWorkload>(descriptor, info, m_MemoryManager->GetIntraLayerManager());
316 }
317 
318 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateGather(const armnn::GatherQueueDescriptor& descriptor,
319  const armnn::WorkloadInfo& info) const
320 {
321  return std::make_unique<NeonGatherWorkload>(descriptor, info);
322 }
323 
324 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateGreater(const GreaterQueueDescriptor& descriptor,
325  const WorkloadInfo& info) const
326 {
327  IgnoreUnused(descriptor);
328 
329  ComparisonQueueDescriptor comparisonDescriptor;
331 
332  return CreateComparison(comparisonDescriptor, info);
333 }
334 
335 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateInput(const InputQueueDescriptor& descriptor,
336  const WorkloadInfo& info) const
337 {
338  return std::make_unique<CopyMemGenericWorkload>(descriptor, info);
339 }
340 
342  const InstanceNormalizationQueueDescriptor& descriptor,
343  const WorkloadInfo& info) const
344 {
345  return std::make_unique<NeonInstanceNormalizationWorkload>(descriptor, info);
346 }
347 
349  const WorkloadInfo& info) const
350 {
351  return MakeWorkloadHelper<NeonL2NormalizationFloatWorkload, NullWorkload>(descriptor, info,
352  m_MemoryManager->GetIntraLayerManager());
353 }
354 
355 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateLogSoftmax(const LogSoftmaxQueueDescriptor& descriptor,
356  const WorkloadInfo& info) const
357 {
358  return std::make_unique<NeonLogSoftmaxWorkload>(descriptor, info, m_MemoryManager->GetIntraLayerManager());
359 }
360 
361 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateLogicalBinary(const LogicalBinaryQueueDescriptor& descriptor,
362  const WorkloadInfo& info) const
363 {
364  switch(descriptor.m_Parameters.m_Operation)
365  {
367  return std::make_unique<NeonLogicalAndWorkload>(descriptor, info);
369  return std::make_unique<NeonLogicalOrWorkload>(descriptor, info);
370  default:
371  return nullptr;
372  }
373 }
374 
376  const WorkloadInfo& info) const
377 {
378  switch(descriptor.m_Parameters.m_Operation)
379  {
381  return std::make_unique<NeonLogicalNotWorkload>(descriptor, info);
382  default:
383  return nullptr;
384  }
385 }
386 
387 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateLstm(const LstmQueueDescriptor& descriptor,
388  const WorkloadInfo& info) const
389 {
390  return MakeWorkloadHelper<NeonLstmFloatWorkload, NullWorkload>(descriptor, info);
391 }
392 
393 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateMaximum(const MaximumQueueDescriptor& descriptor,
394  const WorkloadInfo& info) const
395 {
396  return std::make_unique<NeonMaximumWorkload>(descriptor, info);
397 }
398 
399 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateMean(const MeanQueueDescriptor& descriptor,
400  const WorkloadInfo& info) const
401 {
402  return std::make_unique<NeonMeanWorkload>(descriptor, info);
403 }
404 
405 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateMemCopy(const MemCopyQueueDescriptor& descriptor,
406  const WorkloadInfo& info) const
407 {
408  if (descriptor.m_Inputs.empty() || !descriptor.m_Inputs[0])
409  {
410  throw InvalidArgumentException("NeonWorkloadFactory: Invalid null input for MemCopy workload");
411  }
412 
413  return MakeWorkloadHelper<CopyMemGenericWorkload, CopyMemGenericWorkload>(descriptor, info);
414 }
415 
416 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateMemImport(const MemImportQueueDescriptor& descriptor,
417  const WorkloadInfo& info) const
418 {
419  if (descriptor.m_Inputs.empty() || !descriptor.m_Inputs[0])
420  {
421  throw InvalidArgumentException("NeonWorkloadFactory: Invalid null input for MemImport workload");
422  }
423 
424  return std::make_unique<ImportMemGenericWorkload>(descriptor, info);
425 }
426 
427 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateMerger(const MergerQueueDescriptor& descriptor,
428  const WorkloadInfo& info) const
429 {
430  return CreateConcat(descriptor, info);
431 }
432 
433 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateMinimum(const MinimumQueueDescriptor& descriptor,
434  const WorkloadInfo& info) const
435 {
436  return std::make_unique<NeonMinimumWorkload>(descriptor, info);
437 }
438 
439 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateMultiplication(
440  const MultiplicationQueueDescriptor& descriptor, const WorkloadInfo& info) const
441 {
442  return std::make_unique<NeonMultiplicationWorkload>(descriptor, info);
443 }
444 
445 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateNormalization(
446  const NormalizationQueueDescriptor& descriptor, const WorkloadInfo& info) const
447 {
448  return MakeWorkloadHelper<NeonNormalizationFloatWorkload, NullWorkload>(descriptor, info,
449  m_MemoryManager->GetIntraLayerManager());
450 }
451 
452 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateOutput(const OutputQueueDescriptor& descriptor,
453  const WorkloadInfo& info) const
454 {
455  return std::make_unique<CopyMemGenericWorkload>(descriptor, info);
456 }
457 
458 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreatePad(const PadQueueDescriptor& descriptor,
459  const WorkloadInfo& info) const
460 {
461  return std::make_unique<NeonPadWorkload>(descriptor, info);
462 }
463 
464 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreatePermute(const PermuteQueueDescriptor& descriptor,
465  const WorkloadInfo& info) const
466 {
467  return std::make_unique<NeonPermuteWorkload>(descriptor, info);
468 }
469 
470 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreatePooling2d(const Pooling2dQueueDescriptor& descriptor,
471  const WorkloadInfo& info) const
472 {
473  return std::make_unique<NeonPooling2dWorkload>(descriptor, info);
474 }
475 
476 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreatePreCompiled(const PreCompiledQueueDescriptor& descriptor,
477  const WorkloadInfo& info) const
478 {
479  return MakeWorkloadHelper<NullWorkload, NullWorkload>(descriptor, info);
480 }
481 
482 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreatePrelu(const armnn::PreluQueueDescriptor &descriptor,
483  const armnn::WorkloadInfo &info) const
484 {
485  return std::make_unique<NeonPreluWorkload>(descriptor, info);
486 }
487 
488 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateQLstm(const QLstmQueueDescriptor& descriptor,
489  const WorkloadInfo& info) const
490 {
491  return std::make_unique<NeonQLstmWorkload>(descriptor, info);
492 }
493 
494 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateQuantize(const QuantizeQueueDescriptor& descriptor,
495  const WorkloadInfo& info) const
496 {
497  return std::make_unique<NeonQuantizeWorkload>(descriptor, info);
498 }
499 
500 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateQuantizedLstm(const QuantizedLstmQueueDescriptor& descriptor,
501  const WorkloadInfo& info) const
502 {
503  return std::make_unique<NeonQuantizedLstmWorkload>(descriptor, info);
504 }
505 
506 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateReshape(const ReshapeQueueDescriptor& descriptor,
507  const WorkloadInfo& info) const
508 {
509  return std::make_unique<NeonReshapeWorkload>(descriptor, info);
510 }
511 
512 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateResize(const ResizeQueueDescriptor& descriptor,
513  const WorkloadInfo& info) const
514 {
515  return std::make_unique<NeonResizeWorkload>(descriptor, info);
516 }
517 
518 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateResizeBilinear(
519  const ResizeBilinearQueueDescriptor& descriptor,
520  const WorkloadInfo& info) const
521 {
522  ResizeQueueDescriptor resizeDescriptor;
523  resizeDescriptor.m_Inputs = descriptor.m_Inputs;
524  resizeDescriptor.m_Outputs = descriptor.m_Outputs;
525 
526  resizeDescriptor.m_Parameters.m_DataLayout = descriptor.m_Parameters.m_DataLayout;
527  resizeDescriptor.m_Parameters.m_TargetWidth = descriptor.m_Parameters.m_TargetWidth;
528  resizeDescriptor.m_Parameters.m_TargetHeight = descriptor.m_Parameters.m_TargetHeight;
529 
530  return CreateResize(resizeDescriptor, info);
531 }
532 
533 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateRsqrt(const RsqrtQueueDescriptor &descriptor,
534  const WorkloadInfo &info) const
535 {
536  IgnoreUnused(descriptor);
537 
538  ElementwiseUnaryQueueDescriptor elementwiseUnaryDescriptor;
539  elementwiseUnaryDescriptor.m_Parameters = ElementwiseUnaryDescriptor(UnaryOperation::Rsqrt);
540 
541  return CreateElementwiseUnary(elementwiseUnaryDescriptor, info);
542 }
543 
544 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateSlice(const SliceQueueDescriptor& descriptor,
545  const WorkloadInfo& info) const
546 {
547  return std::make_unique<NeonSliceWorkload>(descriptor, info);
548 }
549 
550 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateSoftmax(const SoftmaxQueueDescriptor& descriptor,
551  const WorkloadInfo& info) const
552 {
553  return std::make_unique<NeonSoftmaxWorkload>(descriptor, info, m_MemoryManager->GetIntraLayerManager());
554 }
555 
557  const WorkloadInfo& info) const
558 {
559  return std::make_unique<NeonSpaceToBatchNdWorkload>(descriptor, info);
560 }
561 
562 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateSpaceToDepth(const SpaceToDepthQueueDescriptor& descriptor,
563  const WorkloadInfo& info) const
564 {
565  return std::make_unique<NeonSpaceToDepthWorkload>(descriptor, info);
566 }
567 
568 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateSplitter(const SplitterQueueDescriptor& descriptor,
569  const WorkloadInfo& info) const
570 {
571  return std::make_unique<NeonSplitterWorkload>(descriptor, info);
572 }
573 
574 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateStack(const StackQueueDescriptor& descriptor,
575  const WorkloadInfo& info) const
576 {
577  return std::make_unique<NeonStackWorkload>(descriptor, info);
578 }
579 
580 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateStridedSlice(const StridedSliceQueueDescriptor& descriptor,
581  const WorkloadInfo& info) const
582 {
583  return std::make_unique<NeonStridedSliceWorkload>(descriptor, info);
584 }
585 
586 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateSubtraction(
587  const SubtractionQueueDescriptor& descriptor, const WorkloadInfo& info) const
588 {
589  return std::make_unique<NeonSubtractionWorkload>(descriptor, info);
590 }
591 
592 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateTranspose(const TransposeQueueDescriptor& descriptor,
593  const WorkloadInfo& info) const
594 {
595  return std::make_unique<NeonTransposeWorkload>(descriptor, info);
596 }
597 
599  const TransposeConvolution2dQueueDescriptor &descriptor,
600  const WorkloadInfo &info) const
601 {
602  return std::make_unique<NeonTransposeConvolution2dWorkload>(descriptor, info,
603  m_MemoryManager->GetIntraLayerManager());
604 }
605 
606 } // namespace armnn
std::unique_ptr< IWorkload > CreateDepthToSpace(const DepthToSpaceQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateDebug(const DebugQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateLstm(const LstmQueueDescriptor &descriptor, const WorkloadInfo &info) const override
UnaryOperation m_Operation
Specifies the elementwiseUnary operation to execute.
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
Definition: INetwork.hpp:61
std::unique_ptr< IWorkload > CreateLogSoftmax(const LogSoftmaxQueueDescriptor &descriptor, const WorkloadInfo &info) const override
DataLayout
Definition: Types.hpp:50
std::unique_ptr< IWorkload > CreateGather(const GatherQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateNormalization(const NormalizationQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateFullyConnected(const FullyConnectedQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateComparison(const ComparisonQueueDescriptor &descriptor, const WorkloadInfo &Info) const override
std::unique_ptr< IWorkload > CreateRsqrt(const RsqrtQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreatePad(const PadQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateTransposeConvolution2d(const TransposeConvolution2dQueueDescriptor &descriptor, const WorkloadInfo &info) const override
A ComparisonDescriptor for the ComparisonLayer.
Definition: Descriptors.hpp:73
uint32_t m_TargetWidth
Target width value.
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
std::vector< BackendOptions > ModelOptions
std::unique_ptr< IWorkload > CreateGreater(const GreaterQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateMemImport(const MemImportQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::array< unsigned int, MaxNumOfTensorDimensions > Coordinates
constexpr const char * NeonBackendId()
std::unique_ptr< IWorkload > CreateL2Normalization(const L2NormalizationQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateConvertFp16ToFp32(const ConvertFp16ToFp32QueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateStridedSlice(const StridedSliceQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateMinimum(const MinimumQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateMultiplication(const MultiplicationQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateQuantize(const QuantizeQueueDescriptor &descriptor, const WorkloadInfo &info) const override
Copyright (c) 2020 ARM Limited.
void IgnoreUnused(Ts &&...)
std::unique_ptr< ITensorHandle > CreateSubTensorHandle(ITensorHandle &parent, TensorShape const &subTensorShape, unsigned int const *subTensorOrigin) const override
std::unique_ptr< IWorkload > CreateLogicalUnary(const ElementwiseUnaryQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateConvolution2d(const Convolution2dQueueDescriptor &descriptor, const WorkloadInfo &info) const override
LogicalBinaryOperation m_Operation
Specifies the logical operation to execute.
The NeonBackendModelContext is used to pass in Neon specific backend ModelOptions.
NeonWorkloadFactory(const std::shared_ptr< NeonMemoryManager > &memoryManager)
std::unique_ptr< IWorkload > CreateReshape(const ReshapeQueueDescriptor &descriptor, const WorkloadInfo &info) const override
static bool IsLayerSupported(const Layer &layer, Optional< DataType > dataType, std::string &outReasonIfUnsupported)
std::unique_ptr< IWorkload > CreateAbs(const AbsQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateConvertFp32ToFp16(const ConvertFp32ToFp16QueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateSoftmax(const SoftmaxQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateResizeBilinear(const ResizeBilinearQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateEqual(const EqualQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateSlice(const SliceQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::shared_ptr< IBackendModelContext > IBackendSpecificModelContextPtr
std::unique_ptr< IWorkload > CreateQuantizedLstm(const QuantizedLstmQueueDescriptor &descriptor, const WorkloadInfo &info) const override
uint32_t m_TargetWidth
Target width value.
const BackendId & GetBackendId() const override
std::unique_ptr< IWorkload > CreateSplitter(const SplitterQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateFill(const FillQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateDequantize(const DequantizeQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateMemCopy(const MemCopyQueueDescriptor &descriptor, const WorkloadInfo &info) const override
static bool IsLayerSupported(const BackendId &backendId, const IConnectableLayer &layer, Optional< DataType > dataType, std::string &outReasonIfUnsupported)
virtual TensorShape GetShape() const =0
Get the number of elements for each dimension ordered from slowest iterating dimension to fastest ite...
std::unique_ptr< IWorkload > CreateInstanceNormalization(const InstanceNormalizationQueueDescriptor &descriptor, const WorkloadInfo &info) const override
uint32_t m_TargetHeight
Target height value.
uint32_t m_TargetHeight
Target height value.
std::unique_ptr< IWorkload > CreatePreCompiled(const PreCompiledQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateLogicalBinary(const LogicalBinaryQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateOutput(const OutputQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateConvertFp32ToBf16(const ConvertFp32ToBf16QueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateConstant(const ConstantQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateStack(const StackQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateFloor(const FloorQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateActivation(const ActivationQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateDepthwiseConvolution2d(const DepthwiseConvolution2dQueueDescriptor &descriptor, const WorkloadInfo &info) const override
A ElementwiseUnaryDescriptor for the ElementwiseUnaryLayer.
Definition: Descriptors.hpp:93
std::vector< ITensorHandle * > m_Outputs
std::unique_ptr< IWorkload > CreateMerger(const MergerQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateDivision(const DivisionQueueDescriptor &descriptor, const WorkloadInfo &info) const override
unsigned int GetNumDimensions() const
Function that returns the tensor rank.
Definition: Tensor.cpp:174
std::unique_ptr< IWorkload > CreateInput(const InputQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateQLstm(const QLstmQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateBatchNormalization(const BatchNormalizationQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateElementwiseUnary(const ElementwiseUnaryQueueDescriptor &descriptor, const WorkloadInfo &Info) const override
Contains information about inputs and outputs to a layer.
std::unique_ptr< IWorkload > CreateResize(const ResizeQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::vector< ITensorHandle * > m_Inputs
std::unique_ptr< IWorkload > CreateConcat(const ConcatQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreatePooling2d(const Pooling2dQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateBatchToSpaceNd(const BatchToSpaceNdQueueDescriptor &descriptor, const WorkloadInfo &Info) const override
std::unique_ptr< IWorkload > CreateAddition(const AdditionQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateDetectionPostProcess(const DetectionPostProcessQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateSubtraction(const SubtractionQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateMaximum(const MaximumQueueDescriptor &descriptor, const WorkloadInfo &info) const override
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
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 > CreateArgMinMax(const ArgMinMaxQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreatePrelu(const PreluQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateTranspose(const TransposeQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateSpaceToBatchNd(const SpaceToBatchNdQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreateSpaceToDepth(const SpaceToDepthQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< IWorkload > CreatePermute(const PermuteQueueDescriptor &descriptor, const WorkloadInfo &info) const override
std::unique_ptr< ITensorHandle > CreateTensorHandle(const TensorInfo &tensorInfo, const bool IsMemoryManaged=true) const override