blob: 66999c1a309582a7bc515edd725a44c2aa4aa02c [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"
Derek Lambertic77874a2020-04-28 13:34:56 +010030#include "workloads/NeonExpWorkload.hpp"
Teresa Charlincedd34f2020-03-30 11:17:30 +010031#include "workloads/NeonComparisonWorkload.hpp"
Mike Kelly0886ac42020-04-27 09:55:40 +010032#include "workloads/NeonConstantWorkload.hpp"
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +010033#include "workloads/NeonConvolution2dWorkload.hpp"
Aron Virginas-Tar2f00b742019-09-30 13:28:08 +010034#include "workloads/NeonDepthToSpaceWorkload.hpp"
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010035#include "workloads/NeonDepthwiseConvolutionWorkload.hpp"
Narumol Prangnawarat01961a72019-05-30 16:47:12 +010036#include "workloads/NeonDequantizeWorkload.hpp"
Sadik Armagan0d4863d2019-10-09 14:26:32 +010037#include "workloads/NeonInstanceNormalizationWorkload.hpp"
David Beck0dbe0ee2018-09-24 15:59:27 +010038#include "workloads/NeonL2NormalizationFloatWorkload.hpp"
Keith Davis69e653f2020-07-02 11:49:26 +010039#include "workloads/NeonLogSoftmaxWorkload.hpp"
James Conroy177df1e2020-11-13 10:18:51 +000040#include "workloads/NeonLogicalAndWorkload.hpp"
41#include "workloads/NeonLogicalNotWorkload.hpp"
42#include "workloads/NeonLogicalOrWorkload.hpp"
Jan Eilersad5293a2019-07-08 09:57:55 +010043#include "workloads/NeonLstmFloatWorkload.hpp"
Nattapat Chaimanowong4e6597a2018-12-20 14:14:06 +000044#include "workloads/NeonMaximumWorkload.hpp"
Matthew Benthamfd899962018-12-31 15:49:42 +000045#include "workloads/NeonMeanWorkload.hpp"
Jim Flynn39d487d2019-05-17 15:44:36 +010046#include "workloads/NeonConcatWorkload.hpp"
Conor Kennedy54b21692019-01-09 07:57:38 +000047#include "workloads/NeonMinimumWorkload.hpp"
Conor Kennedyb99480b2019-03-08 08:24:41 +000048#include "workloads/NeonMultiplicationWorkload.hpp"
Pablo Telloe61f0712020-01-23 10:37:17 +000049#include "workloads/NeonDivisionWorkload.hpp"
Sadik Armaganac472102020-03-24 09:54:36 +000050#include "workloads/NeonNegWorkload.hpp"
David Beck0dbe0ee2018-09-24 15:59:27 +010051#include "workloads/NeonNormalizationFloatWorkload.hpp"
52#include "workloads/NeonFullyConnectedWorkload.hpp"
Teresa Charlinf540eb82020-04-10 19:24:55 +010053#include "workloads/NeonGatherWorkload.hpp"
Éanna Ó Catháin12055742019-01-25 10:01:40 +000054#include "workloads/NeonPadWorkload.hpp"
David Beck0dbe0ee2018-09-24 15:59:27 +010055#include "workloads/NeonPermuteWorkload.hpp"
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +010056#include "workloads/NeonPooling2dWorkload.hpp"
Nikhil Raj9b461482019-07-03 15:58:31 +010057#include "workloads/NeonPreluWorkload.hpp"
James Conroycc340932020-05-12 18:08:52 +010058#include "workloads/NeonQLstmWorkload.hpp"
Sadik Armaganfabc2892019-05-31 09:05:11 +010059#include "workloads/NeonQuantizeWorkload.hpp"
Francis Murtagh4fc3c482019-08-02 13:20:54 +010060#include "workloads/NeonQuantizedLstmWorkload.hpp"
Sadik Armagana2747482021-02-09 10:28:54 +000061#include "workloads/NeonReduceWorkload.hpp"
Kevin Maya023c402019-12-12 17:28:05 +000062#include "workloads/NeonReshapeWorkload.hpp"
Ellen Norris-Thompson37e68682019-07-15 14:23:30 +010063#include "workloads/NeonResizeWorkload.hpp"
Aron Virginas-Tar0dd3b432019-09-10 13:55:09 +010064#include "workloads/NeonRsqrtWorkload.hpp"
josh minor036f02d2019-11-15 14:53:22 -060065#include "workloads/NeonSliceWorkload.hpp"
Sadik Armaganbe88a572020-04-30 11:39:37 +010066#include "workloads/NeonSoftmaxWorkload.hpp"
Mike Kelly0be3a882020-01-24 11:27:50 +000067#include "workloads/NeonSpaceToBatchNdWorkload.hpp"
Ellen Norris-Thompson29794572019-06-26 16:40:36 +010068#include "workloads/NeonSpaceToDepthWorkload.hpp"
Narumol Prangnawarat15eb5832019-05-20 15:31:05 +010069#include "workloads/NeonSplitterWorkload.hpp"
Matthew Jackson87f65ea2019-08-01 10:01:34 +010070#include "workloads/NeonStackWorkload.hpp"
FinnWilliamsArm1fa19192019-08-02 17:26:31 +010071#include "workloads/NeonStridedSliceWorkload.hpp"
Conor Kennedyb99480b2019-03-08 08:24:41 +000072#include "workloads/NeonSubtractionWorkload.hpp"
Sadik Armagan581742d2019-08-12 14:11:37 +010073#include "workloads/NeonTransposeConvolution2dWorkload.hpp"
Mike Kellyc9ea45a2020-02-28 18:11:58 +000074#include "workloads/NeonTransposeWorkload.hpp"
telsoa014fcda012018-03-09 14:13:49 +000075#endif
76
telsoa014fcda012018-03-09 14:13:49 +000077namespace armnn
78{
telsoa014fcda012018-03-09 14:13:49 +000079
Aron Virginas-Tarfc824312018-10-15 15:00:13 +010080namespace
arovir017ff76c52018-10-09 09:40:58 +010081{
telsoa014fcda012018-03-09 14:13:49 +000082
Derek Lamberti901ea112019-12-10 22:07:09 +000083template< typename ... Args>
84bool IsNeonBackendSupported(Optional<std::string&> reasonIfUnsupported, Args... args)
telsoa014fcda012018-03-09 14:13:49 +000085{
Jan Eilers8eb25602020-03-09 12:13:48 +000086 IgnoreUnused(reasonIfUnsupported, (args)...);
Matteo Martincighd95e9062019-01-31 15:35:59 +000087#if defined(ARMCOMPUTENEON_ENABLED)
telsoa014fcda012018-03-09 14:13:49 +000088 return true;
89#else
Derek Lamberti0790dce2019-04-15 18:37:35 +010090 SetValueChecked(reasonIfUnsupported, "The armnn library has been built without NEON support");
telsoa014fcda012018-03-09 14:13:49 +000091 return false;
92#endif
93}
94
telsoa01c577f2c2018-08-31 09:22:23 +010095template<typename FloatFunc, typename Uint8Func, typename ... Params>
arovir01085f0a42018-10-08 14:48:19 +010096bool IsSupportedForDataTypeNeon(Optional<std::string&> reasonIfUnsupported,
telsoa014fcda012018-03-09 14:13:49 +000097 DataType dataType,
telsoa01c577f2c2018-08-31 09:22:23 +010098 FloatFunc floatFuncPtr,
telsoa014fcda012018-03-09 14:13:49 +000099 Uint8Func uint8FuncPtr,
100 Params&&... params)
101{
102 return IsNeonBackendSupported(reasonIfUnsupported) &&
103 IsSupportedForDataTypeGeneric(reasonIfUnsupported,
104 dataType,
105 floatFuncPtr,
telsoa01c577f2c2018-08-31 09:22:23 +0100106 floatFuncPtr,
telsoa014fcda012018-03-09 14:13:49 +0000107 uint8FuncPtr,
narpra01db2b1602019-01-23 15:23:11 +0000108 &FalseFunc<>,
kevmay012b4d88e2019-01-24 14:05:09 +0000109 &FalseFunc<>,
telsoa014fcda012018-03-09 14:13:49 +0000110 std::forward<Params>(params)...);
111}
112
Matteo Martincighd95e9062019-01-31 15:35:59 +0000113#if defined(ARMCOMPUTENEON_ENABLED)
telsoa014fcda012018-03-09 14:13:49 +0000114template<class FuncType, class... Args>
arovir01085f0a42018-10-08 14:48:19 +0100115inline bool IsWorkloadSupported(FuncType& func, Optional<std::string&> reasonIfUnsupported, Args&&... args)
telsoa014fcda012018-03-09 14:13:49 +0000116{
117 arm_compute::Status aclStatus = func(std::forward<Args>(args)...);
118 const bool supported = (aclStatus.error_code() == arm_compute::ErrorCode::OK);
119 if (!supported && reasonIfUnsupported)
120 {
arovir01085f0a42018-10-08 14:48:19 +0100121 reasonIfUnsupported.value() = aclStatus.error_description();
telsoa014fcda012018-03-09 14:13:49 +0000122 }
123 return supported;
124}
125
126#define FORWARD_WORKLOAD_VALIDATE_FUNC(func, reasonIfUnsupported, ...) \
127 return IsWorkloadSupported(func, reasonIfUnsupported, __VA_ARGS__);
128#else
129#define FORWARD_WORKLOAD_VALIDATE_FUNC(func, reasonIfUnsupported, ...) \
Derek Lamberti901ea112019-12-10 22:07:09 +0000130 return IsNeonBackendSupported(reasonIfUnsupported, __VA_ARGS__);
telsoa014fcda012018-03-09 14:13:49 +0000131#endif
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100132} // anonymous namespace
133
Sadik Armagan045f6be2020-09-10 13:37:32 +0100134NeonLayerSupport::NeonLayerSupport(const IBackendInternal::IBackendSpecificModelContextPtr& modelContextPtr)
135 : m_ModelContextPtr(modelContextPtr)
136{
137}
138
139NeonLayerSupport::NeonLayerSupport()
140 : m_ModelContextPtr(nullptr)
141{
142}
143
Aron Virginas-Tar914e4db2019-09-09 13:36:45 +0100144bool NeonLayerSupport::IsAbsSupported(const TensorInfo& input,
145 const TensorInfo& output,
146 Optional<std::string&> reasonIfUnsupported) const
147{
josh minor4a3c6102020-01-06 16:40:46 -0600148 ElementwiseUnaryDescriptor descriptor(UnaryOperation::Abs);
149 return IsElementwiseUnarySupported(input, output, descriptor, reasonIfUnsupported);
Aron Virginas-Tar914e4db2019-09-09 13:36:45 +0100150}
151
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100152bool NeonLayerSupport::IsActivationSupported(const TensorInfo& input,
153 const TensorInfo& output,
154 const ActivationDescriptor& descriptor,
155 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000156{
Jan Eilers8eb25602020-03-09 12:13:48 +0000157 IgnoreUnused(descriptor);
telsoa01c577f2c2018-08-31 09:22:23 +0100158 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonActivationWorkloadValidate,
159 reasonIfUnsupported,
160 input,
161 output,
162 descriptor);
telsoa014fcda012018-03-09 14:13:49 +0000163}
164
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100165bool NeonLayerSupport::IsAdditionSupported(const TensorInfo& input0,
166 const TensorInfo& input1,
167 const TensorInfo& output,
168 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000169{
telsoa01c577f2c2018-08-31 09:22:23 +0100170 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonAdditionWorkloadValidate,
171 reasonIfUnsupported,
172 input0,
173 input1,
Mike Kelly07810fc2020-11-12 10:58:48 +0000174 output,
175 nullptr);
telsoa014fcda012018-03-09 14:13:49 +0000176}
177
James Conroyd47a0642019-09-17 14:22:06 +0100178bool NeonLayerSupport::IsArgMinMaxSupported(const TensorInfo& input,
179 const TensorInfo& output,
180 const ArgMinMaxDescriptor& descriptor,
181 Optional<std::string&> reasonIfUnsupported) const
182{
183 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonArgMinMaxWorkloadValidate,
184 reasonIfUnsupported,
185 input,
186 output,
187 descriptor);
188}
189
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100190bool NeonLayerSupport::IsBatchNormalizationSupported(const TensorInfo& input,
191 const TensorInfo& output,
192 const TensorInfo& mean,
193 const TensorInfo& var,
194 const TensorInfo& beta,
195 const TensorInfo& gamma,
196 const BatchNormalizationDescriptor& descriptor,
197 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000198{
telsoa01c577f2c2018-08-31 09:22:23 +0100199 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonBatchNormalizationValidate,
200 reasonIfUnsupported,
201 input,
202 output,
203 mean,
204 var,
205 beta,
206 gamma,
Mike Kelly07810fc2020-11-12 10:58:48 +0000207 descriptor,
208 nullptr);
telsoa014fcda012018-03-09 14:13:49 +0000209}
210
Mike Kelly56858022020-01-27 12:14:47 +0000211bool NeonLayerSupport::IsBatchToSpaceNdSupported(const TensorInfo& input,
212 const TensorInfo& output,
213 const BatchToSpaceNdDescriptor& descriptor,
214 Optional<std::string&> reasonIfUnsupported) const
215{
216 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonBatchToSpaceNdWorkloadValidate,
217 reasonIfUnsupported,
218 input,
219 output,
220 descriptor);
221}
222
Aron Virginas-Tar77bfb5e2019-10-16 17:45:38 +0100223bool NeonLayerSupport::IsComparisonSupported(const TensorInfo& input0,
224 const TensorInfo& input1,
225 const TensorInfo& output,
226 const ComparisonDescriptor& descriptor,
227 Optional<std::string&> reasonIfUnsupported) const
228{
Aron Virginas-Tar77bfb5e2019-10-16 17:45:38 +0100229
Teresa Charlincedd34f2020-03-30 11:17:30 +0100230 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonComparisonWorkloadValidate,
231 reasonIfUnsupported,
232 input0,
233 input1,
234 output,
235 descriptor);
Aron Virginas-Tar77bfb5e2019-10-16 17:45:38 +0100236}
237
Jim Flynn906f9462019-05-10 13:55:21 +0100238bool NeonLayerSupport::IsConcatSupported(const std::vector<const TensorInfo*> inputs,
239 const TensorInfo& output,
Jim Flynne242f2d2019-05-22 14:24:13 +0100240 const ConcatDescriptor& descriptor,
Jim Flynn906f9462019-05-10 13:55:21 +0100241 Optional<std::string&> reasonIfUnsupported) const
242{
Jim Flynne242f2d2019-05-22 14:24:13 +0100243 if (descriptor.GetNumDimensions() <= descriptor.GetConcatAxis())
244 {
245 SetValueChecked(reasonIfUnsupported, "Neon Concat: Concat axis > Number of dimensions.");
246 return false;
247 }
248
249 unsigned int concatInnerAxis = (descriptor.GetNumDimensions() - descriptor.GetConcatAxis()) - 1;
250 if(concatInnerAxis < 3) // Width, height, or channels
251 {
252 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonConcatWorkloadValidate,
253 reasonIfUnsupported,
254 inputs,
255 output,
256 descriptor);
257 }
258 else if (concatInnerAxis == 3)
259 {
260 for (auto& input : inputs)
261 {
262 if (input && !output.IsTypeSpaceMatch(*input)) // Cannot use sub-tensors if the types are not same space
263 {
264 SetValueChecked(reasonIfUnsupported, "Neon Concat: Types and quantization parameters must match.");
265 return false;
266 }
267 }
268 return true; // Sub-tensors support concat along batch
269 }
270 else // > 4 dimensions not supported.
271 {
272 SetValueChecked(reasonIfUnsupported, "Neon Concat: Maximum of 4 dimensions supported.");
273 return false;
274 }
Jim Flynn906f9462019-05-10 13:55:21 +0100275}
276
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100277bool NeonLayerSupport::IsConstantSupported(const TensorInfo& output,
278 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000279{
Mike Kelly0886ac42020-04-27 09:55:40 +0100280 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonConstantWorkloadValidate,
281 reasonIfUnsupported,
282 output);
telsoa014fcda012018-03-09 14:13:49 +0000283}
284
Narumol Prangnawarat250d3922020-03-30 16:11:04 +0100285bool NeonLayerSupport::IsConvertBf16ToFp32Supported(const TensorInfo& input,
286 const TensorInfo& output,
287 Optional<std::string&> reasonIfUnsupported) const
288{
289 armnn::IgnoreUnused(input);
290 armnn::IgnoreUnused(output);
291 armnn::IgnoreUnused(reasonIfUnsupported);
292 return true;
293}
294
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100295bool NeonLayerSupport::IsConvertFp16ToFp32Supported(const TensorInfo& input,
296 const TensorInfo& output,
297 Optional<std::string&> reasonIfUnsupported) const
298{
Jan Eilers8eb25602020-03-09 12:13:48 +0000299 armnn::IgnoreUnused(input);
300 armnn::IgnoreUnused(output);
301 armnn::IgnoreUnused(reasonIfUnsupported);
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100302 return true;
303}
304
Narumol Prangnawarat250d3922020-03-30 16:11:04 +0100305bool NeonLayerSupport::IsConvertFp32ToBf16Supported(const TensorInfo& input,
306 const TensorInfo& output,
307 Optional<std::string&> reasonIfUnsupported) const
308{
309 armnn::IgnoreUnused(input);
310 armnn::IgnoreUnused(output);
311 armnn::IgnoreUnused(reasonIfUnsupported);
312 return true;
313}
314
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100315bool NeonLayerSupport::IsConvertFp32ToFp16Supported(const TensorInfo& input,
316 const TensorInfo& output,
317 Optional<std::string&> reasonIfUnsupported) const
318{
Jan Eilers8eb25602020-03-09 12:13:48 +0000319 armnn::IgnoreUnused(input);
320 armnn::IgnoreUnused(output);
321 armnn::IgnoreUnused(reasonIfUnsupported);
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100322 return true;
323}
324
325bool NeonLayerSupport::IsConvolution2dSupported(const TensorInfo& input,
326 const TensorInfo& output,
327 const Convolution2dDescriptor& descriptor,
328 const TensorInfo& weights,
329 const Optional<TensorInfo>& biases,
330 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000331{
Sadik Armagan045f6be2020-09-10 13:37:32 +0100332 bool isFastMathEnabled = false;
333#if defined(ARMCOMPUTENEON_ENABLED)
334 if (m_ModelContextPtr)
335 {
336 if (m_ModelContextPtr.get() != nullptr)
337 {
Sadik Armagan04a72972020-09-14 15:44:18 +0100338 auto modelOptions = dynamic_cast<NeonBackendModelContext*>(m_ModelContextPtr.get());
Sadik Armagan045f6be2020-09-10 13:37:32 +0100339 if (modelOptions)
340 {
341 isFastMathEnabled = modelOptions->IsFastMathEnabled();
342 }
343 }
344 }
345#endif
346
surmeh013537c2c2018-05-18 16:31:43 +0100347 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonConvolution2dWorkloadValidate,
348 reasonIfUnsupported,
349 input,
350 output,
351 descriptor,
352 weights,
Sadik Armagan045f6be2020-09-10 13:37:32 +0100353 biases,
Mike Kelly07810fc2020-11-12 10:58:48 +0000354 isFastMathEnabled,
355 nullptr);
telsoa014fcda012018-03-09 14:13:49 +0000356}
357
Aron Virginas-Tar2f00b742019-09-30 13:28:08 +0100358bool NeonLayerSupport::IsDepthToSpaceSupported(const TensorInfo& input,
359 const TensorInfo& output,
360 const DepthToSpaceDescriptor& descriptor,
361 Optional<std::string&> reasonIfUnsupported) const
362{
363 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonDepthToSpaceWorkloadValidate,
364 reasonIfUnsupported,
365 input,
366 output,
367 descriptor);
368}
369
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100370bool NeonLayerSupport::IsDepthwiseConvolutionSupported(const TensorInfo& input,
371 const TensorInfo& output,
372 const DepthwiseConvolution2dDescriptor& descriptor,
373 const TensorInfo& weights,
374 const Optional<TensorInfo>& biases,
375 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000376{
telsoa01c577f2c2018-08-31 09:22:23 +0100377 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonDepthwiseConvolutionWorkloadValidate,
378 reasonIfUnsupported,
379 input,
380 output,
381 descriptor,
382 weights,
Mike Kelly07810fc2020-11-12 10:58:48 +0000383 biases,
384 nullptr);
telsoa014fcda012018-03-09 14:13:49 +0000385}
386
Narumol Prangnawarat01961a72019-05-30 16:47:12 +0100387bool NeonLayerSupport::IsDequantizeSupported(const TensorInfo& input,
388 const TensorInfo& output,
389 Optional<std::string&> reasonIfUnsupported) const
390{
391 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonDequantizeWorkloadValidate,
392 reasonIfUnsupported,
393 input,
394 output);
395}
396
Pablo Tellof0bd6832019-04-26 17:58:13 +0100397bool NeonLayerSupport::IsDilatedDepthwiseConvolutionSupported(const TensorInfo& input,
398 const TensorInfo& output,
399 const DepthwiseConvolution2dDescriptor& descriptor,
400 const TensorInfo& weights,
401 const Optional<TensorInfo>& biases,
402 Optional<std::string&> reasonIfUnsupported) const
403{
404 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonDepthwiseConvolutionWorkloadValidate,
405 reasonIfUnsupported,
406 input,
407 output,
408 descriptor,
409 weights,
Mike Kelly07810fc2020-11-12 10:58:48 +0000410 biases,
411 nullptr);
Pablo Tellof0bd6832019-04-26 17:58:13 +0100412}
413
josh minor4a3c6102020-01-06 16:40:46 -0600414bool NeonLayerSupport::IsElementwiseUnarySupported(const TensorInfo& input,
415 const TensorInfo& output,
416 const ElementwiseUnaryDescriptor& descriptor,
417 Optional<std::string&> reasonIfUnsupported) const
418{
Derek Lambertic77874a2020-04-28 13:34:56 +0100419 switch(descriptor.m_Operation)
josh minor4a3c6102020-01-06 16:40:46 -0600420 {
Derek Lambertic77874a2020-04-28 13:34:56 +0100421 case UnaryOperation::Abs:
422 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonAbsWorkloadValidate,
423 reasonIfUnsupported,
424 input,
425 output);
426 case UnaryOperation::Exp:
427 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonExpWorkloadValidate,
428 reasonIfUnsupported,
429 input,
430 output);
431 case UnaryOperation::Neg:
432 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonNegWorkloadValidate,
433 reasonIfUnsupported,
434 input,
435 output);
436 case UnaryOperation::Rsqrt:
437 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonRsqrtWorkloadValidate,
438 reasonIfUnsupported,
439 input,
440 output);
James Conroy177df1e2020-11-13 10:18:51 +0000441 case UnaryOperation::LogicalNot:
442 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonLogicalNotWorkloadValidate,
443 reasonIfUnsupported,
444 input,
445 output);
Derek Lambertic77874a2020-04-28 13:34:56 +0100446 default:
447 return false;
josh minor4a3c6102020-01-06 16:40:46 -0600448 }
josh minor4a3c6102020-01-06 16:40:46 -0600449}
450
Teresa Charlin4b10fef2020-07-29 09:36:41 +0100451bool NeonLayerSupport::IsFillSupported(const TensorInfo& input,
452 const TensorInfo& output,
453 const FillDescriptor& descriptor,
454 Optional<std::string&> reasonIfUnsupported) const
Sadik Armagana792a052020-06-23 16:22:23 +0100455{
Teresa Charlin4b10fef2020-07-29 09:36:41 +0100456 armnn::IgnoreUnused(input);
457 armnn::IgnoreUnused(output);
458 armnn::IgnoreUnused(descriptor);
459
460 return IsNeonBackendSupported(reasonIfUnsupported);
Sadik Armagana792a052020-06-23 16:22:23 +0100461}
462
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100463bool NeonLayerSupport::IsFloorSupported(const TensorInfo& input,
464 const TensorInfo& output,
465 Optional<std::string&> reasonIfUnsupported) const
466{
Jan Eilers8eb25602020-03-09 12:13:48 +0000467 armnn::IgnoreUnused(output);
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100468 return IsNeonBackendSupported(reasonIfUnsupported) &&
469 IsSupportedForDataTypeGeneric(reasonIfUnsupported,
470 input.GetDataType(),
471 &FalseFuncF16<>,
472 &TrueFunc<>,
narpra01db2b1602019-01-23 15:23:11 +0000473 &FalseFuncU8<>,
kevmay012b4d88e2019-01-24 14:05:09 +0000474 &FalseFuncI32<>,
475 &FalseFuncU8<>);
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100476}
477
478bool NeonLayerSupport::IsFullyConnectedSupported(const TensorInfo& input,
479 const TensorInfo& output,
480 const TensorInfo& weights,
481 const TensorInfo& biases,
482 const FullyConnectedDescriptor& descriptor,
483 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000484{
telsoa01c577f2c2018-08-31 09:22:23 +0100485 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonFullyConnectedWorkloadValidate,
486 reasonIfUnsupported,
487 input,
488 output,
489 weights,
490 biases,
Mike Kelly07810fc2020-11-12 10:58:48 +0000491 descriptor,
492 nullptr);
telsoa014fcda012018-03-09 14:13:49 +0000493}
494
Teresa Charlinf540eb82020-04-10 19:24:55 +0100495bool NeonLayerSupport::IsGatherSupported(const TensorInfo& input0,
496 const TensorInfo& input1,
497 const TensorInfo& output,
Teresa Charlin52664732020-06-29 16:27:03 +0100498 const GatherDescriptor& descriptor,
Teresa Charlinf540eb82020-04-10 19:24:55 +0100499 Optional<std::string&> reasonIfUnsupported) const
500{
501 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonGatherWorkloadValidate,
502 reasonIfUnsupported,
503 input0,
504 input1,
Teresa Charlin52664732020-06-29 16:27:03 +0100505 output,
506 descriptor);
Teresa Charlinf540eb82020-04-10 19:24:55 +0100507}
508
kevmay01eed85922019-01-28 08:37:25 +0000509bool NeonLayerSupport::IsGreaterSupported(const armnn::TensorInfo& input0,
510 const armnn::TensorInfo& input1,
511 const armnn::TensorInfo& output,
512 armnn::Optional<std::string&> reasonIfUnsupported) const
513{
Aron Virginas-Tar77bfb5e2019-10-16 17:45:38 +0100514 ComparisonDescriptor descriptor(ComparisonOperation::Greater);
515 return IsComparisonSupported(input0, input1, output, descriptor, reasonIfUnsupported);
kevmay01eed85922019-01-28 08:37:25 +0000516}
517
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100518bool NeonLayerSupport::IsInputSupported(const TensorInfo& input,
519 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000520{
Derek Lamberti901ea112019-12-10 22:07:09 +0000521 return IsNeonBackendSupported(reasonIfUnsupported, input);
telsoa014fcda012018-03-09 14:13:49 +0000522}
523
Sadik Armagan0d4863d2019-10-09 14:26:32 +0100524bool NeonLayerSupport::IsInstanceNormalizationSupported(const TensorInfo& input,
525 const TensorInfo& output,
526 const InstanceNormalizationDescriptor& descriptor,
527 Optional<std::string&> reasonIfUnsupported) const
528{
529 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonInstanceNormalizationWorkloadValidate,
530 reasonIfUnsupported,
531 input,
532 output,
533 descriptor);
534}
535
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100536bool NeonLayerSupport::IsL2NormalizationSupported(const TensorInfo& input,
537 const TensorInfo& output,
538 const L2NormalizationDescriptor& descriptor,
539 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000540{
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100541 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonL2NormalizationWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
telsoa014fcda012018-03-09 14:13:49 +0000542}
543
James Conroy177df1e2020-11-13 10:18:51 +0000544bool NeonLayerSupport::IsLogicalBinarySupported(const TensorInfo& input0,
545 const TensorInfo& input1,
546 const TensorInfo& output,
547 const LogicalBinaryDescriptor& descriptor,
548 Optional<std::string&> reasonIfUnsupported) const
549{
550 switch(descriptor.m_Operation)
551 {
552 case LogicalBinaryOperation::LogicalAnd:
553 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonLogicalAndWorkloadValidate,
554 reasonIfUnsupported,
555 input0,
556 input1,
557 output);
558 case LogicalBinaryOperation::LogicalOr:
559 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonLogicalOrWorkloadValidate,
560 reasonIfUnsupported,
561 input0,
562 input1,
563 output);
564 default:
565 return false;
566 }
567}
568
Keith Davis69e653f2020-07-02 11:49:26 +0100569bool NeonLayerSupport::IsLogSoftmaxSupported(const TensorInfo& input,
570 const TensorInfo& output,
571 const LogSoftmaxDescriptor& descriptor,
572 Optional<std::string&> reasonIfUnsupported) const
573{
574 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonLogSoftmaxWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
575}
576
Jan Eilersad5293a2019-07-08 09:57:55 +0100577bool NeonLayerSupport::IsLstmSupported(const TensorInfo& input,
578 const TensorInfo& outputStateIn,
579 const TensorInfo& cellStateIn,
580 const TensorInfo& scratchBuffer,
581 const TensorInfo& outputStateOut,
582 const TensorInfo& cellStateOut,
583 const TensorInfo& output,
584 const LstmDescriptor& descriptor,
585 const LstmInputParamsInfo& paramsInfo,
586 Optional<std::string&> reasonIfUnsupported) const
587{
588 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonLstmFloatWorkloadValidate,
589 reasonIfUnsupported,
590 input,
591 outputStateIn,
592 cellStateIn,
593 scratchBuffer,
594 outputStateOut,
595 cellStateOut,
596 output,
597 descriptor,
598 paramsInfo);
599}
600
Nattapat Chaimanowong4e6597a2018-12-20 14:14:06 +0000601bool NeonLayerSupport::IsMaximumSupported(const TensorInfo& input0,
602 const TensorInfo& input1,
603 const TensorInfo& output,
604 Optional<std::string&> reasonIfUnsupported) const
605{
606 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonMaximumWorkloadValidate,
607 reasonIfUnsupported,
608 input0,
609 input1,
610 output);
611}
612
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100613bool NeonLayerSupport::IsMeanSupported(const TensorInfo& input,
614 const TensorInfo& output,
615 const MeanDescriptor& descriptor,
616 Optional<std::string&> reasonIfUnsupported) const
narpra0132b90462018-09-13 11:07:48 +0100617{
Matthew Benthamfd899962018-12-31 15:49:42 +0000618 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonMeanWorkloadValidate,
619 reasonIfUnsupported,
620 input,
621 output,
622 descriptor);
narpra0132b90462018-09-13 11:07:48 +0100623}
624
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100625bool NeonLayerSupport::IsMergerSupported(const std::vector<const TensorInfo*> inputs,
Nikhil Raj8599a412018-11-19 14:51:07 +0000626 const TensorInfo& output,
Jim Flynne242f2d2019-05-22 14:24:13 +0100627 const MergerDescriptor& descriptor,
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100628 Optional<std::string&> reasonIfUnsupported) const
629{
Jim Flynne242f2d2019-05-22 14:24:13 +0100630 return IsConcatSupported(inputs, output, descriptor, reasonIfUnsupported);
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100631}
632
Conor Kennedy54b21692019-01-09 07:57:38 +0000633bool NeonLayerSupport::IsMinimumSupported(const TensorInfo& input0,
634 const TensorInfo& input1,
635 const TensorInfo& output,
636 Optional<std::string&> reasonIfUnsupported) const
637{
638 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonMinimumWorkloadValidate,
639 reasonIfUnsupported,
640 input0,
641 input1,
642 output);
643}
644
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100645bool NeonLayerSupport::IsMultiplicationSupported(const TensorInfo& input0,
646 const TensorInfo& input1,
647 const TensorInfo& output,
648 Optional<std::string&> reasonIfUnsupported) const
649{
650 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonMultiplicationWorkloadValidate,
651 reasonIfUnsupported,
652 input0,
653 input1,
Mike Kelly07810fc2020-11-12 10:58:48 +0000654 output,
655 nullptr);
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100656}
657
Pablo Telloe61f0712020-01-23 10:37:17 +0000658bool NeonLayerSupport::IsDivisionSupported(const TensorInfo& input0,
659 const TensorInfo& input1,
660 const TensorInfo& output,
661 Optional<std::string&> reasonIfUnsupported) const
662{
663 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonDivisionWorkloadValidate,
664 reasonIfUnsupported,
665 input0,
666 input1,
Mike Kelly07810fc2020-11-12 10:58:48 +0000667 output,
668 nullptr);
Pablo Telloe61f0712020-01-23 10:37:17 +0000669}
670
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100671bool NeonLayerSupport::IsNormalizationSupported(const TensorInfo& input,
672 const TensorInfo& output,
673 const NormalizationDescriptor& descriptor,
674 Optional<std::string&> reasonIfUnsupported) const
675{
676 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonNormalizationWorkloadValidate,
677 reasonIfUnsupported,
678 input,
679 output,
680 descriptor);
681}
682
683bool NeonLayerSupport::IsOutputSupported(const TensorInfo& output,
684 Optional<std::string&> reasonIfUnsupported) const
685{
Derek Lamberti901ea112019-12-10 22:07:09 +0000686 return IsNeonBackendSupported(reasonIfUnsupported, output);
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100687}
688
Éanna Ó Catháin12055742019-01-25 10:01:40 +0000689bool NeonLayerSupport::IsPadSupported(const TensorInfo& input,
690 const TensorInfo& output,
691 const PadDescriptor& descriptor,
692 Optional<std::string&> reasonIfUnsupported) const
693{
694 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonPadWorkloadValidate,
695 reasonIfUnsupported,
696 input,
697 output,
698 descriptor);
699}
700
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100701bool NeonLayerSupport::IsPermuteSupported(const TensorInfo& input,
702 const TensorInfo& output,
703 const PermuteDescriptor& descriptor,
704 Optional<std::string&> reasonIfUnsupported) const
705{
706 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonPermuteWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
telsoa014fcda012018-03-09 14:13:49 +0000707}
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100708
709bool NeonLayerSupport::IsPooling2dSupported(const TensorInfo& input,
710 const TensorInfo& output,
711 const Pooling2dDescriptor& descriptor,
712 Optional<std::string&> reasonIfUnsupported) const
713{
714 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonPooling2dWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
715}
716
Nikhil Raj9b461482019-07-03 15:58:31 +0100717bool NeonLayerSupport::IsPreluSupported(const armnn::TensorInfo &input,
718 const armnn::TensorInfo &alpha,
719 const armnn::TensorInfo &output,
720 armnn::Optional<std::string &> reasonIfUnsupported) const
721{
722 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonPreluWorkloadValidate, reasonIfUnsupported, input, alpha, output);
723}
724
James Conroycc340932020-05-12 18:08:52 +0100725bool NeonLayerSupport::IsQLstmSupported(const TensorInfo& input,
726 const TensorInfo& previousOutputIn,
727 const TensorInfo& previousCellStateIn,
728 const TensorInfo& outputStateOut,
729 const TensorInfo& cellStateOut,
730 const TensorInfo& output,
731 const QLstmDescriptor& descriptor,
732 const LstmInputParamsInfo& paramsInfo,
733 Optional<std::string&> reasonIfUnsupported) const
734{
735 // Check required here in order to pass IsLayerSupported for datatypes tests
736 if (input.GetDataType() == armnn::DataType::QAsymmS8 &&
737 previousOutputIn.GetDataType() == armnn::DataType::QAsymmS8 &&
738 previousCellStateIn.GetDataType() == armnn::DataType::QSymmS16 &&
739 outputStateOut.GetDataType() == armnn::DataType::QAsymmS8 &&
740 cellStateOut.GetDataType() == armnn::DataType::QSymmS16 &&
741 output.GetDataType() == armnn::DataType::QAsymmS8)
742 {
743 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonQLstmWorkloadValidate,
744 reasonIfUnsupported,
745 input,
746 previousCellStateIn,
747 previousOutputIn,
748 cellStateOut,
749 outputStateOut,
750 output,
751 descriptor,
752 paramsInfo);
753 }
754 else
755 {
756 return false;
757 }
758}
759
Sadik Armaganfabc2892019-05-31 09:05:11 +0100760bool NeonLayerSupport::IsQuantizeSupported(const TensorInfo& input,
761 const TensorInfo& output,
762 Optional<std::string&> reasonIfUnsupported) const
763{
764 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonQuantizeWorkloadValidate,
765 reasonIfUnsupported,
766 input,
767 output);
768}
769
Francis Murtagh4fc3c482019-08-02 13:20:54 +0100770bool NeonLayerSupport::IsQuantizedLstmSupported(const TensorInfo& input,
771 const TensorInfo& cellStateIn,
772 const TensorInfo& outputStateIn,
773 const TensorInfo& cellStateOut,
774 const TensorInfo& outputStateOut,
775 const QuantizedLstmInputParamsInfo& paramsInfo,
776 Optional<std::string&> reasonIfUnsupported) const
777{
778 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonQuantizedLstmWorkloadValidate,
779 reasonIfUnsupported,
780 input,
781 cellStateIn,
782 outputStateIn,
783 cellStateOut,
784 outputStateOut,
785 paramsInfo);
786}
787
Sadik Armagana2747482021-02-09 10:28:54 +0000788bool NeonLayerSupport::IsReduceSupported(const TensorInfo& input,
789 const TensorInfo& output,
790 const ReduceDescriptor& descriptor,
791 Optional<std::string&> reasonIfUnsupported) const
792{
793 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonReduceWorkloadValidate,
794 reasonIfUnsupported,
795 input,
796 output,
797 descriptor);
798}
799
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100800bool NeonLayerSupport::IsReshapeSupported(const TensorInfo& input,
Kevin Maya023c402019-12-12 17:28:05 +0000801 const TensorInfo& output,
Matteo Martincigh992d6dc2019-01-10 17:34:20 +0000802 const ReshapeDescriptor& descriptor,
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100803 Optional<std::string&> reasonIfUnsupported) const
804{
Jan Eilers8eb25602020-03-09 12:13:48 +0000805 armnn::IgnoreUnused(descriptor);
Kevin Maya023c402019-12-12 17:28:05 +0000806 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonReshapeWorkloadValidate,
807 reasonIfUnsupported,
808 input,
809 output);
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100810}
811
Aron Virginas-Tar169d2f12019-07-01 19:01:44 +0100812bool NeonLayerSupport::IsResizeSupported(const TensorInfo& input,
813 const TensorInfo& output,
814 const ResizeDescriptor& descriptor,
815 Optional<std::string&> reasonIfUnsupported) const
816{
Ellen Norris-Thompson37e68682019-07-15 14:23:30 +0100817 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonResizeWorkloadValidate,
818 reasonIfUnsupported,
819 input,
820 output,
821 descriptor);
Aron Virginas-Tar169d2f12019-07-01 19:01:44 +0100822}
823
Sadik Armaganc625f002018-12-17 11:32:16 +0000824bool NeonLayerSupport::IsResizeBilinearSupported(const TensorInfo& input,
825 const TensorInfo& output,
826 Optional<std::string&> reasonIfUnsupported) const
827{
Ellen Norris-Thompson37e68682019-07-15 14:23:30 +0100828 ResizeDescriptor descriptor;
829 descriptor.m_Method = ResizeMethod::Bilinear;
830 descriptor.m_DataLayout = DataLayout::NCHW;
831
832 const TensorShape& outputShape = output.GetShape();
833 descriptor.m_TargetHeight = outputShape[2];
834 descriptor.m_TargetWidth = outputShape[3];
835
836 return IsResizeSupported(input, output, descriptor, reasonIfUnsupported);
Sadik Armaganc625f002018-12-17 11:32:16 +0000837}
838
Aron Virginas-Tar0dd3b432019-09-10 13:55:09 +0100839bool NeonLayerSupport::IsRsqrtSupported(const TensorInfo& input,
840 const TensorInfo& output,
841 Optional<std::string&> reasonIfUnsupported) const
842{
josh minor4a3c6102020-01-06 16:40:46 -0600843 ElementwiseUnaryDescriptor descriptor(UnaryOperation::Rsqrt);
844 return IsElementwiseUnarySupported(input, output, descriptor, reasonIfUnsupported);
Aron Virginas-Tar0dd3b432019-09-10 13:55:09 +0100845}
846
josh minor036f02d2019-11-15 14:53:22 -0600847bool NeonLayerSupport::IsSliceSupported(const TensorInfo& input,
848 const TensorInfo& output,
849 const SliceDescriptor& descriptor,
850 Optional<std::string&> reasonIfUnsupported) const
851{
852 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonSliceWorkloadValidate,
853 reasonIfUnsupported,
854 input,
855 output,
856 descriptor);
857}
858
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100859bool NeonLayerSupport::IsSoftmaxSupported(const TensorInfo& input,
860 const TensorInfo& output,
861 const SoftmaxDescriptor& descriptor,
862 Optional<std::string&> reasonIfUnsupported) const
863{
864 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonSoftmaxWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
865}
866
Mike Kelly0be3a882020-01-24 11:27:50 +0000867bool NeonLayerSupport::IsSpaceToBatchNdSupported(const TensorInfo& input,
868 const TensorInfo& output,
869 const SpaceToBatchNdDescriptor& descriptor,
870 Optional<std::string&> reasonIfUnsupported) const
871{
872 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonSpaceToBatchNdWorkloadValidate,
873 reasonIfUnsupported,
874 input,
875 output,
876 descriptor);
877}
878
Ellen Norris-Thompson29794572019-06-26 16:40:36 +0100879bool NeonLayerSupport::IsSpaceToDepthSupported(const TensorInfo& input,
Mike Kelly0be3a882020-01-24 11:27:50 +0000880 const TensorInfo& output,
881 const SpaceToDepthDescriptor& descriptor,
882 Optional<std::string&> reasonIfUnsupported) const
Ellen Norris-Thompson29794572019-06-26 16:40:36 +0100883{
884 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonSpaceToDepthWorkloadValidate,
885 reasonIfUnsupported,
886 input,
887 output,
888 descriptor);
889}
890
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100891bool NeonLayerSupport::IsSplitterSupported(const TensorInfo& input,
892 const ViewsDescriptor& descriptor,
893 Optional<std::string&> reasonIfUnsupported) const
894{
Jan Eilers8eb25602020-03-09 12:13:48 +0000895 armnn::IgnoreUnused(descriptor);
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100896 return IsSupportedForDataTypeNeon(reasonIfUnsupported,
897 input.GetDataType(),
898 &TrueFunc<>,
899 &TrueFunc<>);
900}
901
Narumol Prangnawarat15eb5832019-05-20 15:31:05 +0100902bool NeonLayerSupport::IsSplitterSupported(const TensorInfo& input,
903 const std::vector<std::reference_wrapper<TensorInfo>>& outputs,
904 const ViewsDescriptor& descriptor,
905 Optional<std::string&> reasonIfUnsupported) const
906{
907#if defined(ARMCOMPUTENEON_ENABLED)
908 // Split along the last dimension, cannot use sub-tensors
909 // as width and height of the sub-tensors do not match
910 // the width and height of the parent tensor
911 // in case of input with more than 2D.
912 std::set<unsigned int> splitAxis = ComputeSplitAxis(descriptor, input.GetShape());
913 if (descriptor.GetNumDimensions() > 2 && splitAxis.size() == 1 &&
914 *splitAxis.begin() == descriptor.GetNumDimensions() - 1 )
915 {
916 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonSplitterWorkloadValidate,
917 reasonIfUnsupported,
918 input,
919 outputs,
920 *splitAxis.begin());
921 }
922#endif
Jan Eilers8eb25602020-03-09 12:13:48 +0000923 IgnoreUnused(descriptor);
Narumol Prangnawarat15eb5832019-05-20 15:31:05 +0100924 for (auto output : outputs)
925 {
926 if (!input.IsTypeSpaceMatch(output)) // Cannot use sub-tensors if the types are not same space
927 {
928 SetValueChecked(reasonIfUnsupported, "Neon Splitter: Types and quantization parameters must match.");
929 return false;
930 }
931 }
932 return true;
933}
934
Matthew Jackson87f65ea2019-08-01 10:01:34 +0100935bool NeonLayerSupport::IsStackSupported(const std::vector<const TensorInfo*>& inputs,
936 const TensorInfo& output,
937 const StackDescriptor& descriptor,
938 Optional<std::string&> reasonIfUnsupported) const
939{
940 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonStackWorkloadValidate,
941 reasonIfUnsupported,
942 inputs,
943 output,
944 descriptor);
945}
946
FinnWilliamsArm1fa19192019-08-02 17:26:31 +0100947bool NeonLayerSupport::IsStridedSliceSupported(const TensorInfo& input,
948 const TensorInfo& output,
949 const StridedSliceDescriptor& descriptor,
950 Optional<std::string&> reasonIfUnsupported) const
951{
952 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonStridedSliceWorkloadValidate,
953 reasonIfUnsupported,
954 input,
955 output,
956 descriptor);
957}
958
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100959bool NeonLayerSupport::IsSubtractionSupported(const TensorInfo& input0,
960 const TensorInfo& input1,
961 const TensorInfo& output,
962 Optional<std::string&> reasonIfUnsupported) const
963{
964 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonSubtractionWorkloadValidate,
965 reasonIfUnsupported,
966 input0,
967 input1,
Mike Kelly07810fc2020-11-12 10:58:48 +0000968 output,
969 nullptr);
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100970}
971
Sadik Armagan581742d2019-08-12 14:11:37 +0100972bool NeonLayerSupport::IsTransposeConvolution2dSupported(const TensorInfo& input,
973 const TensorInfo& output,
974 const TransposeConvolution2dDescriptor& descriptor,
975 const TensorInfo& weights,
976 const Optional<TensorInfo>& biases,
977 Optional<std::string&> reasonIfUnsupported) const
978{
979 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonTransposeConvolution2dWorkloadValidate,
980 reasonIfUnsupported,
981 input,
982 output,
983 descriptor,
984 weights,
985 biases);
986}
987
Mike Kellyc9ea45a2020-02-28 18:11:58 +0000988bool NeonLayerSupport::IsTransposeSupported(const TensorInfo& input,
989 const TensorInfo& output,
990 const TransposeDescriptor& descriptor,
991 Optional<std::string&> reasonIfUnsupported) const
992{
993 FORWARD_WORKLOAD_VALIDATE_FUNC(NeonTransposeWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
994}
995
Aron Virginas-Tarfc824312018-10-15 15:00:13 +0100996} // namespace armnn