blob: 28352011dc8dd644169bf302b0671bff2539f851 [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
Aron Virginas-Tar77bfb5e2019-10-16 17:45:38 +0100175std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateComparison(const ComparisonQueueDescriptor& descriptor,
176 const WorkloadInfo& info) const
177{
Teresa Charlincedd34f2020-03-30 11:17:30 +0100178 return std::make_unique<NeonComparisonWorkload>(descriptor, info);
Aron Virginas-Tar77bfb5e2019-10-16 17:45:38 +0100179}
180
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100181std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateConcat(const ConcatQueueDescriptor& descriptor,
telsoa014fcda012018-03-09 14:13:49 +0000182 const WorkloadInfo& info) const
183{
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100184 return std::make_unique<NeonConcatWorkload>(descriptor, info);
telsoa014fcda012018-03-09 14:13:49 +0000185}
186
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100187std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateConstant(const ConstantQueueDescriptor& descriptor,
188 const WorkloadInfo& info) const
telsoa014fcda012018-03-09 14:13:49 +0000189{
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100190 return std::make_unique<NeonConstantWorkload>(descriptor, info);
telsoa014fcda012018-03-09 14:13:49 +0000191}
192
Narumol Prangnawarat250d3922020-03-30 16:11:04 +0100193std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateConvertBf16ToFp32(
194 const ConvertBf16ToFp32QueueDescriptor& descriptor,
195 const WorkloadInfo& info) const
196{
197 return std::make_unique<NeonConvertBf16ToFp32Workload>(descriptor, info);
198}
199
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100200std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateConvertFp16ToFp32(
201 const ConvertFp16ToFp32QueueDescriptor& descriptor,
202 const WorkloadInfo& info) const
telsoa014fcda012018-03-09 14:13:49 +0000203{
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100204 return std::make_unique<NeonConvertFp16ToFp32Workload>(descriptor, info);
telsoa014fcda012018-03-09 14:13:49 +0000205}
206
Narumol Prangnawarat250d3922020-03-30 16:11:04 +0100207std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateConvertFp32ToBf16(
208 const ConvertFp32ToBf16QueueDescriptor& descriptor,
209 const WorkloadInfo& info) const
210{
211 return std::make_unique<NeonConvertFp32ToBf16Workload>(descriptor, info);
212}
213
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100214std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateConvertFp32ToFp16(
215 const ConvertFp32ToFp16QueueDescriptor& descriptor,
216 const WorkloadInfo& info) const
telsoa014fcda012018-03-09 14:13:49 +0000217{
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100218 return std::make_unique<NeonConvertFp32ToFp16Workload>(descriptor, info);
Nikhil Raj9b461482019-07-03 15:58:31 +0100219}
220
telsoa014fcda012018-03-09 14:13:49 +0000221std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateConvolution2d(
222 const Convolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) const
223{
Sadik Armagan04a72972020-09-14 15:44:18 +0100224 bool isFastMathEnabled = false;
225 if (m_ModelContextPtr)
226 {
227 if (m_ModelContextPtr.get() != nullptr)
228 {
229 auto modelOptions = dynamic_cast<NeonBackendModelContext*>(m_ModelContextPtr.get());
230 if (modelOptions)
231 {
232 isFastMathEnabled = modelOptions->IsFastMathEnabled();
233 }
234 }
235 }
236 return std::make_unique<NeonConvolution2dWorkload>(descriptor,
237 info,
238 m_MemoryManager->GetIntraLayerManager(),
239 isFastMathEnabled);
telsoa014fcda012018-03-09 14:13:49 +0000240}
241
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100242std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateDebug(const DebugQueueDescriptor& descriptor,
243 const WorkloadInfo& info) const
244{
245 return MakeWorkloadHelper<NullWorkload, NullWorkload>(descriptor, info);
246}
247
Aron Virginas-Tar2f00b742019-09-30 13:28:08 +0100248std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateDepthToSpace(const DepthToSpaceQueueDescriptor& descriptor,
249 const WorkloadInfo& info) const
250{
251 return std::make_unique<NeonDepthToSpaceWorkload>(descriptor, info);
252}
253
telsoa014fcda012018-03-09 14:13:49 +0000254std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateDepthwiseConvolution2d(
255 const DepthwiseConvolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) const
256{
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100257 return std::make_unique<NeonDepthwiseConvolutionWorkload>(descriptor, info);
telsoa014fcda012018-03-09 14:13:49 +0000258}
259
Narumol Prangnawarat01961a72019-05-30 16:47:12 +0100260std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateDequantize(const DequantizeQueueDescriptor& descriptor,
261 const WorkloadInfo& info) const
262{
263 return std::make_unique<NeonDequantizeWorkload>(descriptor, info);
264}
265
Narumol Prangnawarat94dd5d82019-01-23 18:06:26 +0000266std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateDetectionPostProcess(
267 const armnn::DetectionPostProcessQueueDescriptor& descriptor, const armnn::WorkloadInfo& info) const
268{
James Conroyd9fb6e22020-02-21 16:52:44 +0000269 return MakeWorkloadHelper<NullWorkload, NullWorkload>(descriptor, info);
Narumol Prangnawarat94dd5d82019-01-23 18:06:26 +0000270}
271
Francis Murtaghe7a86a42018-08-29 12:42:10 +0100272std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateDivision(
273 const DivisionQueueDescriptor& descriptor, const WorkloadInfo& info) const
274{
Pablo Telloe61f0712020-01-23 10:37:17 +0000275 return std::make_unique<NeonDivisionWorkload>(descriptor, info);
Francis Murtaghe7a86a42018-08-29 12:42:10 +0100276}
277
Sadik Armaganac472102020-03-24 09:54:36 +0000278std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateElementwiseUnary(
279 const ElementwiseUnaryQueueDescriptor& descriptor, const WorkloadInfo& info) const
josh minor4a3c6102020-01-06 16:40:46 -0600280{
Derek Lambertic77874a2020-04-28 13:34:56 +0100281 switch(descriptor.m_Parameters.m_Operation)
josh minor4a3c6102020-01-06 16:40:46 -0600282 {
Derek Lambertic77874a2020-04-28 13:34:56 +0100283 case UnaryOperation::Abs:
James Conroy177df1e2020-11-13 10:18:51 +0000284 {
285 AbsQueueDescriptor absQueueDescriptor;
286 absQueueDescriptor.m_Inputs = descriptor.m_Inputs;
287 absQueueDescriptor.m_Outputs = descriptor.m_Outputs;
josh minor4a3c6102020-01-06 16:40:46 -0600288
James Conroy177df1e2020-11-13 10:18:51 +0000289 return std::make_unique<NeonAbsWorkload>(absQueueDescriptor, info);
290 }
Derek Lambertic77874a2020-04-28 13:34:56 +0100291 case UnaryOperation::Rsqrt:
James Conroy177df1e2020-11-13 10:18:51 +0000292 {
293 RsqrtQueueDescriptor rsqrtQueueDescriptor;
294 rsqrtQueueDescriptor.m_Inputs = descriptor.m_Inputs;
295 rsqrtQueueDescriptor.m_Outputs = descriptor.m_Outputs;
josh minor4a3c6102020-01-06 16:40:46 -0600296
James Conroy177df1e2020-11-13 10:18:51 +0000297 return std::make_unique<NeonRsqrtWorkload>(rsqrtQueueDescriptor, info);
298 }
Derek Lambertic77874a2020-04-28 13:34:56 +0100299 case UnaryOperation::Neg:
300 return std::make_unique<NeonNegWorkload>(descriptor, info);
301 case UnaryOperation::Exp:
302 return std::make_unique<NeonExpWorkload>(descriptor, info);
James Conroy177df1e2020-11-13 10:18:51 +0000303 case UnaryOperation::LogicalNot:
304 return std::make_unique<NeonLogicalNotWorkload>(descriptor, info);
Derek Lambertic77874a2020-04-28 13:34:56 +0100305 default:
306 return nullptr;
josh minor4a3c6102020-01-06 16:40:46 -0600307 }
josh minor4a3c6102020-01-06 16:40:46 -0600308}
309
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100310std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateEqual(const EqualQueueDescriptor& descriptor,
311 const WorkloadInfo& info) const
David Beckc2044fe2018-09-05 15:00:38 +0100312{
Jan Eilers8eb25602020-03-09 12:13:48 +0000313 IgnoreUnused(descriptor);
Aron Virginas-Tar77bfb5e2019-10-16 17:45:38 +0100314
315 ComparisonQueueDescriptor comparisonDescriptor;
316 comparisonDescriptor.m_Parameters = ComparisonDescriptor(ComparisonOperation::Equal);
317
318 return CreateComparison(comparisonDescriptor, info);
David Beckc2044fe2018-09-05 15:00:38 +0100319}
320
Sadik Armagana792a052020-06-23 16:22:23 +0100321std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateFill(const FillQueueDescriptor& descriptor,
322 const WorkloadInfo& info) const
323{
324 return std::make_unique<NeonFillWorkload>(descriptor, info);
325}
326
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100327std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateFloor(const FloorQueueDescriptor& descriptor,
328 const WorkloadInfo& info) const
329{
330 return MakeWorkloadHelper<NeonFloorFloatWorkload, NullWorkload>(descriptor, info);
331}
332
333std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateFullyConnected(
334 const FullyConnectedQueueDescriptor& descriptor, const WorkloadInfo& info) const
335{
Kevin Maybe7e35c2020-04-29 17:05:05 +0100336 return std::make_unique<NeonFullyConnectedWorkload>(descriptor, info, m_MemoryManager->GetIntraLayerManager());
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100337}
338
339std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateGather(const armnn::GatherQueueDescriptor& descriptor,
340 const armnn::WorkloadInfo& info) const
341{
Teresa Charlinf540eb82020-04-10 19:24:55 +0100342 return std::make_unique<NeonGatherWorkload>(descriptor, info);
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100343}
344
345std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateGreater(const GreaterQueueDescriptor& descriptor,
346 const WorkloadInfo& info) const
347{
Jan Eilers8eb25602020-03-09 12:13:48 +0000348 IgnoreUnused(descriptor);
Aron Virginas-Tar77bfb5e2019-10-16 17:45:38 +0100349
350 ComparisonQueueDescriptor comparisonDescriptor;
351 comparisonDescriptor.m_Parameters = ComparisonDescriptor(ComparisonOperation::Greater);
352
353 return CreateComparison(comparisonDescriptor, info);
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100354}
355
356std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateInput(const InputQueueDescriptor& descriptor,
357 const WorkloadInfo& info) const
358{
359 return std::make_unique<CopyMemGenericWorkload>(descriptor, info);
360}
361
362std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateInstanceNormalization(
363 const InstanceNormalizationQueueDescriptor& descriptor,
364 const WorkloadInfo& info) const
365{
366 return std::make_unique<NeonInstanceNormalizationWorkload>(descriptor, info);
367}
368
369std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateL2Normalization(const L2NormalizationQueueDescriptor& descriptor,
370 const WorkloadInfo& info) const
371{
372 return MakeWorkloadHelper<NeonL2NormalizationFloatWorkload, NullWorkload>(descriptor, info,
373 m_MemoryManager->GetIntraLayerManager());
374}
375
Keith Davis69e653f2020-07-02 11:49:26 +0100376std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateLogSoftmax(const LogSoftmaxQueueDescriptor& descriptor,
377 const WorkloadInfo& info) const
378{
379 return std::make_unique<NeonLogSoftmaxWorkload>(descriptor, info, m_MemoryManager->GetIntraLayerManager());
380}
381
James Conroy177df1e2020-11-13 10:18:51 +0000382std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateLogicalBinary(const LogicalBinaryQueueDescriptor& descriptor,
383 const WorkloadInfo& info) const
384{
385 switch(descriptor.m_Parameters.m_Operation)
386 {
387 case LogicalBinaryOperation::LogicalAnd:
388 return std::make_unique<NeonLogicalAndWorkload>(descriptor, info);
389 case LogicalBinaryOperation::LogicalOr:
390 return std::make_unique<NeonLogicalOrWorkload>(descriptor, info);
391 default:
392 return nullptr;
393 }
394}
395
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100396std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateLstm(const LstmQueueDescriptor& descriptor,
397 const WorkloadInfo& info) const
398{
399 return MakeWorkloadHelper<NeonLstmFloatWorkload, NullWorkload>(descriptor, info);
400}
401
402std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateMaximum(const MaximumQueueDescriptor& descriptor,
403 const WorkloadInfo& info) const
404{
405 return std::make_unique<NeonMaximumWorkload>(descriptor, info);
406}
407
408std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateMean(const MeanQueueDescriptor& descriptor,
409 const WorkloadInfo& info) const
410{
411 return std::make_unique<NeonMeanWorkload>(descriptor, info);
telsoa014fcda012018-03-09 14:13:49 +0000412}
413
414std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateMemCopy(const MemCopyQueueDescriptor& descriptor,
415 const WorkloadInfo& info) const
416{
417 if (descriptor.m_Inputs.empty() || !descriptor.m_Inputs[0])
418 {
419 throw InvalidArgumentException("NeonWorkloadFactory: Invalid null input for MemCopy workload");
420 }
421
Aron Virginas-Tara8e06ed2018-10-19 16:46:15 +0100422 return MakeWorkloadHelper<CopyMemGenericWorkload, CopyMemGenericWorkload>(descriptor, info);
telsoa014fcda012018-03-09 14:13:49 +0000423}
424
Derek Lambertif674aa02019-08-01 15:56:25 +0100425std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateMemImport(const MemImportQueueDescriptor& descriptor,
426 const WorkloadInfo& info) const
427{
428 if (descriptor.m_Inputs.empty() || !descriptor.m_Inputs[0])
429 {
430 throw InvalidArgumentException("NeonWorkloadFactory: Invalid null input for MemImport workload");
431 }
432
433 return std::make_unique<ImportMemGenericWorkload>(descriptor, info);
434}
435
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100436std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateMerger(const MergerQueueDescriptor& descriptor,
437 const WorkloadInfo& info) const
438{
439 return CreateConcat(descriptor, info);
440}
441
442std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateMinimum(const MinimumQueueDescriptor& descriptor,
443 const WorkloadInfo& info) const
444{
445 return std::make_unique<NeonMinimumWorkload>(descriptor, info);
446}
447
448std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateMultiplication(
449 const MultiplicationQueueDescriptor& descriptor, const WorkloadInfo& info) const
450{
451 return std::make_unique<NeonMultiplicationWorkload>(descriptor, info);
452}
453
454std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateNormalization(
455 const NormalizationQueueDescriptor& descriptor, const WorkloadInfo& info) const
456{
457 return MakeWorkloadHelper<NeonNormalizationFloatWorkload, NullWorkload>(descriptor, info,
458 m_MemoryManager->GetIntraLayerManager());
459}
460
461std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateOutput(const OutputQueueDescriptor& descriptor,
Keith Davis69e653f2020-07-02 11:49:26 +0100462 const WorkloadInfo& info) const
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100463{
464 return std::make_unique<CopyMemGenericWorkload>(descriptor, info);
465}
466
467std::unique_ptr<IWorkload> NeonWorkloadFactory::CreatePad(const PadQueueDescriptor& descriptor,
468 const WorkloadInfo& info) const
469{
470 return std::make_unique<NeonPadWorkload>(descriptor, info);
471}
472
473std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreatePermute(const PermuteQueueDescriptor& descriptor,
Keith Davis69e653f2020-07-02 11:49:26 +0100474 const WorkloadInfo& info) const
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100475{
476 return std::make_unique<NeonPermuteWorkload>(descriptor, info);
477}
478
479std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreatePooling2d(const Pooling2dQueueDescriptor& 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<NeonPooling2dWorkload>(descriptor, info);
483}
484
485std::unique_ptr<IWorkload> NeonWorkloadFactory::CreatePreCompiled(const PreCompiledQueueDescriptor& descriptor,
486 const WorkloadInfo& info) const
487{
488 return MakeWorkloadHelper<NullWorkload, NullWorkload>(descriptor, info);
489}
490
491std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreatePrelu(const armnn::PreluQueueDescriptor &descriptor,
492 const armnn::WorkloadInfo &info) const
493{
494 return std::make_unique<NeonPreluWorkload>(descriptor, info);
495}
496
James Conroycc340932020-05-12 18:08:52 +0100497std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateQLstm(const QLstmQueueDescriptor& descriptor,
498 const WorkloadInfo& info) const
499{
500 return std::make_unique<NeonQLstmWorkload>(descriptor, info);
501}
502
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100503std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateQuantize(const QuantizeQueueDescriptor& descriptor,
504 const WorkloadInfo& info) const
505{
Kevin May90774732020-03-03 12:10:10 +0000506 return std::make_unique<NeonQuantizeWorkload>(descriptor, info);
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100507}
508
509std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateQuantizedLstm(const QuantizedLstmQueueDescriptor& descriptor,
510 const WorkloadInfo& info) const
511{
512 return std::make_unique<NeonQuantizedLstmWorkload>(descriptor, info);
513}
514
David Monahan97451b42020-12-03 09:48:06 +0000515std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateRank(const RankQueueDescriptor& descriptor,
516 const WorkloadInfo& info) const
517{
518 return std::make_unique<NeonRankWorkload>(descriptor, info);
519}
520
Sadik Armagana2747482021-02-09 10:28:54 +0000521std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateReduce(const ReduceQueueDescriptor& descriptor,
522 const WorkloadInfo& info) const
523{
524 return std::make_unique<NeonReduceWorkload>(descriptor, info);
525}
526
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100527std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateReshape(const ReshapeQueueDescriptor& descriptor,
528 const WorkloadInfo& info) const
529{
530 return std::make_unique<NeonReshapeWorkload>(descriptor, info);
531}
532
Aron Virginas-Tar169d2f12019-07-01 19:01:44 +0100533std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateResize(const ResizeQueueDescriptor& descriptor,
534 const WorkloadInfo& info) const
535{
Ellen Norris-Thompson37e68682019-07-15 14:23:30 +0100536 return std::make_unique<NeonResizeWorkload>(descriptor, info);
Aron Virginas-Tar169d2f12019-07-01 19:01:44 +0100537}
538
telsoa014fcda012018-03-09 14:13:49 +0000539std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateResizeBilinear(
540 const ResizeBilinearQueueDescriptor& descriptor,
541 const WorkloadInfo& info) const
542{
Ellen Norris-Thompson37e68682019-07-15 14:23:30 +0100543 ResizeQueueDescriptor resizeDescriptor;
544 resizeDescriptor.m_Inputs = descriptor.m_Inputs;
545 resizeDescriptor.m_Outputs = descriptor.m_Outputs;
546
547 resizeDescriptor.m_Parameters.m_DataLayout = descriptor.m_Parameters.m_DataLayout;
548 resizeDescriptor.m_Parameters.m_TargetWidth = descriptor.m_Parameters.m_TargetWidth;
549 resizeDescriptor.m_Parameters.m_TargetHeight = descriptor.m_Parameters.m_TargetHeight;
550
551 return CreateResize(resizeDescriptor, info);
telsoa014fcda012018-03-09 14:13:49 +0000552}
553
Mohamed Nour Abouelseouda1d3c6a2018-12-27 12:39:16 +0000554std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateRsqrt(const RsqrtQueueDescriptor &descriptor,
555 const WorkloadInfo &info) const
556{
Jan Eilers8eb25602020-03-09 12:13:48 +0000557 IgnoreUnused(descriptor);
josh minor4a3c6102020-01-06 16:40:46 -0600558
559 ElementwiseUnaryQueueDescriptor elementwiseUnaryDescriptor;
560 elementwiseUnaryDescriptor.m_Parameters = ElementwiseUnaryDescriptor(UnaryOperation::Rsqrt);
561
562 return CreateElementwiseUnary(elementwiseUnaryDescriptor, info);
Mohamed Nour Abouelseouda1d3c6a2018-12-27 12:39:16 +0000563}
564
josh minor036f02d2019-11-15 14:53:22 -0600565std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateSlice(const SliceQueueDescriptor& descriptor,
566 const WorkloadInfo& info) const
567{
568 return std::make_unique<NeonSliceWorkload>(descriptor, info);
569}
570
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100571std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateSoftmax(const SoftmaxQueueDescriptor& descriptor,
572 const WorkloadInfo& info) const
Sadik Armagan581742d2019-08-12 14:11:37 +0100573{
Sadik Armaganbe88a572020-04-30 11:39:37 +0100574 return std::make_unique<NeonSoftmaxWorkload>(descriptor, info, m_MemoryManager->GetIntraLayerManager());
Sadik Armagan581742d2019-08-12 14:11:37 +0100575}
576
Mike Kelly0be3a882020-01-24 11:27:50 +0000577std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateSpaceToBatchNd(const SpaceToBatchNdQueueDescriptor& descriptor,
578 const WorkloadInfo& info) const
579{
580 return std::make_unique<NeonSpaceToBatchNdWorkload>(descriptor, info);
581}
582
583std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateSpaceToDepth(const SpaceToDepthQueueDescriptor& descriptor,
584 const WorkloadInfo& info) const
narpra01b89b05f2019-01-16 09:53:09 +0000585{
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100586 return std::make_unique<NeonSpaceToDepthWorkload>(descriptor, info);
587}
588
589std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateSplitter(const SplitterQueueDescriptor& descriptor,
590 const WorkloadInfo& info) const
591{
592 return std::make_unique<NeonSplitterWorkload>(descriptor, info);
narpra01b89b05f2019-01-16 09:53:09 +0000593}
594
Matthew Jackson87f65ea2019-08-01 10:01:34 +0100595std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateStack(const StackQueueDescriptor& descriptor,
596 const WorkloadInfo& info) const
597{
598 return std::make_unique<NeonStackWorkload>(descriptor, info);
599}
600
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100601std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateStridedSlice(const StridedSliceQueueDescriptor& descriptor,
602 const WorkloadInfo& info) const
James Conroyd47a0642019-09-17 14:22:06 +0100603{
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100604 return std::make_unique<NeonStridedSliceWorkload>(descriptor, info);
605}
606
607std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateSubtraction(
608 const SubtractionQueueDescriptor& descriptor, const WorkloadInfo& info) const
609{
610 return std::make_unique<NeonSubtractionWorkload>(descriptor, info);
611}
612
Mike Kellyc9ea45a2020-02-28 18:11:58 +0000613std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateTranspose(const TransposeQueueDescriptor& descriptor,
614 const WorkloadInfo& info) const
615{
616 return std::make_unique<NeonTransposeWorkload>(descriptor, info);
617}
618
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100619std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateTransposeConvolution2d(
620 const TransposeConvolution2dQueueDescriptor &descriptor,
621 const WorkloadInfo &info) const
622{
623 return std::make_unique<NeonTransposeConvolution2dWorkload>(descriptor, info,
624 m_MemoryManager->GetIntraLayerManager());
James Conroyd47a0642019-09-17 14:22:06 +0100625}
626
Aron Virginas-Tar56055192018-11-12 18:10:43 +0000627} // namespace armnn