blob: 9967fb8604c39b466c3b425877b7ece70bd8265d [file] [log] [blame]
Laurent Carlier749294b2020-06-01 09:03:17 +01001//
Keith Davis69e653f2020-07-02 11:49:26 +01002// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
David Beckecb56cd2018-09-05 12:52:57 +01003// SPDX-License-Identifier: MIT
telsoa014fcda012018-03-09 14:13:49 +00004//
Aron Virginas-Tar56055192018-11-12 18:10:43 +00005
David Beck79141b92018-10-23 16:09:36 +01006#include "NeonBackendId.hpp"
Sadik Armagan04a72972020-09-14 15:44:18 +01007#include "NeonBackendModelContext.hpp"
Aron Virginas-Tar56055192018-11-12 18:10:43 +00008#include "NeonTensorHandle.hpp"
9#include "NeonWorkloadFactory.hpp"
10
David Beck0dbe0ee2018-09-24 15:59:27 +010011#include <Layer.hpp>
telsoa014fcda012018-03-09 14:13:49 +000012
Aron Virginas-Tar56055192018-11-12 18:10:43 +000013#include <armnn/Utils.hpp>
Jan Eilers8eb25602020-03-09 12:13:48 +000014#include <armnn/utility/IgnoreUnused.hpp>
Matthew Sloyan171214c2020-09-09 09:07:37 +010015#include <armnn/utility/NumericCast.hpp>
Jan Eilersbb446e52020-04-02 13:56:54 +010016#include <armnn/utility/PolymorphicDowncast.hpp>
telsoa01c577f2c2018-08-31 09:22:23 +010017
Aron Virginas-Tar56055192018-11-12 18:10:43 +000018#include <backendsCommon/CpuTensorHandle.hpp>
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000019#include <backendsCommon/MakeWorkloadHelper.hpp>
Aron Virginas-Tar56055192018-11-12 18:10:43 +000020#include <backendsCommon/MemCopyWorkload.hpp>
Derek Lambertif674aa02019-08-01 15:56:25 +010021#include <backendsCommon/MemImportWorkload.hpp>
telsoa014fcda012018-03-09 14:13:49 +000022
Aron Virginas-Tar56055192018-11-12 18:10:43 +000023#include <neon/workloads/NeonWorkloadUtils.hpp>
24#include <neon/workloads/NeonWorkloads.hpp>
25
telsoa014fcda012018-03-09 14:13:49 +000026namespace armnn
27{
28
David Beck79141b92018-10-23 16:09:36 +010029namespace
30{
31static const BackendId s_Id{NeonBackendId()};
32}
33
David Beck29c75de2018-10-23 13:35:58 +010034bool NeonWorkloadFactory::IsLayerSupported(const Layer& layer,
35 Optional<DataType> dataType,
telsoa01c577f2c2018-08-31 09:22:23 +010036 std::string& outReasonIfUnsupported)
telsoa014fcda012018-03-09 14:13:49 +000037{
David Beck79141b92018-10-23 16:09:36 +010038 return IWorkloadFactory::IsLayerSupported(s_Id, layer, dataType, outReasonIfUnsupported);
39}
40
Sadik Armagan04a72972020-09-14 15:44:18 +010041bool NeonWorkloadFactory::IsLayerSupported(const IConnectableLayer& layer,
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
David Beck79141b92018-10-23 16:09:36 +010049const BackendId& NeonWorkloadFactory::GetBackendId() const
50{
51 return s_Id;
telsoa014fcda012018-03-09 14:13:49 +000052}
53
Matthew Sloyan0a7dc6b2021-02-10 16:50:53 +000054void NeonWorkloadFactory::SetNumberOfThreads()
55{
56 if (m_ModelContextPtr)
57 {
58 const unsigned int MIN_THREADS = 1;
59 const unsigned int MAX_THREADS = 64;
60
61 // Set the number of threads to be used if the user has set NumberOfThreads param
62 // Only set if within limit or valid input
63 auto modelOptions = dynamic_cast<NeonBackendModelContext*>(m_ModelContextPtr.get());
64 auto numberOfThreads = modelOptions->GetNumberOfThreads();
65
66 if (numberOfThreads != 0 && numberOfThreads >= MIN_THREADS && numberOfThreads <= MAX_THREADS)
67 {
68 arm_compute::Scheduler::get().set_num_threads(numberOfThreads);
69 }
70 }
71}
72
Aron Virginas-Tar56055192018-11-12 18:10:43 +000073NeonWorkloadFactory::NeonWorkloadFactory(const std::shared_ptr<NeonMemoryManager>& memoryManager)
Sadik Armagan04a72972020-09-14 15:44:18 +010074 : m_MemoryManager(memoryManager), m_ModelContextPtr(IBackendInternal::IBackendSpecificModelContextPtr{})
75{
Matthew Sloyan0a7dc6b2021-02-10 16:50:53 +000076 SetNumberOfThreads();
Sadik Armagan04a72972020-09-14 15:44:18 +010077}
78
79NeonWorkloadFactory::NeonWorkloadFactory(const std::shared_ptr<NeonMemoryManager>& memoryManager,
80 const IBackendInternal::IBackendSpecificModelContextPtr& modelContextPtr)
81 : m_MemoryManager(memoryManager), m_ModelContextPtr(modelContextPtr)
surmeh013537c2c2018-05-18 16:31:43 +010082{
Matthew Sloyan0a7dc6b2021-02-10 16:50:53 +000083 SetNumberOfThreads();
surmeh013537c2c2018-05-18 16:31:43 +010084}
85
telsoa014fcda012018-03-09 14:13:49 +000086std::unique_ptr<ITensorHandle> NeonWorkloadFactory::CreateSubTensorHandle(ITensorHandle& parent,
87 TensorShape const& subTensorShape,
88 unsigned int const* subTensorOrigin) const
89{
telsoa014fcda012018-03-09 14:13:49 +000090 const arm_compute::TensorShape shape = armcomputetensorutils::BuildArmComputeTensorShape(subTensorShape);
91
92 arm_compute::Coordinates coords;
93 coords.set_num_dimensions(subTensorShape.GetNumDimensions());
94 for (unsigned int i = 0; i < subTensorShape.GetNumDimensions(); i++)
95 {
telsoa01c577f2c2018-08-31 09:22:23 +010096 // Arm compute indexes tensor coords in reverse order.
telsoa014fcda012018-03-09 14:13:49 +000097 unsigned int revertedIndex = subTensorShape.GetNumDimensions() - i - 1;
Matthew Sloyan171214c2020-09-09 09:07:37 +010098 coords.set(i, armnn::numeric_cast<int>(subTensorOrigin[revertedIndex]));
telsoa014fcda012018-03-09 14:13:49 +000099 }
100
Derek Lamberti0790dce2019-04-15 18:37:35 +0100101 const arm_compute::TensorShape parentShape = armcomputetensorutils::BuildArmComputeTensorShape(parent.GetShape());
102 if (!::arm_compute::error_on_invalid_subtensor(__func__, __FILE__, __LINE__, parentShape, coords, shape))
103 {
104 return nullptr;
105 }
106
telsoa01c577f2c2018-08-31 09:22:23 +0100107 return std::make_unique<NeonSubTensorHandle>(
Jan Eilersbb446e52020-04-02 13:56:54 +0100108 PolymorphicDowncast<IAclTensorHandle*>(&parent), shape, coords);
telsoa014fcda012018-03-09 14:13:49 +0000109}
110
David Monahan3fb7e102019-08-20 11:25:29 +0100111std::unique_ptr<ITensorHandle> NeonWorkloadFactory::CreateTensorHandle(const TensorInfo& tensorInfo,
112 const bool IsMemoryManaged) const
telsoa014fcda012018-03-09 14:13:49 +0000113{
telsoa01c577f2c2018-08-31 09:22:23 +0100114 auto tensorHandle = std::make_unique<NeonTensorHandle>(tensorInfo);
David Monahan3fb7e102019-08-20 11:25:29 +0100115 if (IsMemoryManaged)
116 {
117 tensorHandle->SetMemoryGroup(m_MemoryManager->GetInterLayerMemoryGroup());
118 }
telsoa01c577f2c2018-08-31 09:22:23 +0100119 return tensorHandle;
telsoa014fcda012018-03-09 14:13:49 +0000120}
121
Francis Murtagh351d13d2018-09-24 15:01:18 +0100122std::unique_ptr<ITensorHandle> NeonWorkloadFactory::CreateTensorHandle(const TensorInfo& tensorInfo,
David Monahan3fb7e102019-08-20 11:25:29 +0100123 DataLayout dataLayout,
124 const bool IsMemoryManaged) const
Francis Murtagh351d13d2018-09-24 15:01:18 +0100125{
126 auto tensorHandle = std::make_unique<NeonTensorHandle>(tensorInfo, dataLayout);
David Monahan3fb7e102019-08-20 11:25:29 +0100127 if (IsMemoryManaged)
128 {
129 tensorHandle->SetMemoryGroup(m_MemoryManager->GetInterLayerMemoryGroup());
130 }
Francis Murtagh351d13d2018-09-24 15:01:18 +0100131 return tensorHandle;
132}
133
Aron Virginas-Tar914e4db2019-09-09 13:36:45 +0100134std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateAbs(const AbsQueueDescriptor& descriptor,
135 const WorkloadInfo& info) const
136{
Jan Eilers8eb25602020-03-09 12:13:48 +0000137 IgnoreUnused(descriptor);
josh minor4a3c6102020-01-06 16:40:46 -0600138
139 ElementwiseUnaryQueueDescriptor elementwiseUnaryDescriptor;
140 elementwiseUnaryDescriptor.m_Parameters = ElementwiseUnaryDescriptor(UnaryOperation::Abs);
141
142 return CreateElementwiseUnary(elementwiseUnaryDescriptor, info);
Aron Virginas-Tar914e4db2019-09-09 13:36:45 +0100143}
144
telsoa014fcda012018-03-09 14:13:49 +0000145std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateActivation(const ActivationQueueDescriptor& descriptor,
146 const WorkloadInfo& info) const
147{
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +0100148 return std::make_unique<NeonActivationWorkload>(descriptor, info);
telsoa014fcda012018-03-09 14:13:49 +0000149}
150
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100151std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateAddition(const AdditionQueueDescriptor& descriptor,
152 const WorkloadInfo& info) const
telsoa014fcda012018-03-09 14:13:49 +0000153{
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100154 return std::make_unique<NeonAdditionWorkload>(descriptor, info);
telsoa014fcda012018-03-09 14:13:49 +0000155}
156
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100157std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateArgMinMax(const ArgMinMaxQueueDescriptor& descriptor,
158 const WorkloadInfo& info) const
telsoa014fcda012018-03-09 14:13:49 +0000159{
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100160 return std::make_unique<NeonArgMinMaxWorkload>(descriptor, info);
telsoa014fcda012018-03-09 14:13:49 +0000161}
162
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100163std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateBatchNormalization(
164 const BatchNormalizationQueueDescriptor& descriptor, const WorkloadInfo& info) const
165{
166 return std::make_unique<NeonBatchNormalizationWorkload>(descriptor, info);
167}
168
169std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateBatchToSpaceNd(const BatchToSpaceNdQueueDescriptor& descriptor,
170 const WorkloadInfo& info) const
171{
Mike Kelly56858022020-01-27 12:14:47 +0000172 return std::make_unique<NeonBatchToSpaceNdWorkload>(descriptor, info);
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100173}
174
Sadik Armagan48f011e2021-04-21 10:50:34 +0100175std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateCast(const CastQueueDescriptor& descriptor,
176 const WorkloadInfo& info) const
177{
178 return std::make_unique<NeonCastWorkload>(descriptor, info);
179}
180
Aron Virginas-Tar77bfb5e2019-10-16 17:45:38 +0100181std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateComparison(const ComparisonQueueDescriptor& descriptor,
182 const WorkloadInfo& info) const
183{
Teresa Charlincedd34f2020-03-30 11:17:30 +0100184 return std::make_unique<NeonComparisonWorkload>(descriptor, info);
Aron Virginas-Tar77bfb5e2019-10-16 17:45:38 +0100185}
186
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100187std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateConcat(const ConcatQueueDescriptor& descriptor,
telsoa014fcda012018-03-09 14:13:49 +0000188 const WorkloadInfo& info) const
189{
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100190 return std::make_unique<NeonConcatWorkload>(descriptor, info);
telsoa014fcda012018-03-09 14:13:49 +0000191}
192
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100193std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateConstant(const ConstantQueueDescriptor& descriptor,
194 const WorkloadInfo& info) const
telsoa014fcda012018-03-09 14:13:49 +0000195{
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100196 return std::make_unique<NeonConstantWorkload>(descriptor, info);
telsoa014fcda012018-03-09 14:13:49 +0000197}
198
Narumol Prangnawarat250d3922020-03-30 16:11:04 +0100199std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateConvertBf16ToFp32(
200 const ConvertBf16ToFp32QueueDescriptor& descriptor,
201 const WorkloadInfo& info) const
202{
203 return std::make_unique<NeonConvertBf16ToFp32Workload>(descriptor, info);
204}
205
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100206std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateConvertFp16ToFp32(
207 const ConvertFp16ToFp32QueueDescriptor& descriptor,
208 const WorkloadInfo& info) const
telsoa014fcda012018-03-09 14:13:49 +0000209{
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100210 return std::make_unique<NeonConvertFp16ToFp32Workload>(descriptor, info);
telsoa014fcda012018-03-09 14:13:49 +0000211}
212
Narumol Prangnawarat250d3922020-03-30 16:11:04 +0100213std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateConvertFp32ToBf16(
214 const ConvertFp32ToBf16QueueDescriptor& descriptor,
215 const WorkloadInfo& info) const
216{
217 return std::make_unique<NeonConvertFp32ToBf16Workload>(descriptor, info);
218}
219
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100220std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateConvertFp32ToFp16(
221 const ConvertFp32ToFp16QueueDescriptor& descriptor,
222 const WorkloadInfo& info) const
telsoa014fcda012018-03-09 14:13:49 +0000223{
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100224 return std::make_unique<NeonConvertFp32ToFp16Workload>(descriptor, info);
Nikhil Raj9b461482019-07-03 15:58:31 +0100225}
226
telsoa014fcda012018-03-09 14:13:49 +0000227std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateConvolution2d(
228 const Convolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) const
229{
Sadik Armagan04a72972020-09-14 15:44:18 +0100230 bool isFastMathEnabled = false;
231 if (m_ModelContextPtr)
232 {
233 if (m_ModelContextPtr.get() != nullptr)
234 {
235 auto modelOptions = dynamic_cast<NeonBackendModelContext*>(m_ModelContextPtr.get());
236 if (modelOptions)
237 {
238 isFastMathEnabled = modelOptions->IsFastMathEnabled();
239 }
240 }
241 }
242 return std::make_unique<NeonConvolution2dWorkload>(descriptor,
243 info,
244 m_MemoryManager->GetIntraLayerManager(),
245 isFastMathEnabled);
telsoa014fcda012018-03-09 14:13:49 +0000246}
247
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100248std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateDebug(const DebugQueueDescriptor& descriptor,
249 const WorkloadInfo& info) const
250{
251 return MakeWorkloadHelper<NullWorkload, NullWorkload>(descriptor, info);
252}
253
Aron Virginas-Tar2f00b742019-09-30 13:28:08 +0100254std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateDepthToSpace(const DepthToSpaceQueueDescriptor& descriptor,
255 const WorkloadInfo& info) const
256{
257 return std::make_unique<NeonDepthToSpaceWorkload>(descriptor, info);
258}
259
telsoa014fcda012018-03-09 14:13:49 +0000260std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateDepthwiseConvolution2d(
261 const DepthwiseConvolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) const
262{
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100263 return std::make_unique<NeonDepthwiseConvolutionWorkload>(descriptor, info);
telsoa014fcda012018-03-09 14:13:49 +0000264}
265
Narumol Prangnawarat01961a72019-05-30 16:47:12 +0100266std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateDequantize(const DequantizeQueueDescriptor& descriptor,
267 const WorkloadInfo& info) const
268{
269 return std::make_unique<NeonDequantizeWorkload>(descriptor, info);
270}
271
Narumol Prangnawarat94dd5d82019-01-23 18:06:26 +0000272std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateDetectionPostProcess(
273 const armnn::DetectionPostProcessQueueDescriptor& descriptor, const armnn::WorkloadInfo& info) const
274{
James Conroyd9fb6e22020-02-21 16:52:44 +0000275 return MakeWorkloadHelper<NullWorkload, NullWorkload>(descriptor, info);
Narumol Prangnawarat94dd5d82019-01-23 18:06:26 +0000276}
277
Francis Murtaghe7a86a42018-08-29 12:42:10 +0100278std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateDivision(
279 const DivisionQueueDescriptor& descriptor, const WorkloadInfo& info) const
280{
Pablo Telloe61f0712020-01-23 10:37:17 +0000281 return std::make_unique<NeonDivisionWorkload>(descriptor, info);
Francis Murtaghe7a86a42018-08-29 12:42:10 +0100282}
283
Sadik Armaganac472102020-03-24 09:54:36 +0000284std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateElementwiseUnary(
285 const ElementwiseUnaryQueueDescriptor& descriptor, const WorkloadInfo& info) const
josh minor4a3c6102020-01-06 16:40:46 -0600286{
Derek Lambertic77874a2020-04-28 13:34:56 +0100287 switch(descriptor.m_Parameters.m_Operation)
josh minor4a3c6102020-01-06 16:40:46 -0600288 {
Derek Lambertic77874a2020-04-28 13:34:56 +0100289 case UnaryOperation::Abs:
James Conroy177df1e2020-11-13 10:18:51 +0000290 {
291 AbsQueueDescriptor absQueueDescriptor;
292 absQueueDescriptor.m_Inputs = descriptor.m_Inputs;
293 absQueueDescriptor.m_Outputs = descriptor.m_Outputs;
josh minor4a3c6102020-01-06 16:40:46 -0600294
James Conroy177df1e2020-11-13 10:18:51 +0000295 return std::make_unique<NeonAbsWorkload>(absQueueDescriptor, info);
296 }
Derek Lambertic77874a2020-04-28 13:34:56 +0100297 case UnaryOperation::Rsqrt:
James Conroy177df1e2020-11-13 10:18:51 +0000298 {
299 RsqrtQueueDescriptor rsqrtQueueDescriptor;
300 rsqrtQueueDescriptor.m_Inputs = descriptor.m_Inputs;
301 rsqrtQueueDescriptor.m_Outputs = descriptor.m_Outputs;
josh minor4a3c6102020-01-06 16:40:46 -0600302
James Conroy177df1e2020-11-13 10:18:51 +0000303 return std::make_unique<NeonRsqrtWorkload>(rsqrtQueueDescriptor, info);
304 }
Derek Lambertic77874a2020-04-28 13:34:56 +0100305 case UnaryOperation::Neg:
306 return std::make_unique<NeonNegWorkload>(descriptor, info);
307 case UnaryOperation::Exp:
308 return std::make_unique<NeonExpWorkload>(descriptor, info);
James Conroy177df1e2020-11-13 10:18:51 +0000309 case UnaryOperation::LogicalNot:
310 return std::make_unique<NeonLogicalNotWorkload>(descriptor, info);
Derek Lambertic77874a2020-04-28 13:34:56 +0100311 default:
312 return nullptr;
josh minor4a3c6102020-01-06 16:40:46 -0600313 }
josh minor4a3c6102020-01-06 16:40:46 -0600314}
315
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100316std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateEqual(const EqualQueueDescriptor& descriptor,
317 const WorkloadInfo& info) const
David Beckc2044fe2018-09-05 15:00:38 +0100318{
Jan Eilers8eb25602020-03-09 12:13:48 +0000319 IgnoreUnused(descriptor);
Aron Virginas-Tar77bfb5e2019-10-16 17:45:38 +0100320
321 ComparisonQueueDescriptor comparisonDescriptor;
322 comparisonDescriptor.m_Parameters = ComparisonDescriptor(ComparisonOperation::Equal);
323
324 return CreateComparison(comparisonDescriptor, info);
David Beckc2044fe2018-09-05 15:00:38 +0100325}
326
Sadik Armagana792a052020-06-23 16:22:23 +0100327std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateFill(const FillQueueDescriptor& descriptor,
328 const WorkloadInfo& info) const
329{
330 return std::make_unique<NeonFillWorkload>(descriptor, info);
331}
332
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100333std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateFloor(const FloorQueueDescriptor& descriptor,
334 const WorkloadInfo& info) const
335{
336 return MakeWorkloadHelper<NeonFloorFloatWorkload, NullWorkload>(descriptor, info);
337}
338
339std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateFullyConnected(
340 const FullyConnectedQueueDescriptor& descriptor, const WorkloadInfo& info) const
341{
Kevin Maybe7e35c2020-04-29 17:05:05 +0100342 return std::make_unique<NeonFullyConnectedWorkload>(descriptor, info, m_MemoryManager->GetIntraLayerManager());
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100343}
344
345std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateGather(const armnn::GatherQueueDescriptor& descriptor,
346 const armnn::WorkloadInfo& info) const
347{
Teresa Charlinf540eb82020-04-10 19:24:55 +0100348 return std::make_unique<NeonGatherWorkload>(descriptor, info);
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100349}
350
351std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateGreater(const GreaterQueueDescriptor& descriptor,
352 const WorkloadInfo& info) const
353{
Jan Eilers8eb25602020-03-09 12:13:48 +0000354 IgnoreUnused(descriptor);
Aron Virginas-Tar77bfb5e2019-10-16 17:45:38 +0100355
356 ComparisonQueueDescriptor comparisonDescriptor;
357 comparisonDescriptor.m_Parameters = ComparisonDescriptor(ComparisonOperation::Greater);
358
359 return CreateComparison(comparisonDescriptor, info);
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100360}
361
362std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateInput(const InputQueueDescriptor& descriptor,
363 const WorkloadInfo& info) const
364{
365 return std::make_unique<CopyMemGenericWorkload>(descriptor, info);
366}
367
368std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateInstanceNormalization(
369 const InstanceNormalizationQueueDescriptor& descriptor,
370 const WorkloadInfo& info) const
371{
372 return std::make_unique<NeonInstanceNormalizationWorkload>(descriptor, info);
373}
374
375std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateL2Normalization(const L2NormalizationQueueDescriptor& descriptor,
376 const WorkloadInfo& info) const
377{
378 return MakeWorkloadHelper<NeonL2NormalizationFloatWorkload, NullWorkload>(descriptor, info,
379 m_MemoryManager->GetIntraLayerManager());
380}
381
Keith Davis69e653f2020-07-02 11:49:26 +0100382std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateLogSoftmax(const LogSoftmaxQueueDescriptor& descriptor,
383 const WorkloadInfo& info) const
384{
385 return std::make_unique<NeonLogSoftmaxWorkload>(descriptor, info, m_MemoryManager->GetIntraLayerManager());
386}
387
James Conroy177df1e2020-11-13 10:18:51 +0000388std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateLogicalBinary(const LogicalBinaryQueueDescriptor& descriptor,
389 const WorkloadInfo& info) const
390{
391 switch(descriptor.m_Parameters.m_Operation)
392 {
393 case LogicalBinaryOperation::LogicalAnd:
394 return std::make_unique<NeonLogicalAndWorkload>(descriptor, info);
395 case LogicalBinaryOperation::LogicalOr:
396 return std::make_unique<NeonLogicalOrWorkload>(descriptor, info);
397 default:
398 return nullptr;
399 }
400}
401
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100402std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateLstm(const LstmQueueDescriptor& descriptor,
403 const WorkloadInfo& info) const
404{
405 return MakeWorkloadHelper<NeonLstmFloatWorkload, NullWorkload>(descriptor, info);
406}
407
408std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateMaximum(const MaximumQueueDescriptor& descriptor,
409 const WorkloadInfo& info) const
410{
411 return std::make_unique<NeonMaximumWorkload>(descriptor, info);
412}
413
414std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateMean(const MeanQueueDescriptor& descriptor,
415 const WorkloadInfo& info) const
416{
417 return std::make_unique<NeonMeanWorkload>(descriptor, info);
telsoa014fcda012018-03-09 14:13:49 +0000418}
419
420std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateMemCopy(const MemCopyQueueDescriptor& descriptor,
421 const WorkloadInfo& info) const
422{
423 if (descriptor.m_Inputs.empty() || !descriptor.m_Inputs[0])
424 {
425 throw InvalidArgumentException("NeonWorkloadFactory: Invalid null input for MemCopy workload");
426 }
427
Aron Virginas-Tara8e06ed2018-10-19 16:46:15 +0100428 return MakeWorkloadHelper<CopyMemGenericWorkload, CopyMemGenericWorkload>(descriptor, info);
telsoa014fcda012018-03-09 14:13:49 +0000429}
430
Derek Lambertif674aa02019-08-01 15:56:25 +0100431std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateMemImport(const MemImportQueueDescriptor& descriptor,
432 const WorkloadInfo& info) const
433{
434 if (descriptor.m_Inputs.empty() || !descriptor.m_Inputs[0])
435 {
436 throw InvalidArgumentException("NeonWorkloadFactory: Invalid null input for MemImport workload");
437 }
438
439 return std::make_unique<ImportMemGenericWorkload>(descriptor, info);
440}
441
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100442std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateMerger(const MergerQueueDescriptor& descriptor,
443 const WorkloadInfo& info) const
444{
445 return CreateConcat(descriptor, info);
446}
447
448std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateMinimum(const MinimumQueueDescriptor& descriptor,
449 const WorkloadInfo& info) const
450{
451 return std::make_unique<NeonMinimumWorkload>(descriptor, info);
452}
453
454std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateMultiplication(
455 const MultiplicationQueueDescriptor& descriptor, const WorkloadInfo& info) const
456{
457 return std::make_unique<NeonMultiplicationWorkload>(descriptor, info);
458}
459
460std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateNormalization(
461 const NormalizationQueueDescriptor& descriptor, const WorkloadInfo& info) const
462{
463 return MakeWorkloadHelper<NeonNormalizationFloatWorkload, NullWorkload>(descriptor, info,
464 m_MemoryManager->GetIntraLayerManager());
465}
466
467std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateOutput(const OutputQueueDescriptor& descriptor,
Keith Davis69e653f2020-07-02 11:49:26 +0100468 const WorkloadInfo& info) const
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100469{
470 return std::make_unique<CopyMemGenericWorkload>(descriptor, info);
471}
472
473std::unique_ptr<IWorkload> NeonWorkloadFactory::CreatePad(const PadQueueDescriptor& descriptor,
474 const WorkloadInfo& info) const
475{
476 return std::make_unique<NeonPadWorkload>(descriptor, info);
477}
478
479std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreatePermute(const PermuteQueueDescriptor& descriptor,
Keith Davis69e653f2020-07-02 11:49:26 +0100480 const WorkloadInfo& info) const
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100481{
482 return std::make_unique<NeonPermuteWorkload>(descriptor, info);
483}
484
485std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreatePooling2d(const Pooling2dQueueDescriptor& descriptor,
Keith Davis69e653f2020-07-02 11:49:26 +0100486 const WorkloadInfo& info) const
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100487{
488 return std::make_unique<NeonPooling2dWorkload>(descriptor, info);
489}
490
491std::unique_ptr<IWorkload> NeonWorkloadFactory::CreatePreCompiled(const PreCompiledQueueDescriptor& descriptor,
492 const WorkloadInfo& info) const
493{
494 return MakeWorkloadHelper<NullWorkload, NullWorkload>(descriptor, info);
495}
496
497std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreatePrelu(const armnn::PreluQueueDescriptor &descriptor,
498 const armnn::WorkloadInfo &info) const
499{
500 return std::make_unique<NeonPreluWorkload>(descriptor, info);
501}
502
James Conroycc340932020-05-12 18:08:52 +0100503std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateQLstm(const QLstmQueueDescriptor& descriptor,
504 const WorkloadInfo& info) const
505{
506 return std::make_unique<NeonQLstmWorkload>(descriptor, info);
507}
508
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100509std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateQuantize(const QuantizeQueueDescriptor& descriptor,
510 const WorkloadInfo& info) const
511{
Kevin May90774732020-03-03 12:10:10 +0000512 return std::make_unique<NeonQuantizeWorkload>(descriptor, info);
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100513}
514
515std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateQuantizedLstm(const QuantizedLstmQueueDescriptor& descriptor,
516 const WorkloadInfo& info) const
517{
518 return std::make_unique<NeonQuantizedLstmWorkload>(descriptor, info);
519}
520
David Monahan97451b42020-12-03 09:48:06 +0000521std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateRank(const RankQueueDescriptor& descriptor,
522 const WorkloadInfo& info) const
523{
524 return std::make_unique<NeonRankWorkload>(descriptor, info);
525}
526
Sadik Armagana2747482021-02-09 10:28:54 +0000527std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateReduce(const ReduceQueueDescriptor& descriptor,
528 const WorkloadInfo& info) const
529{
530 return std::make_unique<NeonReduceWorkload>(descriptor, info);
531}
532
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100533std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateReshape(const ReshapeQueueDescriptor& descriptor,
534 const WorkloadInfo& info) const
535{
536 return std::make_unique<NeonReshapeWorkload>(descriptor, info);
537}
538
Aron Virginas-Tar169d2f12019-07-01 19:01:44 +0100539std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateResize(const ResizeQueueDescriptor& descriptor,
540 const WorkloadInfo& info) const
541{
Ellen Norris-Thompson37e68682019-07-15 14:23:30 +0100542 return std::make_unique<NeonResizeWorkload>(descriptor, info);
Aron Virginas-Tar169d2f12019-07-01 19:01:44 +0100543}
544
telsoa014fcda012018-03-09 14:13:49 +0000545std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateResizeBilinear(
546 const ResizeBilinearQueueDescriptor& descriptor,
547 const WorkloadInfo& info) const
548{
Ellen Norris-Thompson37e68682019-07-15 14:23:30 +0100549 ResizeQueueDescriptor resizeDescriptor;
550 resizeDescriptor.m_Inputs = descriptor.m_Inputs;
551 resizeDescriptor.m_Outputs = descriptor.m_Outputs;
552
553 resizeDescriptor.m_Parameters.m_DataLayout = descriptor.m_Parameters.m_DataLayout;
554 resizeDescriptor.m_Parameters.m_TargetWidth = descriptor.m_Parameters.m_TargetWidth;
555 resizeDescriptor.m_Parameters.m_TargetHeight = descriptor.m_Parameters.m_TargetHeight;
556
557 return CreateResize(resizeDescriptor, info);
telsoa014fcda012018-03-09 14:13:49 +0000558}
559
Mohamed Nour Abouelseouda1d3c6a2018-12-27 12:39:16 +0000560std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateRsqrt(const RsqrtQueueDescriptor &descriptor,
561 const WorkloadInfo &info) const
562{
Jan Eilers8eb25602020-03-09 12:13:48 +0000563 IgnoreUnused(descriptor);
josh minor4a3c6102020-01-06 16:40:46 -0600564
565 ElementwiseUnaryQueueDescriptor elementwiseUnaryDescriptor;
566 elementwiseUnaryDescriptor.m_Parameters = ElementwiseUnaryDescriptor(UnaryOperation::Rsqrt);
567
568 return CreateElementwiseUnary(elementwiseUnaryDescriptor, info);
Mohamed Nour Abouelseouda1d3c6a2018-12-27 12:39:16 +0000569}
570
josh minor036f02d2019-11-15 14:53:22 -0600571std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateSlice(const SliceQueueDescriptor& descriptor,
572 const WorkloadInfo& info) const
573{
574 return std::make_unique<NeonSliceWorkload>(descriptor, info);
575}
576
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100577std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateSoftmax(const SoftmaxQueueDescriptor& descriptor,
578 const WorkloadInfo& info) const
Sadik Armagan581742d2019-08-12 14:11:37 +0100579{
Sadik Armaganbe88a572020-04-30 11:39:37 +0100580 return std::make_unique<NeonSoftmaxWorkload>(descriptor, info, m_MemoryManager->GetIntraLayerManager());
Sadik Armagan581742d2019-08-12 14:11:37 +0100581}
582
Mike Kelly0be3a882020-01-24 11:27:50 +0000583std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateSpaceToBatchNd(const SpaceToBatchNdQueueDescriptor& descriptor,
584 const WorkloadInfo& info) const
585{
586 return std::make_unique<NeonSpaceToBatchNdWorkload>(descriptor, info);
587}
588
589std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateSpaceToDepth(const SpaceToDepthQueueDescriptor& descriptor,
590 const WorkloadInfo& info) const
narpra01b89b05f2019-01-16 09:53:09 +0000591{
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100592 return std::make_unique<NeonSpaceToDepthWorkload>(descriptor, info);
593}
594
595std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateSplitter(const SplitterQueueDescriptor& descriptor,
596 const WorkloadInfo& info) const
597{
598 return std::make_unique<NeonSplitterWorkload>(descriptor, info);
narpra01b89b05f2019-01-16 09:53:09 +0000599}
600
Matthew Jackson87f65ea2019-08-01 10:01:34 +0100601std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateStack(const StackQueueDescriptor& descriptor,
602 const WorkloadInfo& info) const
603{
604 return std::make_unique<NeonStackWorkload>(descriptor, info);
605}
606
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100607std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateStridedSlice(const StridedSliceQueueDescriptor& descriptor,
608 const WorkloadInfo& info) const
James Conroyd47a0642019-09-17 14:22:06 +0100609{
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100610 return std::make_unique<NeonStridedSliceWorkload>(descriptor, info);
611}
612
613std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateSubtraction(
614 const SubtractionQueueDescriptor& descriptor, const WorkloadInfo& info) const
615{
616 return std::make_unique<NeonSubtractionWorkload>(descriptor, info);
617}
618
Mike Kellyc9ea45a2020-02-28 18:11:58 +0000619std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateTranspose(const TransposeQueueDescriptor& descriptor,
620 const WorkloadInfo& info) const
621{
622 return std::make_unique<NeonTransposeWorkload>(descriptor, info);
623}
624
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100625std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateTransposeConvolution2d(
626 const TransposeConvolution2dQueueDescriptor &descriptor,
627 const WorkloadInfo &info) const
628{
629 return std::make_unique<NeonTransposeConvolution2dWorkload>(descriptor, info,
630 m_MemoryManager->GetIntraLayerManager());
James Conroyd47a0642019-09-17 14:22:06 +0100631}
632
Aron Virginas-Tar56055192018-11-12 18:10:43 +0000633} // namespace armnn