IVGCVSW-1946: Remove armnn/src from the include paths
[platform/upstream/armnn.git] / src / backends / neon / NeonWorkloadFactory.cpp
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 #include "NeonWorkloadFactory.hpp"
6 #include "NeonBackendId.hpp"
7 #include <armnn/Utils.hpp>
8 #include <backendsCommon/CpuTensorHandle.hpp>
9 #include <Layer.hpp>
10
11 #ifdef ARMCOMPUTENEON_ENABLED
12 #include <arm_compute/runtime/Allocator.h>
13
14 #include <backendsCommon/MemCopyWorkload.hpp>
15 #include "NeonTensorHandle.hpp"
16 #include "workloads/NeonWorkloadUtils.hpp"
17 #include "workloads/NeonWorkloads.hpp"
18
19 #include <aclCommon/memory/IPoolManager.hpp>
20 #endif
21
22 #include <backendsCommon/MakeWorkloadHelper.hpp>
23
24 #include <boost/polymorphic_cast.hpp>
25
26 namespace armnn
27 {
28
29 namespace
30 {
31 static const BackendId s_Id{NeonBackendId()};
32 }
33
34 bool NeonWorkloadFactory::IsLayerSupported(const Layer& layer,
35                                            Optional<DataType> dataType,
36                                            std::string& outReasonIfUnsupported)
37 {
38     return IWorkloadFactory::IsLayerSupported(s_Id, layer, dataType, outReasonIfUnsupported);
39 }
40
41 const BackendId& NeonWorkloadFactory::GetBackendId() const
42 {
43     return s_Id;
44 }
45
46 #ifdef ARMCOMPUTENEON_ENABLED
47
48 NeonWorkloadFactory::NeonWorkloadFactory()
49     : m_MemoryManager(std::make_unique<arm_compute::Allocator>(), BaseMemoryManager::MemoryAffinity::Offset)
50 {
51 }
52
53 std::unique_ptr<ITensorHandle> NeonWorkloadFactory::CreateSubTensorHandle(ITensorHandle& parent,
54     TensorShape const& subTensorShape,
55     unsigned int const* subTensorOrigin) const
56 {
57     BOOST_ASSERT(parent.GetType() == ITensorHandle::Neon);
58
59     const arm_compute::TensorShape shape = armcomputetensorutils::BuildArmComputeTensorShape(subTensorShape);
60
61     arm_compute::Coordinates coords;
62     coords.set_num_dimensions(subTensorShape.GetNumDimensions());
63     for (unsigned int i = 0; i < subTensorShape.GetNumDimensions(); i++)
64     {
65         // Arm compute indexes tensor coords in reverse order.
66         unsigned int revertedIndex = subTensorShape.GetNumDimensions() - i - 1;
67         coords.set(i, boost::numeric_cast<int>(subTensorOrigin[revertedIndex]));
68     }
69
70     return std::make_unique<NeonSubTensorHandle>(
71         boost::polymorphic_downcast<INeonTensorHandle*>(&parent), shape, coords);
72 }
73
74 std::unique_ptr<ITensorHandle> NeonWorkloadFactory::CreateTensorHandle(const TensorInfo& tensorInfo) const
75 {
76     auto tensorHandle = std::make_unique<NeonTensorHandle>(tensorInfo);
77     tensorHandle->SetMemoryGroup(m_MemoryManager.GetInterLayerMemoryGroup());
78
79     return tensorHandle;
80 }
81
82 std::unique_ptr<ITensorHandle> NeonWorkloadFactory::CreateTensorHandle(const TensorInfo& tensorInfo,
83                                                                        DataLayout dataLayout) const
84 {
85     auto tensorHandle = std::make_unique<NeonTensorHandle>(tensorInfo, dataLayout);
86     tensorHandle->SetMemoryGroup(m_MemoryManager.GetInterLayerMemoryGroup());
87
88     return tensorHandle;
89 }
90
91 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateInput(const InputQueueDescriptor& descriptor,
92                                                             const WorkloadInfo&        info) const
93 {
94     return MakeWorkloadHelper<CopyMemGenericWorkload, CopyMemGenericWorkload>(descriptor, info);
95 }
96
97 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateOutput(const OutputQueueDescriptor& descriptor,
98                                                              const WorkloadInfo&        info) const
99 {
100     return MakeWorkloadHelper<CopyMemGenericWorkload, CopyMemGenericWorkload>(descriptor, info);
101 }
102
103 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateActivation(const ActivationQueueDescriptor& descriptor,
104                                                                  const WorkloadInfo&              info) const
105 {
106     return std::make_unique<NeonActivationWorkload>(descriptor, info);
107 }
108
109 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateSoftmax(const SoftmaxQueueDescriptor& descriptor,
110                                                               const WorkloadInfo&           info) const
111 {
112     return MakeWorkloadHelper<NeonSoftmaxFloatWorkload, NeonSoftmaxUint8Workload>(descriptor, info,
113         m_MemoryManager.GetIntraLayerManager());
114 }
115
116 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateSplitter(const SplitterQueueDescriptor& descriptor,
117                                                                const WorkloadInfo&            info) const
118 {
119     return std::make_unique<NeonSplitterWorkload>(descriptor, info);
120 }
121
122 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateMerger(const MergerQueueDescriptor& descriptor,
123                                                                     const WorkloadInfo&          info) const
124 {
125     return std::make_unique<NeonMergerWorkload>(descriptor, info);
126 }
127
128 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateFullyConnected(
129     const FullyConnectedQueueDescriptor& descriptor, const WorkloadInfo& info) const
130 {
131     return MakeWorkloadHelper<NeonFullyConnectedWorkload, NeonFullyConnectedWorkload>(descriptor, info,
132         m_MemoryManager.GetIntraLayerManager());
133 }
134
135 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreatePermute(const PermuteQueueDescriptor& descriptor,
136                                                                      const WorkloadInfo&           info) const
137 {
138     return std::make_unique<NeonPermuteWorkload>(descriptor, info);
139 }
140
141 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreatePooling2d(const Pooling2dQueueDescriptor& descriptor,
142                                                                        const WorkloadInfo&           info) const
143 {
144     return std::make_unique<NeonPooling2dWorkload>(descriptor, info);
145 }
146
147 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateConvolution2d(
148     const Convolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) const
149 {
150     return std::make_unique<NeonConvolution2dWorkload>(descriptor, info,
151                                                        m_MemoryManager.GetIntraLayerManager());
152 }
153
154 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateDepthwiseConvolution2d(
155     const DepthwiseConvolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) const
156 {
157     return std::make_unique<NeonDepthwiseConvolutionWorkload>(descriptor, info);
158 }
159
160 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateNormalization(
161     const NormalizationQueueDescriptor& descriptor, const WorkloadInfo& info) const
162 {
163     return MakeWorkloadHelper<NeonNormalizationFloatWorkload, NullWorkload>(descriptor, info,
164         m_MemoryManager.GetIntraLayerManager());
165 }
166
167 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateAddition(const AdditionQueueDescriptor& descriptor,
168                                                                       const WorkloadInfo&            info) const
169 {
170     return MakeWorkloadHelper<NeonAdditionFloatWorkload, NullWorkload>(descriptor, info);
171 }
172
173 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateMultiplication(
174     const MultiplicationQueueDescriptor& descriptor, const WorkloadInfo& info) const
175 {
176     return MakeWorkloadHelper<NeonMultiplicationFloatWorkload, NullWorkload>(descriptor, info);
177 }
178
179 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateDivision(
180     const DivisionQueueDescriptor& descriptor, const WorkloadInfo& info) const
181 {
182     return MakeWorkloadHelper<NullWorkload, NullWorkload>(descriptor, info);
183 }
184
185 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateSubtraction(
186     const SubtractionQueueDescriptor& descriptor, const WorkloadInfo& info) const
187 {
188     return MakeWorkloadHelper<NeonSubtractionFloatWorkload, NullWorkload>(descriptor, info);
189 }
190
191 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateBatchNormalization(
192     const BatchNormalizationQueueDescriptor& descriptor, const WorkloadInfo& info) const
193 {
194     return MakeWorkloadHelper<NeonBatchNormalizationFloatWorkload, NullWorkload>(descriptor, info);
195 }
196
197 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateMemCopy(const MemCopyQueueDescriptor& descriptor,
198                                                                      const WorkloadInfo&        info) const
199 {
200     if (descriptor.m_Inputs.empty() || !descriptor.m_Inputs[0])
201     {
202         throw InvalidArgumentException("NeonWorkloadFactory: Invalid null input for MemCopy workload");
203     }
204
205     return MakeWorkloadHelper<CopyMemGenericWorkload, CopyMemGenericWorkload>(descriptor, info);
206 }
207
208 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateResizeBilinear(
209     const ResizeBilinearQueueDescriptor& descriptor,
210     const WorkloadInfo& info) const
211 {
212     return nullptr;
213 }
214
215 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateFakeQuantization(
216     const FakeQuantizationQueueDescriptor& descriptor,
217     const WorkloadInfo& info) const
218 {
219     return nullptr;
220 }
221
222 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateL2Normalization(const L2NormalizationQueueDescriptor& descriptor,
223     const WorkloadInfo& info) const
224 {
225     return MakeWorkloadHelper<NeonL2NormalizationFloatWorkload, NullWorkload>(descriptor, info,
226         m_MemoryManager.GetIntraLayerManager());
227 }
228
229 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateConstant(const ConstantQueueDescriptor& descriptor,
230     const WorkloadInfo& info) const
231 {
232     return std::make_unique<NeonConstantWorkload>(descriptor, info);
233 }
234
235 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateReshape(const ReshapeQueueDescriptor& descriptor,
236     const WorkloadInfo& info) const
237 {
238     return std::make_unique<NeonReshapeWorkload>(descriptor, info);
239 }
240
241 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateSpaceToBatchNd(const SpaceToBatchNdQueueDescriptor& descriptor,
242     const WorkloadInfo& info) const
243 {
244     return nullptr;
245 }
246
247 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateFloor(const FloorQueueDescriptor& descriptor,
248     const WorkloadInfo& info) const
249 {
250     return MakeWorkloadHelper<NeonFloorFloatWorkload, NullWorkload>(descriptor, info);
251 }
252
253 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateLstm(const LstmQueueDescriptor& descriptor,
254     const WorkloadInfo& info) const
255 {
256     return MakeWorkloadHelper<NeonLstmFloatWorkload, NullWorkload>(descriptor, info);
257 }
258
259 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateConvertFp16ToFp32(
260     const ConvertFp16ToFp32QueueDescriptor& descriptor,
261     const WorkloadInfo& info) const
262 {
263     return std::make_unique<NeonConvertFp16ToFp32Workload>(descriptor, info);
264 }
265
266 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateConvertFp32ToFp16(
267     const ConvertFp32ToFp16QueueDescriptor& descriptor,
268     const WorkloadInfo& info) const
269 {
270     return std::make_unique<NeonConvertFp32ToFp16Workload>(descriptor, info);
271 }
272
273 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateMean(const MeanQueueDescriptor& descriptor,
274                                                            const WorkloadInfo& info) const
275 {
276     return MakeWorkloadHelper<NullWorkload, NullWorkload>(descriptor, info);
277 }
278
279 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreatePad(const PadQueueDescriptor& descriptor,
280                                                           const WorkloadInfo& info) const
281 {
282     return MakeWorkloadHelper<NullWorkload, NullWorkload>(descriptor, info);
283 }
284
285 void NeonWorkloadFactory::Finalize()
286 {
287     m_MemoryManager.Finalize();
288 }
289
290 void NeonWorkloadFactory::Release()
291 {
292     m_MemoryManager.Release();
293 }
294
295 void NeonWorkloadFactory::Acquire()
296 {
297     m_MemoryManager.Acquire();
298 }
299
300 #else // Compiled without ArmCompute libs
301
302 NeonWorkloadFactory::NeonWorkloadFactory()
303 {
304 }
305
306 std::unique_ptr<ITensorHandle> NeonWorkloadFactory::CreateSubTensorHandle(ITensorHandle& parent,
307     TensorShape const& subTensorShape,
308     unsigned int const* subTensorOrigin) const
309 {
310     return nullptr;
311 }
312
313 std::unique_ptr<ITensorHandle> NeonWorkloadFactory::CreateTensorHandle(const TensorInfo& tensorInfo) const
314 {
315     return nullptr;
316 }
317
318 std::unique_ptr<ITensorHandle> NeonWorkloadFactory::CreateTensorHandle(const TensorInfo& tensorInfo,
319                                                                        DataLayout dataLayout) const
320 {
321     return nullptr;
322 }
323
324 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateInput(const InputQueueDescriptor& descriptor,
325                                                             const WorkloadInfo&        info) const
326 {
327     return nullptr;
328 }
329
330 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateOutput(const OutputQueueDescriptor& descriptor,
331                                                              const WorkloadInfo&        info) const
332 {
333     return nullptr;
334 }
335
336 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateActivation(const ActivationQueueDescriptor& descriptor,
337                                                                  const WorkloadInfo&              info) const
338 {
339     return nullptr;
340 }
341
342 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateSoftmax(const SoftmaxQueueDescriptor& descriptor,
343                                                               const WorkloadInfo&           info) const
344 {
345     return nullptr;
346 }
347
348 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateSplitter(const SplitterQueueDescriptor& descriptor,
349                                                                const WorkloadInfo&            info) const
350 {
351     return nullptr;
352 }
353
354 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateMerger(const MergerQueueDescriptor& descriptor,
355                                                              const WorkloadInfo&          info) const
356 {
357     return nullptr;
358 }
359
360 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateFullyConnected(const FullyConnectedQueueDescriptor& descriptor,
361                                                                      const WorkloadInfo&                  info) const
362 {
363     return nullptr;
364 }
365
366 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreatePermute(const PermuteQueueDescriptor& descriptor,
367                                                                      const WorkloadInfo&           info) const
368 {
369     return nullptr;
370 }
371
372 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreatePooling2d(const Pooling2dQueueDescriptor& descriptor,
373                                                                 const WorkloadInfo&           info) const
374 {
375     return nullptr;
376 }
377
378 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateConvolution2d(const Convolution2dQueueDescriptor& descriptor,
379                                                                     const WorkloadInfo&               info) const
380 {
381     return nullptr;
382 }
383
384 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateDepthwiseConvolution2d(
385     const DepthwiseConvolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) const
386 {
387     return nullptr;
388 }
389
390 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateNormalization(const NormalizationQueueDescriptor& descriptor,
391                                                                     const WorkloadInfo&                 info) const
392 {
393     return nullptr;
394 }
395
396 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateAddition(const AdditionQueueDescriptor& descriptor,
397                                                                const WorkloadInfo&            info) const
398 {
399     return nullptr;
400 }
401
402 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateBatchNormalization(const BatchNormalizationQueueDescriptor& data,
403                                                                          const WorkloadInfo& info) const
404 {
405     return nullptr;
406 }
407
408 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateMultiplication(const MultiplicationQueueDescriptor& data,
409                                                                      const WorkloadInfo&                  info) const
410 {
411     return nullptr;
412 }
413
414 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateMemCopy(const MemCopyQueueDescriptor& descriptor,
415                                                               const WorkloadInfo&        info) const
416 {
417     return nullptr;
418 }
419
420 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateResizeBilinear(const ResizeBilinearQueueDescriptor& descriptor,
421                                                                      const WorkloadInfo& info) const
422 {
423     return nullptr;
424 }
425
426 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateFakeQuantization(
427         const FakeQuantizationQueueDescriptor& descriptor, const WorkloadInfo& info) const
428 {
429     return nullptr;
430 }
431
432 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateL2Normalization(const L2NormalizationQueueDescriptor& descriptor,
433     const WorkloadInfo& info) const
434 {
435     return nullptr;
436 }
437
438 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateConstant(const ConstantQueueDescriptor& descriptor,
439     const WorkloadInfo& info) const
440 {
441     return nullptr;
442 }
443
444 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateReshape(const ReshapeQueueDescriptor& descriptor,
445     const WorkloadInfo&           info) const
446 {
447     return nullptr;
448 }
449
450 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateSpaceToBatchNd(const SpaceToBatchNdQueueDescriptor& descriptor,
451     const WorkloadInfo& info) const
452 {
453     return nullptr;
454 }
455
456 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateFloor(const FloorQueueDescriptor& descriptor,
457     const WorkloadInfo& info) const
458 {
459     return nullptr;
460 }
461
462 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateLstm(const LstmQueueDescriptor& descriptor,
463     const WorkloadInfo& info) const
464 {
465     return nullptr;
466 }
467
468 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateConvertFp16ToFp32(
469     const ConvertFp16ToFp32QueueDescriptor& descriptor,
470     const WorkloadInfo& info) const
471 {
472     return nullptr;
473 }
474
475 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateConvertFp32ToFp16(
476     const ConvertFp32ToFp16QueueDescriptor& descriptor,
477     const WorkloadInfo& info) const
478 {
479     return nullptr;
480 }
481
482 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateDivision(const DivisionQueueDescriptor& data,
483                                                                const WorkloadInfo& info) const
484 {
485     return nullptr;
486 }
487
488 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateSubtraction(const SubtractionQueueDescriptor& data,
489                                                                   const WorkloadInfo& info) const
490 {
491     return nullptr;
492 }
493
494 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateMean(const MeanQueueDescriptor& descriptor,
495                                                            const WorkloadInfo& info) const
496 {
497     return nullptr;
498 }
499
500 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreatePad(const PadQueueDescriptor& descriptor,
501                                                           const WorkloadInfo& info) const
502 {
503     return nullptr;
504 }
505
506 void NeonWorkloadFactory::Finalize()
507 {}
508
509 void NeonWorkloadFactory::Release()
510 {}
511
512 void NeonWorkloadFactory::Acquire()
513 {}
514
515 #endif
516
517 } //namespace armnn