blob: a1519cd46ff8397fdec43c385759a2398b2ff37d [file] [log] [blame]
telsoa014fcda012018-03-09 14:13:49 +00001//
Teresa Charlin52664732020-06-29 16:27:03 +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//
5
6#include "NeonLayerSupport.hpp"
David Beck3e9e1152018-10-17 14:17:50 +01007#include "NeonBackendId.hpp"
Sadik Armagan045f6be2020-09-10 13:37:32 +01008#include "NeonBackendModelContext.hpp"
telsoa014fcda012018-03-09 14:13:49 +00009
telsoa014fcda012018-03-09 14:13:49 +000010#include <armnn/Descriptors.hpp>
Derek Lambertic77874a2020-04-28 13:34:56 +010011#include <armnn/Exceptions.hpp>
telsoa014fcda012018-03-09 14:13:49 +000012#include <armnn/Tensor.hpp>
Aron Virginas-Tarfc824312018-10-15 15:00:13 +010013#include <armnn/Types.hpp>
Matteo Martincighc601aa62019-10-29 15:03:22 +000014#include <armnn/BackendRegistry.hpp>
telsoa014fcda012018-03-09 14:13:49 +000015
Matteo Martincighc601aa62019-10-29 15:03:22 +000016#include <InternalTypes.hpp>
17#include <LayerSupportCommon.hpp>
Jan Eilers8eb25602020-03-09 12:13:48 +000018#include <armnn/utility/IgnoreUnused.hpp>
Sadik Armagan045f6be2020-09-10 13:37:32 +010019#include <armnn/utility/PolymorphicDowncast.hpp>
telsoa014fcda012018-03-09 14:13:49 +000020
Matteo Martincighd95e9062019-01-31 15:35:59 +000021#if defined(ARMCOMPUTENEON_ENABLED)
Narumol Prangnawarat15eb5832019-05-20 15:31:05 +010022#include <aclCommon/ArmComputeUtils.hpp>
Aron Virginas-Tar710f6642019-11-27 14:48:32 +000023#include <aclCommon/ArmComputeTensorUtils.hpp>
Aron Virginas-Tar914e4db2019-09-09 13:36:45 +010024#include "workloads/NeonAbsWorkload.hpp"
Matthew Bentham955258d2018-12-10 10:48:52 +000025#include "workloads/NeonAdditionWorkload.hpp"
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +010026#include "workloads/NeonActivationWorkload.hpp"
James Conroyd47a0642019-09-17 14:22:06 +010027#include "workloads/NeonArgMinMaxWorkload.hpp"
Matthew Benthamc48ac8c2018-12-12 16:15:59 +000028#include "workloads/NeonBatchNormalizationWorkload.hpp"
Mike Kelly56858022020-01-27 12:14:47 +000029#include "workloads/NeonBatchToSpaceNdWorkload.hpp"
Sadik Armagan48f011e2021-04-21 10:50:34 +010030#include "workloads/NeonCastWorkload.hpp"
Derek Lambertic77874a2020-04-28 13:34:56 +010031#include "workloads/NeonExpWorkload.hpp"
Teresa Charlincedd34f2020-03-30 11:17:30 +010032#include "workloads/NeonComparisonWorkload.hpp"
Mike Kelly0886ac42020-04-27 09:55:40 +010033#include "workloads/NeonConstantWorkload.hpp"
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +010034#include "workloads/NeonConvolution2dWorkload.hpp"
Aron Virginas-Tar2f00b742019-09-30 13:28:08 +010035#include "workloads/NeonDepthToSpaceWorkload.hpp"
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010036#include "workloads/NeonDepthwiseConvolutionWorkload.hpp"
Narumol Prangnawarat01961a72019-05-30 16:47:12 +010037#include "workloads/NeonDequantizeWorkload.hpp"
Sadik Armagan0d4863d2019-10-09 14:26:32 +010038#include "workloads/NeonInstanceNormalizationWorkload.hpp"
David Beck0dbe0ee2018-09-24 15:59:27 +010039#include "workloads/NeonL2NormalizationFloatWorkload.hpp"
Keith Davis69e653f2020-07-02 11:49:26 +010040#include "workloads/NeonLogSoftmaxWorkload.hpp"
James Conroy177df1e2020-11-13 10:18:51 +000041#include "workloads/NeonLogicalAndWorkload.hpp"
42#include "workloads/NeonLogicalNotWorkload.hpp"
43#include "workloads/NeonLogicalOrWorkload.hpp"
Jan Eilersad5293a2019-07-08 09:57:55 +010044#include "workloads/NeonLstmFloatWorkload.hpp"
Nattapat Chaimanowong4e6597a2018-12-20 14:14:06 +000045#include "workloads/NeonMaximumWorkload.hpp"
Matthew Benthamfd899962018-12-31 15:49:42 +000046#include "workloads/NeonMeanWorkload.hpp"
Jim Flynn39d487d2019-05-17 15:44:36 +010047#include "workloads/NeonConcatWorkload.hpp"
Conor Kennedy54b21692019-01-09 07:57:38 +000048#include "workloads/NeonMinimumWorkload.hpp"
Conor Kennedyb99480b2019-03-08 08:24:41 +000049#include "workloads/NeonMultiplicationWorkload.hpp"
Pablo Telloe61f0712020-01-23 10:37:17 +000050#include "workloads/NeonDivisionWorkload.hpp"
Sadik Armaganac472102020-03-24 09:54:36 +000051#include "workloads/NeonNegWorkload.hpp"
David Beck0dbe0ee2018-09-24 15:59:27 +010052#include "workloads/NeonNormalizationFloatWorkload.hpp"
53#include "workloads/NeonFullyConnectedWorkload.hpp"
Teresa Charlinf540eb82020-04-10 19:24:55 +010054#include "workloads/NeonGatherWorkload.hpp"
Éanna Ó Catháin12055742019-01-25 10:01:40 +000055#include "workloads/NeonPadWorkload.hpp"
David Beck0dbe0ee2018-09-24 15:59:27 +010056#include "workloads/NeonPermuteWorkload.hpp"
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +010057#include "workloads/NeonPooling2dWorkload.hpp"
Nikhil Raj9b461482019-07-03 15:58:31 +010058#include "workloads/NeonPreluWorkload.hpp"
James Conroycc340932020-05-12 18:08:52 +010059#include "workloads/NeonQLstmWorkload.hpp"
Sadik Armaganfabc2892019-05-31 09:05:11 +010060#include "workloads/NeonQuantizeWorkload.hpp"
Francis Murtagh4fc3c482019-08-02 13:20:54 +010061#include "workloads/NeonQuantizedLstmWorkload.hpp"
Sadik Armagana2747482021-02-09 10:28:54 +000062#include "workloads/NeonReduceWorkload.hpp"
Kevin Maya023c402019-12-12 17:28:05 +000063#include "workloads/NeonReshapeWorkload.hpp"
Ellen Norris-Thompson37e68682019-07-15 14:23:30 +010064#include "workloads/NeonResizeWorkload.hpp"
Aron Virginas-Tar0dd3b432019-09-10 13:55:09 +010065#include "workloads/NeonRsqrtWorkload.hpp"
josh minor036f02d2019-11-15 14:53:22 -060066#include "workloads/NeonSliceWorkload.hpp"
Sadik Armaganbe88a572020-04-30 11:39:37 +010067#include "workloads/NeonSoftmaxWorkload.hpp"
Mike Kelly0be3a882020-01-24 11:27:50 +000068#include "workloads/NeonSpaceToBatchNdWorkload.hpp"
Ellen Norris-Thompson29794572019-06-26 16:40:36 +010069#include "workloads/NeonSpaceToDepthWorkload.hpp"
Narumol Prangnawarat15eb5832019-05-20 15:31:05 +010070#include "workloads/NeonSplitterWorkload.hpp"
Matthew Jackson87f65ea2019-08-01 10:01:34 +010071#include "workloads/NeonStackWorkload.hpp"
FinnWilliamsArm1fa19192019-08-02 17:26:31 +010072#include "workloads/NeonStridedSliceWorkload.hpp"
Conor Kennedyb99480b2019-03-08 08:24:41 +000073#include "workloads/NeonSubtractionWorkload.hpp"
Sadik Armagan581742d2019-08-12 14:11:37 +010074#include "workloads/NeonTransposeConvolution2dWorkload.hpp"
Mike Kellyc9ea45a2020-02-28 18:11:58 +000075#include "workloads/NeonTransposeWorkload.hpp"
telsoa014fcda012018-03-09 14:13:49 +000076#endif
77
telsoa014fcda012018-03-09 14:13:49 +000078namespace armnn
79{
telsoa014fcda012018-03-09 14:13:49 +000080
Aron Virginas-Tarfc824312018-10-15 15:00:13 +010081namespace
arovir017ff76c52018-10-09 09:40:58 +010082{
telsoa014fcda012018-03-09 14:13:49 +000083
Derek Lamberti901ea112019-12-10 22:07:09 +000084template< typename ... Args>
85bool IsNeonBackendSupported(Optional<std::string&> reasonIfUnsupported, Args... args)
telsoa014fcda012018-03-09 14:13:49 +000086{
Jan Eilers8eb25602020-03-09 12:13:48 +000087 IgnoreUnused(reasonIfUnsupported, (args)...);
Matteo Martincighd95e9062019-01-31 15:35:59 +000088#if defined(ARMCOMPUTENEON_ENABLED)
telsoa014fcda012018-03-09 14:13:49 +000089 return true;
90#else
Derek Lamberti0790dce2019-04-15 18:37:35 +010091 SetValueChecked(reasonIfUnsupported, "The armnn library has been built without NEON support");
telsoa014fcda012018-03-09 14:13:49 +000092 return false;
93#endif
94}
95
telsoa01c577f2c2018-08-31 09:22:23 +010096template<typename FloatFunc, typename Uint8Func, typename ... Params>
arovir01085f0a42018-10-08 14:48:19 +010097bool IsSupportedForDataTypeNeon(Optional<std::string&> reasonIfUnsupported,
telsoa014fcda012018-03-09 14:13:49 +000098 DataType dataType,
telsoa01c577f2c2018-08-31 09:22:23 +010099 FloatFunc floatFuncPtr,
telsoa014fcda012018-03-09 14:13:49 +0000100 Uint8Func uint8FuncPtr,
101 Params&&... params)
102{
103 return IsNeonBackendSupported(reasonIfUnsupported) &&
104 IsSupportedForDataTypeGeneric(reasonIfUnsupported,
105 dataType,
106 floatFuncPtr,
telsoa01c577f2c2018-08-31 09:22:23 +0100107 floatFuncPtr,
telsoa014fcda012018-03-09 14:13:49 +0000108 uint8FuncPtr,
narpra01db2b1602019-01-23 15:23:11 +0000109 &FalseFunc<>,
kevmay012b4d88e2019-01-24 14:05:09 +0000110 &FalseFunc<>,
telsoa014fcda012018-03-09 14:13:49 +0000111 std::forward<Params>(params)...);
112}
113
Matteo Martincighd95e9062019-01-31 15:35:59 +0000114#if defined(ARMCOMPUTENEON_ENABLED)
telsoa014fcda012018-03-09 14:13:49 +0000115template<class FuncType, class... Args>
arovir01085f0a42018-10-08 14:48:19 +0100116inline bool IsWorkloadSupported(FuncType& func, Optional<std::string&> reasonIfUnsupported, Args&&... args)
telsoa014fcda012018-03-09 14:13:49 +0000117{
118 arm_compute::Status aclStatus = func(std::forward<Args>(args)...);
119 const bool supported = (aclStatus.error_code() == arm_compute::ErrorCode::OK);
120 if (!supported && reasonIfUnsupported)
121 {
arovir01085f0a42018-10-08 14:48:19 +0100122 reasonIfUnsupported.value() = aclStatus.error_description();
telsoa014fcda012018-03-09 14:13:49 +0000123 }
124 return supported;
125}
126
127#define FORWARD_WORKLOAD_VALIDATE_FUNC(func, reasonIfUnsupported, ...) \
128 return IsWorkloadSupported(func, reasonIfUnsupported, __VA_ARGS__);
129#else
130#define FORWARD_WORKLOAD_VALIDATE_FUNC(func, reasonIfUnsupported, ...) \
Derek Lamberti901ea112019-12-10 22:07:09 +0000131 return IsNeonBackendSupported(reasonIfUnsupported, __VA_ARGS__);
telsoa014fcda012018-03-09 14:13:49 +0000132#endif
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100133} // anonymous namespace
134
Sadik Armagan045f6be2020-09-10 13:37:32 +0100135NeonLayerSupport::NeonLayerSupport(const IBackendInternal::IBackendSpecificModelContextPtr& modelContextPtr)
136 : m_ModelContextPtr(modelContextPtr)
137{
138}
139
140NeonLayerSupport::NeonLayerSupport()
141 : m_ModelContextPtr(nullptr)
142{
143}
144
Aron Virginas-Tar914e4db2019-09-09 13:36:45 +0100145bool NeonLayerSupport::IsAbsSupported(const TensorInfo& input,
146 const TensorInfo& output,
147 Optional<std::string&> reasonIfUnsupported) const
148{
josh minor4a3c6102020-01-06 16:40:46 -0600149 ElementwiseUnaryDescriptor descriptor(UnaryOperation::Abs);
150 return IsElementwiseUnarySupported(input, output, descriptor, reasonIfUnsupported);
Aron Virginas-Tar914e4db2019-09-09 13:36:45 +0100151}
152
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100153bool NeonLayerSupport::IsActivationSupported(const TensorInfo& input,
154 const TensorInfo& output,
155 const ActivationDescriptor& descriptor,
156 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000157{
Jan Eilers8eb25602020-03-09 12:13:48 +0000158 IgnoreUnused(descriptor);
telsoa01c577f2c2018-08-31 09:22:23 +0100159 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonActivationWorkloadValidate,
160 reasonIfUnsupported,
161 input,
162 output,
163 descriptor);
telsoa014fcda012018-03-09 14:13:49 +0000164}
165
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100166bool NeonLayerSupport::IsAdditionSupported(const TensorInfo& input0,
167 const TensorInfo& input1,
168 const TensorInfo& output,
169 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000170{
telsoa01c577f2c2018-08-31 09:22:23 +0100171 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonAdditionWorkloadValidate,
172 reasonIfUnsupported,
173 input0,
174 input1,
Mike Kelly07810fc2020-11-12 10:58:48 +0000175 output,
176 nullptr);
telsoa014fcda012018-03-09 14:13:49 +0000177}
178
James Conroyd47a0642019-09-17 14:22:06 +0100179bool NeonLayerSupport::IsArgMinMaxSupported(const TensorInfo& input,
180 const TensorInfo& output,
181 const ArgMinMaxDescriptor& descriptor,
182 Optional<std::string&> reasonIfUnsupported) const
183{
184 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonArgMinMaxWorkloadValidate,
185 reasonIfUnsupported,
186 input,
187 output,
188 descriptor);
189}
190
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100191bool NeonLayerSupport::IsBatchNormalizationSupported(const TensorInfo& input,
192 const TensorInfo& output,
193 const TensorInfo& mean,
194 const TensorInfo& var,
195 const TensorInfo& beta,
196 const TensorInfo& gamma,
197 const BatchNormalizationDescriptor& descriptor,
198 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000199{
telsoa01c577f2c2018-08-31 09:22:23 +0100200 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonBatchNormalizationValidate,
201 reasonIfUnsupported,
202 input,
203 output,
204 mean,
205 var,
206 beta,
207 gamma,
Mike Kelly07810fc2020-11-12 10:58:48 +0000208 descriptor,
209 nullptr);
telsoa014fcda012018-03-09 14:13:49 +0000210}
211
Mike Kelly56858022020-01-27 12:14:47 +0000212bool NeonLayerSupport::IsBatchToSpaceNdSupported(const TensorInfo& input,
213 const TensorInfo& output,
214 const BatchToSpaceNdDescriptor& descriptor,
215 Optional<std::string&> reasonIfUnsupported) const
216{
217 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonBatchToSpaceNdWorkloadValidate,
218 reasonIfUnsupported,
219 input,
220 output,
221 descriptor);
222}
223
Sadik Armagan48f011e2021-04-21 10:50:34 +0100224bool NeonLayerSupport::IsCastSupported(const TensorInfo& input,
225 const TensorInfo& output,
226 Optional<std::string&> reasonIfUnsupported) const
227{
228 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonCastValidate,
229 reasonIfUnsupported,
230 input,
231 output);
232}
233
Aron Virginas-Tar77bfb5e2019-10-16 17:45:38 +0100234bool NeonLayerSupport::IsComparisonSupported(const TensorInfo& input0,
235 const TensorInfo& input1,
236 const TensorInfo& output,
237 const ComparisonDescriptor& descriptor,
238 Optional<std::string&> reasonIfUnsupported) const
239{
Aron Virginas-Tar77bfb5e2019-10-16 17:45:38 +0100240
Teresa Charlincedd34f2020-03-30 11:17:30 +0100241 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonComparisonWorkloadValidate,
242 reasonIfUnsupported,
243 input0,
244 input1,
245 output,
246 descriptor);
Aron Virginas-Tar77bfb5e2019-10-16 17:45:38 +0100247}
248
Jim Flynn906f9462019-05-10 13:55:21 +0100249bool NeonLayerSupport::IsConcatSupported(const std::vector<const TensorInfo*> inputs,
250 const TensorInfo& output,
Jim Flynne242f2d2019-05-22 14:24:13 +0100251 const ConcatDescriptor& descriptor,
Jim Flynn906f9462019-05-10 13:55:21 +0100252 Optional<std::string&> reasonIfUnsupported) const
253{
Jim Flynne242f2d2019-05-22 14:24:13 +0100254 if (descriptor.GetNumDimensions() <= descriptor.GetConcatAxis())
255 {
256 SetValueChecked(reasonIfUnsupported, "Neon Concat: Concat axis > Number of dimensions.");
257 return false;
258 }
259
260 unsigned int concatInnerAxis = (descriptor.GetNumDimensions() - descriptor.GetConcatAxis()) - 1;
261 if(concatInnerAxis < 3) // Width, height, or channels
262 {
263 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonConcatWorkloadValidate,
264 reasonIfUnsupported,
265 inputs,
266 output,
267 descriptor);
268 }
269 else if (concatInnerAxis == 3)
270 {
271 for (auto& input : inputs)
272 {
273 if (input && !output.IsTypeSpaceMatch(*input)) // Cannot use sub-tensors if the types are not same space
274 {
275 SetValueChecked(reasonIfUnsupported, "Neon Concat: Types and quantization parameters must match.");
276 return false;
277 }
278 }
279 return true; // Sub-tensors support concat along batch
280 }
281 else // > 4 dimensions not supported.
282 {
283 SetValueChecked(reasonIfUnsupported, "Neon Concat: Maximum of 4 dimensions supported.");
284 return false;
285 }
Jim Flynn906f9462019-05-10 13:55:21 +0100286}
287
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100288bool NeonLayerSupport::IsConstantSupported(const TensorInfo& output,
289 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000290{
Mike Kelly0886ac42020-04-27 09:55:40 +0100291 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonConstantWorkloadValidate,
292 reasonIfUnsupported,
293 output);
telsoa014fcda012018-03-09 14:13:49 +0000294}
295
Narumol Prangnawarat250d3922020-03-30 16:11:04 +0100296bool NeonLayerSupport::IsConvertBf16ToFp32Supported(const TensorInfo& input,
297 const TensorInfo& output,
298 Optional<std::string&> reasonIfUnsupported) const
299{
300 armnn::IgnoreUnused(input);
301 armnn::IgnoreUnused(output);
302 armnn::IgnoreUnused(reasonIfUnsupported);
303 return true;
304}
305
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100306bool NeonLayerSupport::IsConvertFp16ToFp32Supported(const TensorInfo& input,
307 const TensorInfo& output,
308 Optional<std::string&> reasonIfUnsupported) const
309{
Jan Eilers8eb25602020-03-09 12:13:48 +0000310 armnn::IgnoreUnused(input);
311 armnn::IgnoreUnused(output);
312 armnn::IgnoreUnused(reasonIfUnsupported);
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100313 return true;
314}
315
Narumol Prangnawarat250d3922020-03-30 16:11:04 +0100316bool NeonLayerSupport::IsConvertFp32ToBf16Supported(const TensorInfo& input,
317 const TensorInfo& output,
318 Optional<std::string&> reasonIfUnsupported) const
319{
320 armnn::IgnoreUnused(input);
321 armnn::IgnoreUnused(output);
322 armnn::IgnoreUnused(reasonIfUnsupported);
323 return true;
324}
325
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100326bool NeonLayerSupport::IsConvertFp32ToFp16Supported(const TensorInfo& input,
327 const TensorInfo& output,
328 Optional<std::string&> reasonIfUnsupported) const
329{
Jan Eilers8eb25602020-03-09 12:13:48 +0000330 armnn::IgnoreUnused(input);
331 armnn::IgnoreUnused(output);
332 armnn::IgnoreUnused(reasonIfUnsupported);
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100333 return true;
334}
335
336bool NeonLayerSupport::IsConvolution2dSupported(const TensorInfo& input,
337 const TensorInfo& output,
338 const Convolution2dDescriptor& descriptor,
339 const TensorInfo& weights,
340 const Optional<TensorInfo>& biases,
341 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000342{
Sadik Armagan045f6be2020-09-10 13:37:32 +0100343 bool isFastMathEnabled = false;
344#if defined(ARMCOMPUTENEON_ENABLED)
345 if (m_ModelContextPtr)
346 {
347 if (m_ModelContextPtr.get() != nullptr)
348 {
Sadik Armagan04a72972020-09-14 15:44:18 +0100349 auto modelOptions = dynamic_cast<NeonBackendModelContext*>(m_ModelContextPtr.get());
Sadik Armagan045f6be2020-09-10 13:37:32 +0100350 if (modelOptions)
351 {
352 isFastMathEnabled = modelOptions->IsFastMathEnabled();
353 }
354 }
355 }
356#endif
357
surmeh013537c2c2018-05-18 16:31:43 +0100358 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonConvolution2dWorkloadValidate,
359 reasonIfUnsupported,
360 input,
361 output,
362 descriptor,
363 weights,
Sadik Armagan045f6be2020-09-10 13:37:32 +0100364 biases,
Mike Kelly07810fc2020-11-12 10:58:48 +0000365 isFastMathEnabled,
366 nullptr);
telsoa014fcda012018-03-09 14:13:49 +0000367}
368
Aron Virginas-Tar2f00b742019-09-30 13:28:08 +0100369bool NeonLayerSupport::IsDepthToSpaceSupported(const TensorInfo& input,
370 const TensorInfo& output,
371 const DepthToSpaceDescriptor& descriptor,
372 Optional<std::string&> reasonIfUnsupported) const
373{
374 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonDepthToSpaceWorkloadValidate,
375 reasonIfUnsupported,
376 input,
377 output,
378 descriptor);
379}
380
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100381bool NeonLayerSupport::IsDepthwiseConvolutionSupported(const TensorInfo& input,
382 const TensorInfo& output,
383 const DepthwiseConvolution2dDescriptor& descriptor,
384 const TensorInfo& weights,
385 const Optional<TensorInfo>& biases,
386 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000387{
telsoa01c577f2c2018-08-31 09:22:23 +0100388 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonDepthwiseConvolutionWorkloadValidate,
389 reasonIfUnsupported,
390 input,
391 output,
392 descriptor,
393 weights,
Mike Kelly07810fc2020-11-12 10:58:48 +0000394 biases,
395 nullptr);
telsoa014fcda012018-03-09 14:13:49 +0000396}
397
Narumol Prangnawarat01961a72019-05-30 16:47:12 +0100398bool NeonLayerSupport::IsDequantizeSupported(const TensorInfo& input,
399 const TensorInfo& output,
400 Optional<std::string&> reasonIfUnsupported) const
401{
402 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonDequantizeWorkloadValidate,
403 reasonIfUnsupported,
404 input,
405 output);
406}
407
Pablo Tellof0bd6832019-04-26 17:58:13 +0100408bool NeonLayerSupport::IsDilatedDepthwiseConvolutionSupported(const TensorInfo& input,
409 const TensorInfo& output,
410 const DepthwiseConvolution2dDescriptor& descriptor,
411 const TensorInfo& weights,
412 const Optional<TensorInfo>& biases,
413 Optional<std::string&> reasonIfUnsupported) const
414{
415 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonDepthwiseConvolutionWorkloadValidate,
416 reasonIfUnsupported,
417 input,
418 output,
419 descriptor,
420 weights,
Mike Kelly07810fc2020-11-12 10:58:48 +0000421 biases,
422 nullptr);
Pablo Tellof0bd6832019-04-26 17:58:13 +0100423}
424
josh minor4a3c6102020-01-06 16:40:46 -0600425bool NeonLayerSupport::IsElementwiseUnarySupported(const TensorInfo& input,
426 const TensorInfo& output,
427 const ElementwiseUnaryDescriptor& descriptor,
428 Optional<std::string&> reasonIfUnsupported) const
429{
Derek Lambertic77874a2020-04-28 13:34:56 +0100430 switch(descriptor.m_Operation)
josh minor4a3c6102020-01-06 16:40:46 -0600431 {
Derek Lambertic77874a2020-04-28 13:34:56 +0100432 case UnaryOperation::Abs:
433 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonAbsWorkloadValidate,
434 reasonIfUnsupported,
435 input,
436 output);
437 case UnaryOperation::Exp:
438 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonExpWorkloadValidate,
439 reasonIfUnsupported,
440 input,
441 output);
442 case UnaryOperation::Neg:
443 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonNegWorkloadValidate,
444 reasonIfUnsupported,
445 input,
446 output);
447 case UnaryOperation::Rsqrt:
448 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonRsqrtWorkloadValidate,
449 reasonIfUnsupported,
450 input,
451 output);
James Conroy177df1e2020-11-13 10:18:51 +0000452 case UnaryOperation::LogicalNot:
453 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonLogicalNotWorkloadValidate,
454 reasonIfUnsupported,
455 input,
456 output);
Derek Lambertic77874a2020-04-28 13:34:56 +0100457 default:
458 return false;
josh minor4a3c6102020-01-06 16:40:46 -0600459 }
josh minor4a3c6102020-01-06 16:40:46 -0600460}
461
Teresa Charlin4b10fef2020-07-29 09:36:41 +0100462bool NeonLayerSupport::IsFillSupported(const TensorInfo& input,
463 const TensorInfo& output,
464 const FillDescriptor& descriptor,
465 Optional<std::string&> reasonIfUnsupported) const
Sadik Armagana792a052020-06-23 16:22:23 +0100466{
Teresa Charlin4b10fef2020-07-29 09:36:41 +0100467 armnn::IgnoreUnused(input);
468 armnn::IgnoreUnused(output);
469 armnn::IgnoreUnused(descriptor);
470
471 return IsNeonBackendSupported(reasonIfUnsupported);
Sadik Armagana792a052020-06-23 16:22:23 +0100472}
473
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100474bool NeonLayerSupport::IsFloorSupported(const TensorInfo& input,
475 const TensorInfo& output,
476 Optional<std::string&> reasonIfUnsupported) const
477{
Jan Eilers8eb25602020-03-09 12:13:48 +0000478 armnn::IgnoreUnused(output);
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100479 return IsNeonBackendSupported(reasonIfUnsupported) &&
480 IsSupportedForDataTypeGeneric(reasonIfUnsupported,
481 input.GetDataType(),
482 &FalseFuncF16<>,
483 &TrueFunc<>,
narpra01db2b1602019-01-23 15:23:11 +0000484 &FalseFuncU8<>,
kevmay012b4d88e2019-01-24 14:05:09 +0000485 &FalseFuncI32<>,
486 &FalseFuncU8<>);
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100487}
488
489bool NeonLayerSupport::IsFullyConnectedSupported(const TensorInfo& input,
490 const TensorInfo& output,
491 const TensorInfo& weights,
492 const TensorInfo& biases,
493 const FullyConnectedDescriptor& descriptor,
494 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000495{
telsoa01c577f2c2018-08-31 09:22:23 +0100496 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonFullyConnectedWorkloadValidate,
497 reasonIfUnsupported,
498 input,
499 output,
500 weights,
501 biases,
Mike Kelly07810fc2020-11-12 10:58:48 +0000502 descriptor,
503 nullptr);
telsoa014fcda012018-03-09 14:13:49 +0000504}
505
Teresa Charlinf540eb82020-04-10 19:24:55 +0100506bool NeonLayerSupport::IsGatherSupported(const TensorInfo& input0,
507 const TensorInfo& input1,
508 const TensorInfo& output,
Teresa Charlin52664732020-06-29 16:27:03 +0100509 const GatherDescriptor& descriptor,
Teresa Charlinf540eb82020-04-10 19:24:55 +0100510 Optional<std::string&> reasonIfUnsupported) const
511{
512 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonGatherWorkloadValidate,
513 reasonIfUnsupported,
514 input0,
515 input1,
Teresa Charlin52664732020-06-29 16:27:03 +0100516 output,
517 descriptor);
Teresa Charlinf540eb82020-04-10 19:24:55 +0100518}
519
kevmay01eed85922019-01-28 08:37:25 +0000520bool NeonLayerSupport::IsGreaterSupported(const armnn::TensorInfo& input0,
521 const armnn::TensorInfo& input1,
522 const armnn::TensorInfo& output,
523 armnn::Optional<std::string&> reasonIfUnsupported) const
524{
Aron Virginas-Tar77bfb5e2019-10-16 17:45:38 +0100525 ComparisonDescriptor descriptor(ComparisonOperation::Greater);
526 return IsComparisonSupported(input0, input1, output, descriptor, reasonIfUnsupported);
kevmay01eed85922019-01-28 08:37:25 +0000527}
528
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100529bool NeonLayerSupport::IsInputSupported(const TensorInfo& input,
530 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000531{
Derek Lamberti901ea112019-12-10 22:07:09 +0000532 return IsNeonBackendSupported(reasonIfUnsupported, input);
telsoa014fcda012018-03-09 14:13:49 +0000533}
534
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100535bool NeonLayerSupport::IsInstanceNormalizationSupported(const TensorInfo& input,
536 const TensorInfo& output,
537 const InstanceNormalizationDescriptor& descriptor,
538 Optional<std::string&> reasonIfUnsupported) const
539{
540 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonInstanceNormalizationWorkloadValidate,
541 reasonIfUnsupported,
542 input,
543 output,
544 descriptor);
545}
546
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100547bool NeonLayerSupport::IsL2NormalizationSupported(const TensorInfo& input,
548 const TensorInfo& output,
549 const L2NormalizationDescriptor& descriptor,
550 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000551{
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100552 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonL2NormalizationWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
telsoa014fcda012018-03-09 14:13:49 +0000553}
554
James Conroy177df1e2020-11-13 10:18:51 +0000555bool NeonLayerSupport::IsLogicalBinarySupported(const TensorInfo& input0,
556 const TensorInfo& input1,
557 const TensorInfo& output,
558 const LogicalBinaryDescriptor& descriptor,
559 Optional<std::string&> reasonIfUnsupported) const
560{
561 switch(descriptor.m_Operation)
562 {
563 case LogicalBinaryOperation::LogicalAnd:
564 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonLogicalAndWorkloadValidate,
565 reasonIfUnsupported,
566 input0,
567 input1,
568 output);
569 case LogicalBinaryOperation::LogicalOr:
570 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonLogicalOrWorkloadValidate,
571 reasonIfUnsupported,
572 input0,
573 input1,
574 output);
575 default:
576 return false;
577 }
578}
579
Keith Davis69e653f2020-07-02 11:49:26 +0100580bool NeonLayerSupport::IsLogSoftmaxSupported(const TensorInfo& input,
581 const TensorInfo& output,
582 const LogSoftmaxDescriptor& descriptor,
583 Optional<std::string&> reasonIfUnsupported) const
584{
585 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonLogSoftmaxWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
586}
587
Jan Eilersad5293a2019-07-08 09:57:55 +0100588bool NeonLayerSupport::IsLstmSupported(const TensorInfo& input,
589 const TensorInfo& outputStateIn,
590 const TensorInfo& cellStateIn,
591 const TensorInfo& scratchBuffer,
592 const TensorInfo& outputStateOut,
593 const TensorInfo& cellStateOut,
594 const TensorInfo& output,
595 const LstmDescriptor& descriptor,
596 const LstmInputParamsInfo& paramsInfo,
597 Optional<std::string&> reasonIfUnsupported) const
598{
599 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonLstmFloatWorkloadValidate,
600 reasonIfUnsupported,
601 input,
602 outputStateIn,
603 cellStateIn,
604 scratchBuffer,
605 outputStateOut,
606 cellStateOut,
607 output,
608 descriptor,
609 paramsInfo);
610}
611
Nattapat Chaimanowong4e6597a2018-12-20 14:14:06 +0000612bool NeonLayerSupport::IsMaximumSupported(const TensorInfo& input0,
613 const TensorInfo& input1,
614 const TensorInfo& output,
615 Optional<std::string&> reasonIfUnsupported) const
616{
617 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonMaximumWorkloadValidate,
618 reasonIfUnsupported,
619 input0,
620 input1,
621 output);
622}
623
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100624bool NeonLayerSupport::IsMeanSupported(const TensorInfo& input,
625 const TensorInfo& output,
626 const MeanDescriptor& descriptor,
627 Optional<std::string&> reasonIfUnsupported) const
narpra0132b90462018-09-13 11:07:48 +0100628{
Matthew Benthamfd899962018-12-31 15:49:42 +0000629 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonMeanWorkloadValidate,
630 reasonIfUnsupported,
631 input,
632 output,
633 descriptor);
narpra0132b90462018-09-13 11:07:48 +0100634}
635
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100636bool NeonLayerSupport::IsMergerSupported(const std::vector<const TensorInfo*> inputs,
Nikhil Raj8599a412018-11-19 14:51:07 +0000637 const TensorInfo& output,
Jim Flynne242f2d2019-05-22 14:24:13 +0100638 const MergerDescriptor& descriptor,
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100639 Optional<std::string&> reasonIfUnsupported) const
640{
Jim Flynne242f2d2019-05-22 14:24:13 +0100641 return IsConcatSupported(inputs, output, descriptor, reasonIfUnsupported);
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100642}
643
Conor Kennedy54b21692019-01-09 07:57:38 +0000644bool NeonLayerSupport::IsMinimumSupported(const TensorInfo& input0,
645 const TensorInfo& input1,
646 const TensorInfo& output,
647 Optional<std::string&> reasonIfUnsupported) const
648{
649 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonMinimumWorkloadValidate,
650 reasonIfUnsupported,
651 input0,
652 input1,
653 output);
654}
655
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100656bool NeonLayerSupport::IsMultiplicationSupported(const TensorInfo& input0,
657 const TensorInfo& input1,
658 const TensorInfo& output,
659 Optional<std::string&> reasonIfUnsupported) const
660{
661 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonMultiplicationWorkloadValidate,
662 reasonIfUnsupported,
663 input0,
664 input1,
Mike Kelly07810fc2020-11-12 10:58:48 +0000665 output,
666 nullptr);
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100667}
668
Pablo Telloe61f0712020-01-23 10:37:17 +0000669bool NeonLayerSupport::IsDivisionSupported(const TensorInfo& input0,
670 const TensorInfo& input1,
671 const TensorInfo& output,
672 Optional<std::string&> reasonIfUnsupported) const
673{
674 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonDivisionWorkloadValidate,
675 reasonIfUnsupported,
676 input0,
677 input1,
Mike Kelly07810fc2020-11-12 10:58:48 +0000678 output,
679 nullptr);
Pablo Telloe61f0712020-01-23 10:37:17 +0000680}
681
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100682bool NeonLayerSupport::IsNormalizationSupported(const TensorInfo& input,
683 const TensorInfo& output,
684 const NormalizationDescriptor& descriptor,
685 Optional<std::string&> reasonIfUnsupported) const
686{
687 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonNormalizationWorkloadValidate,
688 reasonIfUnsupported,
689 input,
690 output,
691 descriptor);
692}
693
694bool NeonLayerSupport::IsOutputSupported(const TensorInfo& output,
695 Optional<std::string&> reasonIfUnsupported) const
696{
Derek Lamberti901ea112019-12-10 22:07:09 +0000697 return IsNeonBackendSupported(reasonIfUnsupported, output);
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100698}
699
Éanna Ó Catháin12055742019-01-25 10:01:40 +0000700bool NeonLayerSupport::IsPadSupported(const TensorInfo& input,
701 const TensorInfo& output,
702 const PadDescriptor& descriptor,
703 Optional<std::string&> reasonIfUnsupported) const
704{
705 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonPadWorkloadValidate,
706 reasonIfUnsupported,
707 input,
708 output,
709 descriptor);
710}
711
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100712bool NeonLayerSupport::IsPermuteSupported(const TensorInfo& input,
713 const TensorInfo& output,
714 const PermuteDescriptor& descriptor,
715 Optional<std::string&> reasonIfUnsupported) const
716{
717 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonPermuteWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
telsoa014fcda012018-03-09 14:13:49 +0000718}
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100719
720bool NeonLayerSupport::IsPooling2dSupported(const TensorInfo& input,
721 const TensorInfo& output,
722 const Pooling2dDescriptor& descriptor,
723 Optional<std::string&> reasonIfUnsupported) const
724{
725 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonPooling2dWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
726}
727
Nikhil Raj9b461482019-07-03 15:58:31 +0100728bool NeonLayerSupport::IsPreluSupported(const armnn::TensorInfo &input,
729 const armnn::TensorInfo &alpha,
730 const armnn::TensorInfo &output,
731 armnn::Optional<std::string &> reasonIfUnsupported) const
732{
733 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonPreluWorkloadValidate, reasonIfUnsupported, input, alpha, output);
734}
735
James Conroycc340932020-05-12 18:08:52 +0100736bool NeonLayerSupport::IsQLstmSupported(const TensorInfo& input,
737 const TensorInfo& previousOutputIn,
738 const TensorInfo& previousCellStateIn,
739 const TensorInfo& outputStateOut,
740 const TensorInfo& cellStateOut,
741 const TensorInfo& output,
742 const QLstmDescriptor& descriptor,
743 const LstmInputParamsInfo& paramsInfo,
744 Optional<std::string&> reasonIfUnsupported) const
745{
746 // Check required here in order to pass IsLayerSupported for datatypes tests
747 if (input.GetDataType() == armnn::DataType::QAsymmS8 &&
748 previousOutputIn.GetDataType() == armnn::DataType::QAsymmS8 &&
749 previousCellStateIn.GetDataType() == armnn::DataType::QSymmS16 &&
750 outputStateOut.GetDataType() == armnn::DataType::QAsymmS8 &&
751 cellStateOut.GetDataType() == armnn::DataType::QSymmS16 &&
752 output.GetDataType() == armnn::DataType::QAsymmS8)
753 {
754 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonQLstmWorkloadValidate,
755 reasonIfUnsupported,
756 input,
757 previousCellStateIn,
758 previousOutputIn,
759 cellStateOut,
760 outputStateOut,
761 output,
762 descriptor,
763 paramsInfo);
764 }
765 else
766 {
767 return false;
768 }
769}
770
Sadik Armaganfabc2892019-05-31 09:05:11 +0100771bool NeonLayerSupport::IsQuantizeSupported(const TensorInfo& input,
772 const TensorInfo& output,
773 Optional<std::string&> reasonIfUnsupported) const
774{
775 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonQuantizeWorkloadValidate,
776 reasonIfUnsupported,
777 input,
778 output);
779}
780
Francis Murtagh4fc3c482019-08-02 13:20:54 +0100781bool NeonLayerSupport::IsQuantizedLstmSupported(const TensorInfo& input,
782 const TensorInfo& cellStateIn,
783 const TensorInfo& outputStateIn,
784 const TensorInfo& cellStateOut,
785 const TensorInfo& outputStateOut,
786 const QuantizedLstmInputParamsInfo& paramsInfo,
787 Optional<std::string&> reasonIfUnsupported) const
788{
789 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonQuantizedLstmWorkloadValidate,
790 reasonIfUnsupported,
791 input,
792 cellStateIn,
793 outputStateIn,
794 cellStateOut,
795 outputStateOut,
796 paramsInfo);
797}
798
Sadik Armagana2747482021-02-09 10:28:54 +0000799bool NeonLayerSupport::IsReduceSupported(const TensorInfo& input,
800 const TensorInfo& output,
801 const ReduceDescriptor& descriptor,
802 Optional<std::string&> reasonIfUnsupported) const
803{
804 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonReduceWorkloadValidate,
805 reasonIfUnsupported,
806 input,
807 output,
808 descriptor);
809}
810
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100811bool NeonLayerSupport::IsReshapeSupported(const TensorInfo& input,
Kevin Maya023c402019-12-12 17:28:05 +0000812 const TensorInfo& output,
Matteo Martincigh992d6dc2019-01-10 17:34:20 +0000813 const ReshapeDescriptor& descriptor,
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100814 Optional<std::string&> reasonIfUnsupported) const
815{
Jan Eilers8eb25602020-03-09 12:13:48 +0000816 armnn::IgnoreUnused(descriptor);
Kevin Maya023c402019-12-12 17:28:05 +0000817 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonReshapeWorkloadValidate,
818 reasonIfUnsupported,
819 input,
820 output);
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100821}
822
Aron Virginas-Tar169d2f12019-07-01 19:01:44 +0100823bool NeonLayerSupport::IsResizeSupported(const TensorInfo& input,
824 const TensorInfo& output,
825 const ResizeDescriptor& descriptor,
826 Optional<std::string&> reasonIfUnsupported) const
827{
Ellen Norris-Thompson37e68682019-07-15 14:23:30 +0100828 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonResizeWorkloadValidate,
829 reasonIfUnsupported,
830 input,
831 output,
832 descriptor);
Aron Virginas-Tar169d2f12019-07-01 19:01:44 +0100833}
834
Sadik Armaganc625f002018-12-17 11:32:16 +0000835bool NeonLayerSupport::IsResizeBilinearSupported(const TensorInfo& input,
836 const TensorInfo& output,
837 Optional<std::string&> reasonIfUnsupported) const
838{
Ellen Norris-Thompson37e68682019-07-15 14:23:30 +0100839 ResizeDescriptor descriptor;
840 descriptor.m_Method = ResizeMethod::Bilinear;
841 descriptor.m_DataLayout = DataLayout::NCHW;
842
843 const TensorShape& outputShape = output.GetShape();
844 descriptor.m_TargetHeight = outputShape[2];
845 descriptor.m_TargetWidth = outputShape[3];
846
847 return IsResizeSupported(input, output, descriptor, reasonIfUnsupported);
Sadik Armaganc625f002018-12-17 11:32:16 +0000848}
849
Aron Virginas-Tar0dd3b432019-09-10 13:55:09 +0100850bool NeonLayerSupport::IsRsqrtSupported(const TensorInfo& input,
851 const TensorInfo& output,
852 Optional<std::string&> reasonIfUnsupported) const
853{
josh minor4a3c6102020-01-06 16:40:46 -0600854 ElementwiseUnaryDescriptor descriptor(UnaryOperation::Rsqrt);
855 return IsElementwiseUnarySupported(input, output, descriptor, reasonIfUnsupported);
Aron Virginas-Tar0dd3b432019-09-10 13:55:09 +0100856}
857
josh minor036f02d2019-11-15 14:53:22 -0600858bool NeonLayerSupport::IsSliceSupported(const TensorInfo& input,
859 const TensorInfo& output,
860 const SliceDescriptor& descriptor,
861 Optional<std::string&> reasonIfUnsupported) const
862{
863 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonSliceWorkloadValidate,
864 reasonIfUnsupported,
865 input,
866 output,
867 descriptor);
868}
869
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100870bool NeonLayerSupport::IsSoftmaxSupported(const TensorInfo& input,
871 const TensorInfo& output,
872 const SoftmaxDescriptor& descriptor,
873 Optional<std::string&> reasonIfUnsupported) const
874{
875 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonSoftmaxWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
876}
877
Mike Kelly0be3a882020-01-24 11:27:50 +0000878bool NeonLayerSupport::IsSpaceToBatchNdSupported(const TensorInfo& input,
879 const TensorInfo& output,
880 const SpaceToBatchNdDescriptor& descriptor,
881 Optional<std::string&> reasonIfUnsupported) const
882{
883 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonSpaceToBatchNdWorkloadValidate,
884 reasonIfUnsupported,
885 input,
886 output,
887 descriptor);
888}
889
Ellen Norris-Thompson29794572019-06-26 16:40:36 +0100890bool NeonLayerSupport::IsSpaceToDepthSupported(const TensorInfo& input,
Mike Kelly0be3a882020-01-24 11:27:50 +0000891 const TensorInfo& output,
892 const SpaceToDepthDescriptor& descriptor,
893 Optional<std::string&> reasonIfUnsupported) const
Ellen Norris-Thompson29794572019-06-26 16:40:36 +0100894{
895 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonSpaceToDepthWorkloadValidate,
896 reasonIfUnsupported,
897 input,
898 output,
899 descriptor);
900}
901
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100902bool NeonLayerSupport::IsSplitterSupported(const TensorInfo& input,
903 const ViewsDescriptor& descriptor,
904 Optional<std::string&> reasonIfUnsupported) const
905{
Jan Eilers8eb25602020-03-09 12:13:48 +0000906 armnn::IgnoreUnused(descriptor);
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100907 return IsSupportedForDataTypeNeon(reasonIfUnsupported,
908 input.GetDataType(),
909 &TrueFunc<>,
910 &TrueFunc<>);
911}
912
Narumol Prangnawarat15eb5832019-05-20 15:31:05 +0100913bool NeonLayerSupport::IsSplitterSupported(const TensorInfo& input,
914 const std::vector<std::reference_wrapper<TensorInfo>>& outputs,
915 const ViewsDescriptor& descriptor,
916 Optional<std::string&> reasonIfUnsupported) const
917{
918#if defined(ARMCOMPUTENEON_ENABLED)
919 // Split along the last dimension, cannot use sub-tensors
920 // as width and height of the sub-tensors do not match
921 // the width and height of the parent tensor
922 // in case of input with more than 2D.
923 std::set<unsigned int> splitAxis = ComputeSplitAxis(descriptor, input.GetShape());
924 if (descriptor.GetNumDimensions() > 2 && splitAxis.size() == 1 &&
925 *splitAxis.begin() == descriptor.GetNumDimensions() - 1 )
926 {
927 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonSplitterWorkloadValidate,
928 reasonIfUnsupported,
929 input,
930 outputs,
931 *splitAxis.begin());
932 }
933#endif
Jan Eilers8eb25602020-03-09 12:13:48 +0000934 IgnoreUnused(descriptor);
Narumol Prangnawarat15eb5832019-05-20 15:31:05 +0100935 for (auto output : outputs)
936 {
937 if (!input.IsTypeSpaceMatch(output)) // Cannot use sub-tensors if the types are not same space
938 {
939 SetValueChecked(reasonIfUnsupported, "Neon Splitter: Types and quantization parameters must match.");
940 return false;
941 }
942 }
943 return true;
944}
945
Matthew Jackson87f65ea2019-08-01 10:01:34 +0100946bool NeonLayerSupport::IsStackSupported(const std::vector<const TensorInfo*>& inputs,
947 const TensorInfo& output,
948 const StackDescriptor& descriptor,
949 Optional<std::string&> reasonIfUnsupported) const
950{
951 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonStackWorkloadValidate,
952 reasonIfUnsupported,
953 inputs,
954 output,
955 descriptor);
956}
957
FinnWilliamsArm1fa19192019-08-02 17:26:31 +0100958bool NeonLayerSupport::IsStridedSliceSupported(const TensorInfo& input,
959 const TensorInfo& output,
960 const StridedSliceDescriptor& descriptor,
961 Optional<std::string&> reasonIfUnsupported) const
962{
963 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonStridedSliceWorkloadValidate,
964 reasonIfUnsupported,
965 input,
966 output,
967 descriptor);
968}
969
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100970bool NeonLayerSupport::IsSubtractionSupported(const TensorInfo& input0,
971 const TensorInfo& input1,
972 const TensorInfo& output,
973 Optional<std::string&> reasonIfUnsupported) const
974{
975 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonSubtractionWorkloadValidate,
976 reasonIfUnsupported,
977 input0,
978 input1,
Mike Kelly07810fc2020-11-12 10:58:48 +0000979 output,
980 nullptr);
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100981}
982
Sadik Armagan581742d2019-08-12 14:11:37 +0100983bool NeonLayerSupport::IsTransposeConvolution2dSupported(const TensorInfo& input,
984 const TensorInfo& output,
985 const TransposeConvolution2dDescriptor& descriptor,
986 const TensorInfo& weights,
987 const Optional<TensorInfo>& biases,
988 Optional<std::string&> reasonIfUnsupported) const
989{
990 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonTransposeConvolution2dWorkloadValidate,
991 reasonIfUnsupported,
992 input,
993 output,
994 descriptor,
995 weights,
996 biases);
997}
998
Mike Kellyc9ea45a2020-02-28 18:11:58 +0000999bool NeonLayerSupport::IsTransposeSupported(const TensorInfo& input,
1000 const TensorInfo& output,
1001 const TransposeDescriptor& descriptor,
1002 Optional<std::string&> reasonIfUnsupported) const
1003{
1004 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonTransposeWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
1005}
1006
Aron Virginas-Tarfc824312018-10-15 15:00:13 +01001007} // namespace armnn