blob: 8e3bbe468f1da9ff2795ca8347e69f446f7eed8b [file] [log] [blame]
Laurent Carlier749294b2020-06-01 09:03:17 +01001//
telsoa014fcda012018-03-09 14:13:49 +00002// Copyright © 2017 Arm Ltd. All rights reserved.
David Beckecb56cd2018-09-05 12:52:57 +01003// SPDX-License-Identifier: MIT
telsoa014fcda012018-03-09 14:13:49 +00004//
Matthew Bentham4cefc412019-06-18 16:14:34 +01005#include <Layer.hpp>
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +00006#include <backendsCommon/MemCopyWorkload.hpp>
Derek Lambertif674aa02019-08-01 15:56:25 +01007#include <backendsCommon/MemImportWorkload.hpp>
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +00008#include <backendsCommon/MakeWorkloadHelper.hpp>
James Conroy1f58f032021-04-27 17:13:27 +01009#include <backendsCommon/TensorHandle.hpp>
Ryan OSheaf4bfa6a2020-06-10 11:33:37 +010010#include <reference/workloads/RefFillWorkload.hpp>
telsoa014fcda012018-03-09 14:13:49 +000011#include "RefWorkloadFactory.hpp"
David Beck79141b92018-10-23 16:09:36 +010012#include "RefBackendId.hpp"
David Beckb4540be2018-09-24 13:18:27 +010013#include "workloads/RefWorkloads.hpp"
Matthew Bentham4cefc412019-06-18 16:14:34 +010014#include "RefTensorHandle.hpp"
telsoa014fcda012018-03-09 14:13:49 +000015
telsoa014fcda012018-03-09 14:13:49 +000016
17namespace armnn
18{
19
David Beck79141b92018-10-23 16:09:36 +010020namespace
21{
22static const BackendId s_Id{RefBackendId()};
23}
telsoa014fcda012018-03-09 14:13:49 +000024template <typename F32Workload, typename U8Workload, typename QueueDescriptorType>
25std::unique_ptr<IWorkload> RefWorkloadFactory::MakeWorkload(const QueueDescriptorType& descriptor,
Aron Virginas-Tare662a942019-10-14 15:12:00 +010026 const WorkloadInfo& info) const
telsoa014fcda012018-03-09 14:13:49 +000027{
Keith Davis5204aa82020-01-27 15:24:59 +000028 return MakeWorkloadHelper<NullWorkload, F32Workload, U8Workload, NullWorkload, NullWorkload, NullWorkload>
29 (descriptor, info);
telsoa014fcda012018-03-09 14:13:49 +000030}
31
Ferran Balaguerd73d14f2019-06-10 10:29:54 +010032template <DataType ArmnnType>
33bool IsDataType(const WorkloadInfo& info)
Jim Flynn82fbe7c2019-04-02 15:19:08 +010034{
Ferran Balaguerd73d14f2019-06-10 10:29:54 +010035 auto checkType = [](const TensorInfo& tensorInfo) {return tensorInfo.GetDataType() == ArmnnType;};
36 auto it = std::find_if(std::begin(info.m_InputTensorInfos), std::end(info.m_InputTensorInfos), checkType);
Jim Flynn82fbe7c2019-04-02 15:19:08 +010037 if (it != std::end(info.m_InputTensorInfos))
38 {
39 return true;
40 }
Ferran Balaguerd73d14f2019-06-10 10:29:54 +010041 it = std::find_if(std::begin(info.m_OutputTensorInfos), std::end(info.m_OutputTensorInfos), checkType);
Jim Flynn82fbe7c2019-04-02 15:19:08 +010042 if (it != std::end(info.m_OutputTensorInfos))
43 {
44 return true;
45 }
46 return false;
47}
48
Keith Davis0c2eeac2020-02-11 16:51:50 +000049bool IsSigned32(const WorkloadInfo& info)
50{
51 return IsDataType<DataType::Signed32>(info);
52}
53
Narumol Prangnawarat44179c32020-03-11 14:51:27 +000054bool IsBFloat16(const WorkloadInfo& info)
55{
56 return IsDataType<DataType::BFloat16>(info);
57}
58
Ferran Balaguerd73d14f2019-06-10 10:29:54 +010059bool IsFloat16(const WorkloadInfo& info)
60{
61 return IsDataType<DataType::Float16>(info);
62}
63
Keith Davis0c2eeac2020-02-11 16:51:50 +000064bool IsQSymmS16(const WorkloadInfo& info)
nikraj0199a66312019-06-06 10:31:27 +010065{
Derek Lambertif90c56d2020-01-10 17:14:08 +000066 return IsDataType<DataType::QSymmS16>(info);
nikraj0199a66312019-06-06 10:31:27 +010067}
68
Keith Davis0c2eeac2020-02-11 16:51:50 +000069bool IsQSymmS8(const WorkloadInfo& info)
Keith Davis5204aa82020-01-27 15:24:59 +000070{
71 return IsDataType<DataType::QSymmS8>(info);
72}
73
Keith Davis67e6c542020-02-19 10:08:33 +000074bool IsQAsymmS8(const WorkloadInfo& info)
75{
76 return IsDataType<DataType::QAsymmS8>(info);
77}
78
79bool IsQAsymmU8(const WorkloadInfo& info)
80{
81 return IsDataType<DataType::QAsymmU8>(info);
82}
83
Matthew Bentham7c1603a2019-06-21 17:22:23 +010084RefWorkloadFactory::RefWorkloadFactory(const std::shared_ptr<RefMemoryManager>& memoryManager)
85 : m_MemoryManager(memoryManager)
86{
87}
88
telsoa01c577f2c2018-08-31 09:22:23 +010089RefWorkloadFactory::RefWorkloadFactory()
Matthew Bentham7c1603a2019-06-21 17:22:23 +010090 : m_MemoryManager(new RefMemoryManager())
telsoa014fcda012018-03-09 14:13:49 +000091{
92}
93
David Beck79141b92018-10-23 16:09:36 +010094const BackendId& RefWorkloadFactory::GetBackendId() const
95{
96 return s_Id;
97}
98
David Beck29c75de2018-10-23 13:35:58 +010099bool RefWorkloadFactory::IsLayerSupported(const Layer& layer,
100 Optional<DataType> dataType,
telsoa01c577f2c2018-08-31 09:22:23 +0100101 std::string& outReasonIfUnsupported)
telsoa014fcda012018-03-09 14:13:49 +0000102{
David Beck79141b92018-10-23 16:09:36 +0100103 return IWorkloadFactory::IsLayerSupported(s_Id, layer, dataType, outReasonIfUnsupported);
telsoa014fcda012018-03-09 14:13:49 +0000104}
105
Sadik Armagan04a72972020-09-14 15:44:18 +0100106bool RefWorkloadFactory::IsLayerSupported(const IConnectableLayer& layer,
107 Optional<DataType> dataType,
108 std::string& outReasonIfUnsupported,
109 const ModelOptions& modelOptions)
110{
111 return IWorkloadFactory::IsLayerSupported(s_Id, layer, dataType, outReasonIfUnsupported, modelOptions);
112}
113
David Monahan3fb7e102019-08-20 11:25:29 +0100114std::unique_ptr<ITensorHandle> RefWorkloadFactory::CreateTensorHandle(const TensorInfo& tensorInfo,
Derek Lamberti901ea112019-12-10 22:07:09 +0000115 const bool isMemoryManaged) const
telsoa014fcda012018-03-09 14:13:49 +0000116{
David Monahan3fb7e102019-08-20 11:25:29 +0100117 // For Ref it is okay to make the TensorHandle memory managed as it can also store a pointer
118 // to unmanaged memory. This also ensures memory alignment.
Jan Eilers8eb25602020-03-09 12:13:48 +0000119 IgnoreUnused(isMemoryManaged);
Matthew Bentham7c1603a2019-06-21 17:22:23 +0100120 return std::make_unique<RefTensorHandle>(tensorInfo, m_MemoryManager);
telsoa014fcda012018-03-09 14:13:49 +0000121}
122
Francis Murtagh351d13d2018-09-24 15:01:18 +0100123std::unique_ptr<ITensorHandle> RefWorkloadFactory::CreateTensorHandle(const TensorInfo& tensorInfo,
David Monahan3fb7e102019-08-20 11:25:29 +0100124 DataLayout dataLayout,
Derek Lamberti901ea112019-12-10 22:07:09 +0000125 const bool isMemoryManaged) const
Francis Murtagh351d13d2018-09-24 15:01:18 +0100126{
David Monahan3fb7e102019-08-20 11:25:29 +0100127 // For Ref it is okay to make the TensorHandle memory managed as it can also store a pointer
128 // to unmanaged memory. This also ensures memory alignment.
Jan Eilers8eb25602020-03-09 12:13:48 +0000129 IgnoreUnused(isMemoryManaged, dataLayout);
Matthew Bentham7c1603a2019-06-21 17:22:23 +0100130 return std::make_unique<RefTensorHandle>(tensorInfo, m_MemoryManager);
Francis Murtagh351d13d2018-09-24 15:01:18 +0100131}
132
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100133std::unique_ptr<IWorkload> RefWorkloadFactory::CreateAbs(const AbsQueueDescriptor& descriptor,
134 const WorkloadInfo& info) const
135{
Jan Eilers8eb25602020-03-09 12:13:48 +0000136 IgnoreUnused(descriptor);
josh minor4a3c6102020-01-06 16:40:46 -0600137 ElementwiseUnaryQueueDescriptor elementwiseUnaryDescriptor;
138 elementwiseUnaryDescriptor.m_Parameters.m_Operation = UnaryOperation::Abs;
139
140 return CreateElementwiseUnary(elementwiseUnaryDescriptor, info);
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100141}
142
143std::unique_ptr<IWorkload> RefWorkloadFactory::CreateActivation(const ActivationQueueDescriptor& descriptor,
144 const WorkloadInfo& info) const
145{
146 return std::make_unique<RefActivationWorkload>(descriptor, info);
147}
148
149std::unique_ptr<IWorkload> RefWorkloadFactory::CreateAddition(const AdditionQueueDescriptor& descriptor,
150 const WorkloadInfo& info) const
151{
Finn Williamscbd2c232020-06-22 15:58:32 +0100152 if (info.m_InputTensorInfos[0].GetDataType() == armnn::DataType::Signed32)
153 {
154 return std::make_unique<RefAdditionWorkload<int32_t>>(descriptor, info);
155 }
156 else
157 {
158 return std::make_unique<RefAdditionWorkload<float>>(descriptor, info);
159 }
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100160}
161
162std::unique_ptr<IWorkload> RefWorkloadFactory::CreateArgMinMax(const ArgMinMaxQueueDescriptor& descriptor,
163 const WorkloadInfo& info) const
164{
165 return std::make_unique<RefArgMinMaxWorkload>(descriptor, info);
166}
167
168std::unique_ptr<IWorkload> RefWorkloadFactory::CreateBatchNormalization(
169 const BatchNormalizationQueueDescriptor& descriptor,
170 const WorkloadInfo& info) const
171{
172 return std::make_unique<RefBatchNormalizationWorkload>(descriptor, info);
173}
174
175std::unique_ptr<IWorkload> RefWorkloadFactory::CreateBatchToSpaceNd(const BatchToSpaceNdQueueDescriptor& descriptor,
176 const WorkloadInfo& info) const
177{
178 return std::make_unique<RefBatchToSpaceNdWorkload>(descriptor, info);
179}
180
mathad01b392e982021-04-07 12:07:30 +0100181std::unique_ptr<IWorkload> RefWorkloadFactory::CreateCast(const CastQueueDescriptor& descriptor,
182 const WorkloadInfo& info) const
183{
184 return std::make_unique<RefCastWorkload>(descriptor, info);
185}
186
Aron Virginas-Tar77bfb5e2019-10-16 17:45:38 +0100187std::unique_ptr<IWorkload> RefWorkloadFactory::CreateComparison(const ComparisonQueueDescriptor& descriptor,
188 const WorkloadInfo& info) const
189{
190 return std::make_unique<RefComparisonWorkload>(descriptor, info);
191}
192
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100193std::unique_ptr<IWorkload> RefWorkloadFactory::CreateConcat(const ConcatQueueDescriptor& descriptor,
194 const WorkloadInfo& info) const
195{
196 return std::make_unique<RefConcatWorkload>(descriptor, info);
197}
198
199std::unique_ptr<IWorkload> RefWorkloadFactory::CreateConstant(const ConstantQueueDescriptor& descriptor,
200 const WorkloadInfo& info) const
201{
202 return std::make_unique<RefConstantWorkload>(descriptor, info);
203}
204
Narumol Prangnawarat7ddbbae2020-03-13 10:26:05 +0000205std::unique_ptr<IWorkload> RefWorkloadFactory::CreateConvertBf16ToFp32(
206 const ConvertBf16ToFp32QueueDescriptor& descriptor,
207 const WorkloadInfo& info) const
208{
209 return std::make_unique<RefConvertBf16ToFp32Workload>(descriptor, info);
210}
211
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100212std::unique_ptr<IWorkload> RefWorkloadFactory::CreateConvertFp16ToFp32(
213 const ConvertFp16ToFp32QueueDescriptor& descriptor,
214 const WorkloadInfo& info) const
215{
216 return std::make_unique<RefConvertFp16ToFp32Workload>(descriptor, info);
217}
218
Narumol Prangnawaratea54a012020-03-16 16:36:10 +0000219std::unique_ptr<IWorkload> RefWorkloadFactory::CreateConvertFp32ToBf16(
220 const ConvertFp32ToBf16QueueDescriptor& descriptor,
221 const WorkloadInfo& info) const
222{
223 return std::make_unique<RefConvertFp32ToBf16Workload>(descriptor, info);
224}
225
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100226std::unique_ptr<IWorkload> RefWorkloadFactory::CreateConvertFp32ToFp16(
227 const ConvertFp32ToFp16QueueDescriptor& descriptor,
228 const WorkloadInfo& info) const
229{
230 return std::make_unique<RefConvertFp32ToFp16Workload>(descriptor, info);
231}
232
233std::unique_ptr<IWorkload> RefWorkloadFactory::CreateConvolution2d(const Convolution2dQueueDescriptor& descriptor,
234 const WorkloadInfo& info) const
235{
236 return std::make_unique<RefConvolution2dWorkload>(descriptor, info);
237}
238
239std::unique_ptr<IWorkload> RefWorkloadFactory::CreateDebug(const DebugQueueDescriptor& descriptor,
240 const WorkloadInfo& info) const
241{
Narumol Prangnawarat403a1852020-03-12 14:24:13 +0000242 if (IsBFloat16(info))
243 {
244 return std::make_unique<RefDebugBFloat16Workload>(descriptor, info);
245 }
Aron Virginas-Tardb1a2832019-11-12 16:15:11 +0000246 if (IsFloat16(info))
247 {
248 return std::make_unique<RefDebugFloat16Workload>(descriptor, info);
249 }
Keith Davis0c2eeac2020-02-11 16:51:50 +0000250 if (IsQSymmS16(info))
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100251 {
Keith Davis0c2eeac2020-02-11 16:51:50 +0000252 return std::make_unique<RefDebugQSymmS16Workload>(descriptor, info);
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100253 }
Keith Davis0c2eeac2020-02-11 16:51:50 +0000254 if (IsQSymmS8(info))
Keith Davis5204aa82020-01-27 15:24:59 +0000255 {
Keith Davis0c2eeac2020-02-11 16:51:50 +0000256 return std::make_unique<RefDebugQSymmS8Workload>(descriptor, info);
Keith Davis5204aa82020-01-27 15:24:59 +0000257 }
Keith Davis67e6c542020-02-19 10:08:33 +0000258 if (IsQAsymmU8(info))
259 {
260 return std::make_unique<RefDebugQAsymmU8Workload>(descriptor, info);
261 }
262 if (IsQAsymmS8(info))
263 {
264 return std::make_unique<RefDebugQAsymmS8Workload>(descriptor, info);
265 }
Keith Davis0c2eeac2020-02-11 16:51:50 +0000266 if (IsSigned32(info))
Narumol Prangnawaratd2d917d2020-01-09 10:16:39 +0000267 {
268 return std::make_unique<RefDebugSigned32Workload>(descriptor, info);
269 }
Aron Virginas-Tardb1a2832019-11-12 16:15:11 +0000270
Keith Davis0c2eeac2020-02-11 16:51:50 +0000271 return MakeWorkload<RefDebugFloat32Workload, RefDebugQAsymmU8Workload>(descriptor, info);
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100272}
273
274std::unique_ptr<IWorkload> RefWorkloadFactory::CreateDepthToSpace(const DepthToSpaceQueueDescriptor& descriptor,
275 const WorkloadInfo& info) const
276{
277 return std::make_unique<RefDepthToSpaceWorkload>(descriptor, info);
278}
279
280std::unique_ptr<IWorkload> RefWorkloadFactory::CreateDepthwiseConvolution2d(
281 const DepthwiseConvolution2dQueueDescriptor& descriptor,
282 const WorkloadInfo& info) const
283{
284 return std::make_unique<RefDepthwiseConvolution2dWorkload>(descriptor, info);
285}
286
287std::unique_ptr<IWorkload> RefWorkloadFactory::CreateDequantize(const DequantizeQueueDescriptor& descriptor,
288 const WorkloadInfo& info) const
289{
290 return std::make_unique<RefDequantizeWorkload>(descriptor, info);
291}
292
293std::unique_ptr<IWorkload> RefWorkloadFactory::CreateDetectionPostProcess(
294 const DetectionPostProcessQueueDescriptor& descriptor,
295 const WorkloadInfo& info) const
296{
297 return std::make_unique<RefDetectionPostProcessWorkload>(descriptor, info);
298}
299
300std::unique_ptr<IWorkload> RefWorkloadFactory::CreateDivision(const DivisionQueueDescriptor& descriptor,
301 const WorkloadInfo& info) const
302{
Finn Williamscbd2c232020-06-22 15:58:32 +0100303 if (info.m_InputTensorInfos[0].GetDataType() == armnn::DataType::Signed32)
304 {
305 return std::make_unique<RefDivisionWorkload<int32_t>>(descriptor, info);
306 }
307 else
308 {
309 return std::make_unique<RefDivisionWorkload<float>>(descriptor, info);
310 }
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100311}
312
josh minor4a3c6102020-01-06 16:40:46 -0600313std::unique_ptr<IWorkload> RefWorkloadFactory::CreateElementwiseUnary(const ElementwiseUnaryQueueDescriptor& descriptor,
314 const WorkloadInfo& info) const
315{
Narumol Prangnawarat0c95f4c2020-11-18 16:52:07 +0000316 if (descriptor.m_Parameters.m_Operation == UnaryOperation::LogicalNot)
317 {
318 return std::make_unique<RefLogicalUnaryWorkload>(descriptor, info);
319 }
josh minor4a3c6102020-01-06 16:40:46 -0600320 return std::make_unique<RefElementwiseUnaryWorkload>(descriptor, info);
321}
322
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100323std::unique_ptr<IWorkload> RefWorkloadFactory::CreateEqual(const EqualQueueDescriptor& descriptor,
324 const WorkloadInfo& info) const
325{
Jan Eilers8eb25602020-03-09 12:13:48 +0000326 IgnoreUnused(descriptor);
Aron Virginas-Tar77bfb5e2019-10-16 17:45:38 +0100327 ComparisonQueueDescriptor comparisonDescriptor;
328 comparisonDescriptor.m_Parameters.m_Operation = ComparisonOperation::Equal;
329
330 return CreateComparison(comparisonDescriptor, info);
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100331}
332
Ryan OSheaf4bfa6a2020-06-10 11:33:37 +0100333std::unique_ptr<IWorkload> RefWorkloadFactory::CreateFakeQuantization(const FakeQuantizationQueueDescriptor& descriptor,
334 const WorkloadInfo& info) const
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100335{
336 return MakeWorkload<RefFakeQuantizationFloat32Workload, NullWorkload>(descriptor, info);
337}
338
Ryan OSheaf4bfa6a2020-06-10 11:33:37 +0100339std::unique_ptr<IWorkload> RefWorkloadFactory::CreateFill(const FillQueueDescriptor& descriptor,
340 const WorkloadInfo& info) const
341{
342 return std::make_unique<RefFillWorkload>(descriptor, info);
343}
344
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100345std::unique_ptr<IWorkload> RefWorkloadFactory::CreateFloor(const FloorQueueDescriptor& descriptor,
346 const WorkloadInfo& info) const
347{
Francis Murtaghe8ac1332020-07-30 18:03:40 +0100348 if(IsQuantizedType(info.m_InputTensorInfos[0].GetDataType()))
349 {
350 return nullptr;
351 }
352 else
353 {
354 return std::make_unique<RefFloorWorkload>(descriptor, info);
355 }
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100356}
357
358std::unique_ptr<IWorkload> RefWorkloadFactory::CreateFullyConnected(
359 const FullyConnectedQueueDescriptor& descriptor,
360 const WorkloadInfo& info) const
361{
362 return std::make_unique<RefFullyConnectedWorkload>(descriptor, info);
363}
364
365std::unique_ptr<IWorkload> RefWorkloadFactory::CreateGather(const GatherQueueDescriptor& descriptor,
366 const WorkloadInfo& info) const
367{
368 return std::make_unique<RefGatherWorkload>(descriptor, info);
369}
370
371std::unique_ptr<IWorkload> RefWorkloadFactory::CreateGreater(const GreaterQueueDescriptor& descriptor,
372 const WorkloadInfo& info) const
373{
Jan Eilers8eb25602020-03-09 12:13:48 +0000374 IgnoreUnused(descriptor);
Aron Virginas-Tar77bfb5e2019-10-16 17:45:38 +0100375 ComparisonQueueDescriptor comparisonDescriptor;
376 comparisonDescriptor.m_Parameters.m_Operation = ComparisonOperation::Greater;
377
378 return CreateComparison(comparisonDescriptor, info);
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100379}
380
telsoa014fcda012018-03-09 14:13:49 +0000381std::unique_ptr<IWorkload> RefWorkloadFactory::CreateInput(const InputQueueDescriptor& descriptor,
382 const WorkloadInfo& info) const
383{
384 if (info.m_InputTensorInfos.empty() )
385 {
386 throw InvalidArgumentException("RefWorkloadFactory::CreateInput: Input cannot be zero length");
387 }
388 if (info.m_OutputTensorInfos.empty())
389 {
390 throw InvalidArgumentException("RefWorkloadFactory::CreateInput: Output cannot be zero length");
391 }
392
393 if (info.m_InputTensorInfos[0].GetNumBytes() != info.m_OutputTensorInfos[0].GetNumBytes())
394 {
395 throw InvalidArgumentException("RefWorkloadFactory::CreateInput: data input and output differ in byte count.");
396 }
397
Narumol Prangnawaratb6441e42019-06-04 11:22:00 +0100398 return std::make_unique<CopyMemGenericWorkload>(descriptor, info);
telsoa014fcda012018-03-09 14:13:49 +0000399}
400
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100401std::unique_ptr<IWorkload> RefWorkloadFactory::CreateInstanceNormalization(
402 const InstanceNormalizationQueueDescriptor& descriptor,
403 const WorkloadInfo& info) const
404{
405 return std::make_unique<RefInstanceNormalizationWorkload>(descriptor, info);
406}
407
408std::unique_ptr<IWorkload> RefWorkloadFactory::CreateL2Normalization(const L2NormalizationQueueDescriptor& descriptor,
409 const WorkloadInfo& info) const
410{
411 return std::make_unique<RefL2NormalizationWorkload>(descriptor, info);
412}
413
James Conroyaba90cd2020-11-06 16:28:18 +0000414std::unique_ptr<IWorkload> RefWorkloadFactory::CreateLogicalBinary(const LogicalBinaryQueueDescriptor& descriptor,
415 const WorkloadInfo& info) const
416{
417 return std::make_unique<RefLogicalBinaryWorkload>(descriptor, info);
418}
419
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100420std::unique_ptr<IWorkload> RefWorkloadFactory::CreateLogSoftmax(const LogSoftmaxQueueDescriptor& descriptor,
421 const WorkloadInfo& info) const
422{
423 return std::make_unique<RefLogSoftmaxWorkload>(descriptor, info);
424}
425
426std::unique_ptr<IWorkload> RefWorkloadFactory::CreateLstm(const LstmQueueDescriptor& descriptor,
427 const WorkloadInfo& info) const
428{
429 return std::make_unique<RefLstmWorkload>(descriptor, info);
430}
431
432std::unique_ptr<IWorkload> RefWorkloadFactory::CreateMaximum(const MaximumQueueDescriptor& descriptor,
433 const WorkloadInfo& info) const
434{
Finn Williamscbd2c232020-06-22 15:58:32 +0100435 if (info.m_InputTensorInfos[0].GetDataType() == armnn::DataType::Signed32)
436 {
437 return std::make_unique<RefMaximumWorkload<int32_t>>(descriptor, info);
438 }
439 else
440 {
441 return std::make_unique<RefMaximumWorkload<float>>(descriptor, info);
442 }
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100443}
444
445std::unique_ptr<IWorkload> RefWorkloadFactory::CreateMean(const MeanQueueDescriptor& descriptor,
446 const WorkloadInfo& info) const
447{
448 return std::make_unique<RefMeanWorkload>(descriptor, info);
449}
450
451std::unique_ptr<IWorkload> RefWorkloadFactory::CreateMemCopy(const MemCopyQueueDescriptor& descriptor,
452 const WorkloadInfo& info) const
453{
454 if (descriptor.m_Inputs.empty())
455 {
456 throw InvalidArgumentException("RefWorkloadFactory: CreateMemCopy() expected an input tensor.");
457 }
458 return std::make_unique<CopyMemGenericWorkload>(descriptor, info);
459}
460
461std::unique_ptr<IWorkload> RefWorkloadFactory::CreateMemImport(const MemImportQueueDescriptor& descriptor,
462 const WorkloadInfo& info) const
463{
464 if (descriptor.m_Inputs.empty())
465 {
466 throw InvalidArgumentException("RefWorkloadFactory: CreateMemImport() expected an input tensor.");
467 }
468 return std::make_unique<ImportMemGenericWorkload>(descriptor, info);
469}
470
471std::unique_ptr<IWorkload> RefWorkloadFactory::CreateMerger(const MergerQueueDescriptor& descriptor,
472 const WorkloadInfo& info) const
473{
474 return CreateConcat(descriptor, info);
475}
476
477std::unique_ptr<IWorkload> RefWorkloadFactory::CreateMinimum(const MinimumQueueDescriptor& descriptor,
478 const WorkloadInfo& info) const
479{
Finn Williamscbd2c232020-06-22 15:58:32 +0100480 if (info.m_InputTensorInfos[0].GetDataType() == armnn::DataType::Signed32)
481 {
482 return std::make_unique<RefMinimumWorkload<int32_t>>(descriptor, info);
483 }
484 else
485 {
486 return std::make_unique<RefMinimumWorkload<float>>(descriptor, info);
487 }
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100488}
489
490std::unique_ptr<IWorkload> RefWorkloadFactory::CreateMultiplication(const MultiplicationQueueDescriptor& descriptor,
491 const WorkloadInfo& info) const
492{
Finn Williamscbd2c232020-06-22 15:58:32 +0100493 if (info.m_InputTensorInfos[0].GetDataType() == armnn::DataType::Signed32)
494 {
495 return std::make_unique<RefMultiplicationWorkload<int32_t>>(descriptor, info);
496 }
497 else
498 {
499 return std::make_unique<RefMultiplicationWorkload<float>>(descriptor, info);
500 }
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100501}
502
503std::unique_ptr<IWorkload> RefWorkloadFactory::CreateNormalization(const NormalizationQueueDescriptor& descriptor,
504 const WorkloadInfo& info) const
505{
506 return std::make_unique<RefNormalizationWorkload>(descriptor, info);
507}
508
telsoa014fcda012018-03-09 14:13:49 +0000509std::unique_ptr<IWorkload> RefWorkloadFactory::CreateOutput(const OutputQueueDescriptor& descriptor,
510 const WorkloadInfo& info) const
511{
512 if (info.m_InputTensorInfos.empty() )
513 {
514 throw InvalidArgumentException("RefWorkloadFactory::CreateOutput: Input cannot be zero length");
515 }
516 if (info.m_OutputTensorInfos.empty())
517 {
518 throw InvalidArgumentException("RefWorkloadFactory::CreateOutput: Output cannot be zero length");
519 }
520 if (info.m_InputTensorInfos[0].GetNumBytes() != info.m_OutputTensorInfos[0].GetNumBytes())
521 {
522 throw InvalidArgumentException("RefWorkloadFactory::CreateOutput: data input and output differ in byte count.");
523 }
524
Narumol Prangnawaratb6441e42019-06-04 11:22:00 +0100525 return std::make_unique<CopyMemGenericWorkload>(descriptor, info);
telsoa014fcda012018-03-09 14:13:49 +0000526}
527
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100528std::unique_ptr<IWorkload> RefWorkloadFactory::CreatePad(const PadQueueDescriptor& descriptor,
529 const WorkloadInfo& info) const
telsoa014fcda012018-03-09 14:13:49 +0000530{
Sadik Armagan041b3c02020-06-04 10:32:18 +0100531 return std::make_unique<RefPadWorkload>(descriptor, info);
telsoa014fcda012018-03-09 14:13:49 +0000532}
533
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100534std::unique_ptr<IWorkload> RefWorkloadFactory::CreatePermute(const PermuteQueueDescriptor& descriptor,
535 const WorkloadInfo& info) const
telsoa014fcda012018-03-09 14:13:49 +0000536{
Keith Davis0c2eeac2020-02-11 16:51:50 +0000537 if (IsQSymmS16(info))
Narumol Prangnawarat86bb4e12019-07-08 11:36:05 +0100538 {
539 return std::make_unique<RefPermuteQSymm16Workload>(descriptor, info);
540 }
Narumol Prangnawarat44179c32020-03-11 14:51:27 +0000541 else if (IsBFloat16(info))
542 {
543 return std::make_unique<RefPermuteBFloat16Workload>(descriptor, info);
544 }
Sadik Armagan303980c2020-04-17 12:45:14 +0100545 else if (IsQAsymmS8(info))
546 {
547 return std::make_unique<RefPermuteQAsymmS8Workload>(descriptor, info);
548 }
Narumol Prangnawarat86bb4e12019-07-08 11:36:05 +0100549 return MakeWorkloadHelper<RefPermuteFloat16Workload, RefPermuteFloat32Workload, RefPermuteQAsymm8Workload,
Keith Davis5204aa82020-01-27 15:24:59 +0000550 NullWorkload, NullWorkload, NullWorkload>(descriptor, info);
telsoa014fcda012018-03-09 14:13:49 +0000551}
552
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100553std::unique_ptr<IWorkload> RefWorkloadFactory::CreatePooling2d(const Pooling2dQueueDescriptor& descriptor,
554 const WorkloadInfo& info) const
telsoa014fcda012018-03-09 14:13:49 +0000555{
Teresa Charlina3b20472019-06-06 11:12:32 +0100556 return std::make_unique<RefPooling2dWorkload>(descriptor, info);
telsoa014fcda012018-03-09 14:13:49 +0000557}
558
Derek Lamberti901ea112019-12-10 22:07:09 +0000559std::unique_ptr<IWorkload> RefWorkloadFactory::CreatePreCompiled(const PreCompiledQueueDescriptor& /*descriptor*/,
560 const WorkloadInfo& /*info*/) const
telsoa014fcda012018-03-09 14:13:49 +0000561{
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100562 return nullptr;
telsoa014fcda012018-03-09 14:13:49 +0000563}
564
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100565std::unique_ptr<IWorkload> RefWorkloadFactory::CreatePrelu(const PreluQueueDescriptor& descriptor,
566 const WorkloadInfo& info) const
Aron Virginas-Tar73f66422019-09-23 19:11:59 +0100567{
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100568 return std::make_unique<RefPreluWorkload>(descriptor, info);
Aron Virginas-Tar73f66422019-09-23 19:11:59 +0100569}
570
James Conroy4f1f8992020-04-29 20:01:10 +0100571std::unique_ptr<IWorkload> RefWorkloadFactory::CreateQLstm(const QLstmQueueDescriptor& descriptor,
572 const WorkloadInfo& info) const
573{
574 return std::make_unique<RefQLstmWorkload>(descriptor, info);
575}
576
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100577std::unique_ptr<IWorkload> RefWorkloadFactory::CreateQuantize(const QuantizeQueueDescriptor& descriptor,
578 const WorkloadInfo& info) const
telsoa014fcda012018-03-09 14:13:49 +0000579{
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100580 return std::make_unique<RefQuantizeWorkload>(descriptor, info);
telsoa014fcda012018-03-09 14:13:49 +0000581}
582
Finn Williams2605b232020-06-10 15:53:46 +0100583std::unique_ptr<IWorkload> RefWorkloadFactory::CreateRank(const RankQueueDescriptor& descriptor,
584 const WorkloadInfo& info) const
585{
586 return std::make_unique<RefRankWorkload>(descriptor, info);
587}
588
Sadik Armagan0c3ea5b2021-02-03 09:29:30 +0000589std::unique_ptr<IWorkload> RefWorkloadFactory::CreateReduce(const ReduceQueueDescriptor& descriptor,
590 const WorkloadInfo& info) const
591{
592 return std::make_unique<RefReduceWorkload>(descriptor, info);
593}
594
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100595std::unique_ptr<IWorkload> RefWorkloadFactory::CreateReshape(const ReshapeQueueDescriptor& descriptor,
596 const WorkloadInfo& info) const
Narumol Prangnawarat94dd5d82019-01-23 18:06:26 +0000597{
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100598 return std::make_unique<RefReshapeWorkload>(descriptor, info);
Derek Lambertif674aa02019-08-01 15:56:25 +0100599}
600
Teresa Charlin970f43b2019-07-01 13:51:07 +0100601std::unique_ptr<IWorkload> RefWorkloadFactory::CreateResize(const ResizeQueueDescriptor& descriptor,
602 const WorkloadInfo& info) const
603{
Teresa Charlin970f43b2019-07-01 13:51:07 +0100604 return std::make_unique<RefResizeWorkload>(descriptor, info);
605}
606
telsoa014fcda012018-03-09 14:13:49 +0000607std::unique_ptr<IWorkload> RefWorkloadFactory::CreateResizeBilinear(const ResizeBilinearQueueDescriptor& descriptor,
608 const WorkloadInfo& info) const
609{
Aron Virginas-Tar169d2f12019-07-01 19:01:44 +0100610 ResizeQueueDescriptor resizeDescriptor;
611 resizeDescriptor.m_Parameters.m_Method = ResizeMethod::Bilinear;
612 resizeDescriptor.m_Parameters.m_DataLayout = descriptor.m_Parameters.m_DataLayout;
613 resizeDescriptor.m_Parameters.m_TargetWidth = descriptor.m_Parameters.m_TargetWidth;
614 resizeDescriptor.m_Parameters.m_TargetHeight = descriptor.m_Parameters.m_TargetHeight;
615
616 return CreateResize(resizeDescriptor, info);
telsoa014fcda012018-03-09 14:13:49 +0000617}
618
Mohamed Nour Abouelseouda1d3c6a2018-12-27 12:39:16 +0000619std::unique_ptr<IWorkload> RefWorkloadFactory::CreateRsqrt(const RsqrtQueueDescriptor& descriptor,
620 const WorkloadInfo& info) const
621{
Jan Eilers8eb25602020-03-09 12:13:48 +0000622 IgnoreUnused(descriptor);
josh minor4a3c6102020-01-06 16:40:46 -0600623 ElementwiseUnaryQueueDescriptor elementwiseUnaryDescriptor;
624 elementwiseUnaryDescriptor.m_Parameters.m_Operation = UnaryOperation::Rsqrt;
625
626 return CreateElementwiseUnary(elementwiseUnaryDescriptor, info);
Mohamed Nour Abouelseouda1d3c6a2018-12-27 12:39:16 +0000627}
628
Aron Virginas-Tar92b9f872019-09-17 17:27:04 +0100629std::unique_ptr<IWorkload> RefWorkloadFactory::CreateSlice(const SliceQueueDescriptor& descriptor,
630 const WorkloadInfo& info) const
631{
632 return std::make_unique<RefSliceWorkload>(descriptor, info);
633}
634
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100635std::unique_ptr<IWorkload> RefWorkloadFactory::CreateSoftmax(const SoftmaxQueueDescriptor& descriptor,
636 const WorkloadInfo& info) const
Kevin May09ca49c2019-10-09 12:37:34 +0100637{
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100638 return std::make_unique<RefSoftmaxWorkload>(descriptor, info);
639}
640
641std::unique_ptr<IWorkload> RefWorkloadFactory::CreateSpaceToBatchNd(const SpaceToBatchNdQueueDescriptor& descriptor,
642 const WorkloadInfo& info) const
643{
644 return std::make_unique<RefSpaceToBatchNdWorkload>(descriptor, info);
645}
646
647std::unique_ptr<IWorkload> RefWorkloadFactory::CreateSpaceToDepth(const SpaceToDepthQueueDescriptor& descriptor,
648 const WorkloadInfo& info) const
649{
650 return std::make_unique<RefSpaceToDepthWorkload>(descriptor, info);
651}
652
653std::unique_ptr<IWorkload> RefWorkloadFactory::CreateSplitter(const SplitterQueueDescriptor& descriptor,
654 const WorkloadInfo& info) const
655{
656 return std::make_unique<RefSplitterWorkload>(descriptor, info);
657}
658
659std::unique_ptr<IWorkload> RefWorkloadFactory::CreateStack(const StackQueueDescriptor& descriptor,
660 const WorkloadInfo& info) const
661{
662 return std::make_unique<RefStackWorkload>(descriptor, info);
663}
664
665std::unique_ptr<IWorkload> RefWorkloadFactory::CreateStridedSlice(const StridedSliceQueueDescriptor& descriptor,
666 const WorkloadInfo& info) const
667{
668 return std::make_unique<RefStridedSliceWorkload>(descriptor, info);
669}
670
671std::unique_ptr<IWorkload> RefWorkloadFactory::CreateSubtraction(const SubtractionQueueDescriptor& descriptor,
672 const WorkloadInfo& info) const
673{
Finn Williamscbd2c232020-06-22 15:58:32 +0100674 if (info.m_InputTensorInfos[0].GetDataType() == armnn::DataType::Signed32)
675 {
676 return std::make_unique<RefSubtractionWorkload<int32_t>>(descriptor, info);
677 }
678 else
679 {
680 return std::make_unique<RefSubtractionWorkload<float>>(descriptor, info);
681 }
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100682}
683
Mike Kellyc9ea45a2020-02-28 18:11:58 +0000684std::unique_ptr<IWorkload> RefWorkloadFactory::CreateTranspose(const TransposeQueueDescriptor& descriptor,
685 const WorkloadInfo& info) const
686{
687 if (IsQSymmS16(info))
688 {
689 return std::make_unique<RefTransposeQSymm16Workload>(descriptor, info);
690 }
Narumol Prangnawarat44179c32020-03-11 14:51:27 +0000691 else if (IsBFloat16(info))
692 {
693 return std::make_unique<RefTransposeBFloat16Workload>(descriptor, info);
694 }
Sadik Armagan303980c2020-04-17 12:45:14 +0100695 else if (IsQAsymmS8(info))
696 {
697 return std::make_unique<RefTransposeQAsymmS8Workload>(descriptor, info);
698 }
Mike Kellyc9ea45a2020-02-28 18:11:58 +0000699 return MakeWorkloadHelper<RefTransposeFloat16Workload, RefTransposeFloat32Workload, RefTransposeQAsymm8Workload,
700 NullWorkload, NullWorkload, NullWorkload>(descriptor, info);
701}
702
Aron Virginas-Tare662a942019-10-14 15:12:00 +0100703std::unique_ptr<IWorkload> RefWorkloadFactory::CreateTransposeConvolution2d(
704 const TransposeConvolution2dQueueDescriptor& descriptor,
705 const WorkloadInfo& info) const
706{
707 return std::make_unique<RefTransposeConvolution2dWorkload>(descriptor, info);
Kevin May09ca49c2019-10-09 12:37:34 +0100708}
709
Matteo Martincigh49124022019-01-11 13:25:59 +0000710} // namespace armnn