blob: 497a6435dfb883d0086c9d6a3204ec1aa21e3454 [file] [log] [blame]
telsoa014fcda012018-03-09 14:13:49 +00001//
2// 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//
5
telsoa014fcda012018-03-09 14:13:49 +00006#include "ClLayerSupport.hpp"
David Beck3e9e1152018-10-17 14:17:50 +01007#include "ClBackendId.hpp"
arovir017c22c702018-10-09 11:16:46 +01008
David Beck3cc9a622018-10-12 10:38:31 +01009#include <armnn/Descriptors.hpp>
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000010#include <InternalTypes.hpp>
11#include <LayerSupportCommon.hpp>
telsoa014fcda012018-03-09 14:13:49 +000012
David Beck111b5d92018-11-12 14:59:37 +000013#include <backendsCommon/BackendRegistry.hpp>
David Beck3e9e1152018-10-17 14:17:50 +010014
telsoa014fcda012018-03-09 14:13:49 +000015#include <boost/core/ignore_unused.hpp>
16
Matteo Martincighd95e9062019-01-31 15:35:59 +000017#if defined(ARMCOMPUTECL_ENABLED)
Narumol Prangnawarat74135832019-05-23 15:07:33 +010018#include <aclCommon/ArmComputeUtils.hpp>
David Beckac42efd2018-09-26 17:41:13 +010019#include "workloads/ClAdditionWorkload.hpp"
Nattapat Chaimanowonge06757e2018-10-11 15:39:18 +010020#include "workloads/ClActivationWorkload.hpp"
David Beckac42efd2018-09-26 17:41:13 +010021#include "workloads/ClBatchNormalizationFloatWorkload.hpp"
Mike Kelly831faed2018-11-28 11:52:08 +000022#include "workloads/ClBatchToSpaceNdWorkload.hpp"
David Beckac42efd2018-09-26 17:41:13 +010023#include "workloads/ClConvertFp16ToFp32Workload.hpp"
24#include "workloads/ClConvertFp32ToFp16Workload.hpp"
Matthew Benthamd8067922018-10-03 17:18:04 +010025#include "workloads/ClConvolution2dWorkload.hpp"
Jim Flynn983daec2019-05-29 16:20:16 +010026#include "workloads/ClDequantizeWorkload.hpp"
Matthew Benthamd8777392018-10-08 09:38:55 +010027#include "workloads/ClDepthwiseConvolutionWorkload.hpp"
David Beckac42efd2018-09-26 17:41:13 +010028#include "workloads/ClDivisionFloatWorkload.hpp"
David Beckac42efd2018-09-26 17:41:13 +010029#include "workloads/ClFullyConnectedWorkload.hpp"
Nattapat Chaimanowongc6a41ff2019-01-29 09:56:02 +000030#include "workloads/ClGreaterWorkload.hpp"
arovir01085f0a42018-10-08 14:48:19 +010031#include "workloads/ClL2NormalizationFloatWorkload.hpp"
32#include "workloads/ClLstmFloatWorkload.hpp"
keidav01a959ee52018-12-19 10:04:58 +000033#include "workloads/ClMaximumWorkload.hpp"
Matteo Martincigh28dcab62018-10-19 16:40:03 +010034#include "workloads/ClMeanWorkload.hpp"
Jim Flynn69059412019-05-17 13:03:57 +010035#include "workloads/ClConcatWorkload.hpp"
saoste019292aa32019-01-08 13:55:59 +000036#include "workloads/ClMinimumWorkload.hpp"
arovir01085f0a42018-10-08 14:48:19 +010037#include "workloads/ClMultiplicationWorkload.hpp"
David Beckac42efd2018-09-26 17:41:13 +010038#include "workloads/ClNormalizationFloatWorkload.hpp"
arovir01085f0a42018-10-08 14:48:19 +010039#include "workloads/ClPadWorkload.hpp"
40#include "workloads/ClPermuteWorkload.hpp"
Nattapat Chaimanowongac9e0962018-10-10 17:18:35 +010041#include "workloads/ClPooling2dWorkload.hpp"
Nikhil Raj91e4c6d2019-07-05 12:22:58 +010042#include "workloads/ClPreluWorkload.hpp"
Sadik Armagan20ec2492019-05-31 09:09:44 +010043#include "workloads/ClQuantizeWorkload.hpp"
David Beckac42efd2018-09-26 17:41:13 +010044#include "workloads/ClSoftmaxBaseWorkload.hpp"
Sadik Armaganf4464322018-12-20 16:19:12 +000045#include "workloads/ClSpaceToBatchNdWorkload.hpp"
James Conroyd2aa85e2019-07-01 17:12:40 +010046#include "workloads/ClSpaceToDepthWorkload.hpp"
Narumol Prangnawarat74135832019-05-23 15:07:33 +010047#include "workloads/ClSplitterWorkload.hpp"
keidav01d74dc912018-12-10 18:16:07 +000048#include "workloads/ClStridedSliceWorkload.hpp"
David Beckac42efd2018-09-26 17:41:13 +010049#include "workloads/ClSubtractionWorkload.hpp"
Aron Virginas-Tar7a3e2fe2019-06-27 18:54:47 +010050#include "workloads/ClTransposeConvolution2dWorkload.hpp"
telsoa014fcda012018-03-09 14:13:49 +000051#endif
52
53using namespace boost;
54
55namespace armnn
56{
arovir017c22c702018-10-09 11:16:46 +010057
telsoa014fcda012018-03-09 14:13:49 +000058namespace
59{
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +010060
telsoa014fcda012018-03-09 14:13:49 +000061template<unsigned int FilterSize>
62bool IsMatchingSize2d(const TensorInfo& weightInfo)
63{
telsoa01c577f2c2018-08-31 09:22:23 +010064 // Width & Height must match.
telsoa014fcda012018-03-09 14:13:49 +000065 return (weightInfo.GetShape()[3] == FilterSize) && (weightInfo.GetShape()[2] == FilterSize);
66}
67
68template<uint32_t ValidStride>
69bool IsMatchingStride(uint32_t actualStride)
70{
71 return ValidStride == actualStride;
72}
73
74template<uint32_t FirstStride, uint32_t SecondStride, uint32_t... ValidStrides>
75bool IsMatchingStride(uint32_t actualStride)
76{
77 return IsMatchingStride<FirstStride>(actualStride) || IsMatchingStride<SecondStride, ValidStrides...>(actualStride);
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +010078}
telsoa014fcda012018-03-09 14:13:49 +000079
arovir01085f0a42018-10-08 14:48:19 +010080bool IsClBackendSupported(Optional<std::string&> reasonIfUnsupported)
telsoa014fcda012018-03-09 14:13:49 +000081{
Matteo Martincighd95e9062019-01-31 15:35:59 +000082#if defined(ARMCOMPUTECL_ENABLED)
telsoa014fcda012018-03-09 14:13:49 +000083 return true;
84#else
arovir01085f0a42018-10-08 14:48:19 +010085 if (reasonIfUnsupported)
telsoa014fcda012018-03-09 14:13:49 +000086 {
arovir01085f0a42018-10-08 14:48:19 +010087 reasonIfUnsupported.value() = "The armnn library has been built without CL support";
telsoa014fcda012018-03-09 14:13:49 +000088 }
89 return false;
90#endif
91}
92
Matteo Martincighd95e9062019-01-31 15:35:59 +000093#if defined(ARMCOMPUTECL_ENABLED)
telsoa014fcda012018-03-09 14:13:49 +000094#define FORWARD_CL_LAYER_SUPPORT_FUNC(expr) (expr)
95#else
96#define FORWARD_CL_LAYER_SUPPORT_FUNC(expr) IsClBackendSupported(reasonIfUnsupported)
97#endif
98
Matteo Martincighd95e9062019-01-31 15:35:59 +000099#if defined(ARMCOMPUTECL_ENABLED)
telsoa014fcda012018-03-09 14:13:49 +0000100template<class FuncType, class... Args>
arovir01085f0a42018-10-08 14:48:19 +0100101inline bool IsWorkloadSupported(FuncType&& func, Optional<std::string&> reasonIfUnsupported, Args&&... args)
telsoa014fcda012018-03-09 14:13:49 +0000102{
103 arm_compute::Status aclStatus = func(std::forward<Args>(args)...);
104 const bool supported = (aclStatus.error_code() == arm_compute::ErrorCode::OK);
105 if (!supported && reasonIfUnsupported)
106 {
arovir01085f0a42018-10-08 14:48:19 +0100107 reasonIfUnsupported.value() = aclStatus.error_description();
telsoa014fcda012018-03-09 14:13:49 +0000108 }
109 return supported;
110}
111
112#define FORWARD_WORKLOAD_VALIDATE_FUNC(func, reasonIfUnsupported, ...) \
113 return IsWorkloadSupported(func, reasonIfUnsupported, __VA_ARGS__);
114#else
115#define FORWARD_WORKLOAD_VALIDATE_FUNC(func, reasonIfUnsupported, ...) \
116 return IsClBackendSupported(reasonIfUnsupported);
117#endif
118
telsoa01c577f2c2018-08-31 09:22:23 +0100119template<typename FloatFunc, typename Uint8Func, typename ... Params>
arovir01085f0a42018-10-08 14:48:19 +0100120bool IsSupportedForDataTypeCl(Optional<std::string&> reasonIfUnsupported,
telsoa014fcda012018-03-09 14:13:49 +0000121 DataType dataType,
telsoa01c577f2c2018-08-31 09:22:23 +0100122 FloatFunc floatFuncPtr,
telsoa014fcda012018-03-09 14:13:49 +0000123 Uint8Func uint8FuncPtr,
124 Params&&... params)
125{
126 return IsClBackendSupported(reasonIfUnsupported) &&
127 IsSupportedForDataTypeGeneric(reasonIfUnsupported,
128 dataType,
129 floatFuncPtr,
telsoa01c577f2c2018-08-31 09:22:23 +0100130 floatFuncPtr,
telsoa014fcda012018-03-09 14:13:49 +0000131 uint8FuncPtr,
narpra01db2b1602019-01-23 15:23:11 +0000132 &FalseFunc<>,
kevmay012b4d88e2019-01-24 14:05:09 +0000133 &FalseFunc<>,
telsoa014fcda012018-03-09 14:13:49 +0000134 std::forward<Params>(params)...);
135}
136
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100137} // anonymous namespace
138
139bool ClLayerSupport::IsActivationSupported(const TensorInfo& input,
140 const TensorInfo& output,
141 const ActivationDescriptor& descriptor,
142 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000143{
telsoa01c577f2c2018-08-31 09:22:23 +0100144 FORWARD_WORKLOAD_VALIDATE_FUNC(ClActivationWorkloadValidate,
145 reasonIfUnsupported,
146 input,
147 output,
148 descriptor);
telsoa014fcda012018-03-09 14:13:49 +0000149}
150
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100151bool ClLayerSupport::IsAdditionSupported(const TensorInfo& input0,
152 const TensorInfo& input1,
153 const TensorInfo& output,
154 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000155{
arovir01085f0a42018-10-08 14:48:19 +0100156 FORWARD_WORKLOAD_VALIDATE_FUNC(ClAdditionValidate,
157 reasonIfUnsupported,
158 input0,
159 input1,
160 output);
telsoa014fcda012018-03-09 14:13:49 +0000161}
162
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100163bool ClLayerSupport::IsBatchNormalizationSupported(const TensorInfo& input,
164 const TensorInfo& output,
165 const TensorInfo& mean,
166 const TensorInfo& var,
167 const TensorInfo& beta,
168 const TensorInfo& gamma,
169 const BatchNormalizationDescriptor& descriptor,
170 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000171{
telsoa01c577f2c2018-08-31 09:22:23 +0100172 FORWARD_WORKLOAD_VALIDATE_FUNC(ClBatchNormalizationValidate,
173 reasonIfUnsupported,
174 input,
175 output,
176 mean,
177 var,
178 beta,
179 gamma,
180 descriptor);
telsoa014fcda012018-03-09 14:13:49 +0000181}
182
Mike Kelly831faed2018-11-28 11:52:08 +0000183bool ClLayerSupport::IsBatchToSpaceNdSupported(const TensorInfo& input,
184 const TensorInfo& output,
185 const BatchToSpaceNdDescriptor& descriptor,
186 Optional<std::string&> reasonIfUnsupported) const
187{
188 FORWARD_WORKLOAD_VALIDATE_FUNC(ClBatchToSpaceNdWorkloadValidate,
189 reasonIfUnsupported,
190 input,
191 output,
192 descriptor);
193}
194
Jim Flynn906f9462019-05-10 13:55:21 +0100195bool ClLayerSupport::IsConcatSupported(const std::vector<const TensorInfo*> inputs,
196 const TensorInfo& output,
Jim Flynne242f2d2019-05-22 14:24:13 +0100197 const ConcatDescriptor& descriptor,
Jim Flynn906f9462019-05-10 13:55:21 +0100198 Optional<std::string&> reasonIfUnsupported) const
199{
Jim Flynne242f2d2019-05-22 14:24:13 +0100200 if (descriptor.GetNumDimensions() <= descriptor.GetConcatAxis())
201 {
202 SetValueChecked(reasonIfUnsupported, "Cl Concat: Concat axis > Number of dimensions.");
203 return false;
204 }
205
206 unsigned int concatInnerAxis = (descriptor.GetNumDimensions() - descriptor.GetConcatAxis()) - 1;
207 if(concatInnerAxis < 3) // Width, height, or channels
208 {
209 FORWARD_WORKLOAD_VALIDATE_FUNC(ClConcatWorkloadValidate,
210 reasonIfUnsupported,
211 inputs,
212 output,
213 descriptor);
214 }
215 else if (concatInnerAxis == 3)
216 {
217 // We rely on the sub-tensor optimization to handle the batch dimension for 4D tensors. If we can't use
218 // sub-tensors for this then we can't support it. Here is where we check that the sub-tensors will work.
219 for (auto& input : inputs)
220 {
221 if (input && !output.IsTypeSpaceMatch(*input)) // Cannot use sub-tensors if the types are not same space
222 {
223 SetValueChecked(reasonIfUnsupported, "Cl Concat: Types and quantization parameters must match.");
224 return false;
225 }
226 }
227 return true; // Sub-tensors support concat along batch
228 }
229 else // > 4 dimensions not supported.
230 {
231 SetValueChecked(reasonIfUnsupported, "Cl Concat: Maximum of 4 dimensions supported.");
232 return false;
233 }
Jim Flynn906f9462019-05-10 13:55:21 +0100234}
235
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100236bool ClLayerSupport::IsConstantSupported(const TensorInfo& output,
237 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000238{
239 return IsSupportedForDataTypeCl(reasonIfUnsupported,
240 output.GetDataType(),
241 &TrueFunc<>,
242 &FalseFuncU8<>);
243}
244
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100245bool ClLayerSupport::IsConvertFp16ToFp32Supported(const TensorInfo& input,
246 const TensorInfo& output,
247 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000248{
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100249 FORWARD_WORKLOAD_VALIDATE_FUNC(ClConvertFp16ToFp32WorkloadValidate,
250 reasonIfUnsupported,
251 input,
252 output);
telsoa014fcda012018-03-09 14:13:49 +0000253}
254
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100255bool ClLayerSupport::IsConvertFp32ToFp16Supported(const TensorInfo& input,
256 const TensorInfo& output,
257 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000258{
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100259 FORWARD_WORKLOAD_VALIDATE_FUNC(ClConvertFp32ToFp16WorkloadValidate,
260 reasonIfUnsupported,
261 input,
262 output);
telsoa014fcda012018-03-09 14:13:49 +0000263}
264
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100265bool ClLayerSupport::IsConvolution2dSupported(const TensorInfo& input,
266 const TensorInfo& output,
267 const Convolution2dDescriptor& descriptor,
268 const TensorInfo& weights,
269 const Optional<TensorInfo>& biases,
270 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000271{
surmeh013537c2c2018-05-18 16:31:43 +0100272 FORWARD_WORKLOAD_VALIDATE_FUNC(ClConvolution2dWorkloadValidate,
273 reasonIfUnsupported,
274 input,
275 output,
276 descriptor,
277 weights,
278 biases);
telsoa014fcda012018-03-09 14:13:49 +0000279}
280
Jim Flynn983daec2019-05-29 16:20:16 +0100281bool ClLayerSupport::IsDequantizeSupported(const TensorInfo& input,
282 const TensorInfo& output,
283 Optional<std::string&> reasonIfUnsupported) const
284{
285 FORWARD_WORKLOAD_VALIDATE_FUNC(ClDequantizeWorkloadValidate,
286 reasonIfUnsupported,
287 input,
288 output);
289}
290
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100291bool ClLayerSupport::IsDepthwiseConvolutionSupported(const TensorInfo& input,
292 const TensorInfo& output,
293 const DepthwiseConvolution2dDescriptor& descriptor,
294 const TensorInfo& weights,
295 const Optional<TensorInfo>& biases,
296 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000297{
telsoa01c577f2c2018-08-31 09:22:23 +0100298 FORWARD_WORKLOAD_VALIDATE_FUNC(ClDepthwiseConvolutionWorkloadValidate,
299 reasonIfUnsupported,
300 input,
301 output,
302 descriptor,
303 weights,
304 biases);
telsoa014fcda012018-03-09 14:13:49 +0000305}
306
Pablo Tellof0bd6832019-04-26 17:58:13 +0100307bool ClLayerSupport::IsDilatedDepthwiseConvolutionSupported(const TensorInfo& input,
308 const TensorInfo& output,
309 const DepthwiseConvolution2dDescriptor& descriptor,
310 const TensorInfo& weights,
311 const Optional<TensorInfo>& biases,
312 Optional<std::string&> reasonIfUnsupported) const
313{
314 FORWARD_WORKLOAD_VALIDATE_FUNC(ClDepthwiseConvolutionWorkloadValidate,
315 reasonIfUnsupported,
316 input,
317 output,
318 descriptor,
319 weights,
320 biases);
321}
322
323
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100324bool ClLayerSupport::IsDivisionSupported(const TensorInfo& input0,
325 const TensorInfo& input1,
326 const TensorInfo& output,
327 Optional<std::string&> reasonIfUnsupported) const
Francis Murtaghe7a86a42018-08-29 12:42:10 +0100328{
329 FORWARD_WORKLOAD_VALIDATE_FUNC(ClDivisionWorkloadValidate,
330 reasonIfUnsupported,
331 input0,
332 input1,
333 output);
334}
335
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100336bool ClLayerSupport::IsFloorSupported(const TensorInfo& input,
337 const TensorInfo& output,
338 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000339{
340 ignore_unused(output);
telsoa01c577f2c2018-08-31 09:22:23 +0100341 return IsClBackendSupported(reasonIfUnsupported) &&
342 IsSupportedForDataTypeGeneric(reasonIfUnsupported,
343 input.GetDataType(),
344 &FalseFuncF16<>,
345 &TrueFunc<>,
narpra01db2b1602019-01-23 15:23:11 +0000346 &FalseFuncU8<>,
kevmay012b4d88e2019-01-24 14:05:09 +0000347 &FalseFuncI32<>,
348 &FalseFuncU8<>);
telsoa01c577f2c2018-08-31 09:22:23 +0100349}
350
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100351bool ClLayerSupport::IsFullyConnectedSupported(const TensorInfo& input,
352 const TensorInfo& output,
353 const TensorInfo& weights,
354 const TensorInfo& biases,
355 const FullyConnectedDescriptor& descriptor,
356 Optional<std::string&> reasonIfUnsupported) const
357{
358 FORWARD_WORKLOAD_VALIDATE_FUNC(ClFullyConnectedWorkloadValidate,
359 reasonIfUnsupported,
360 input,
361 output,
362 weights,
363 biases,
364 descriptor);
365}
366
Nattapat Chaimanowongc6a41ff2019-01-29 09:56:02 +0000367bool ClLayerSupport::IsGreaterSupported(const TensorInfo& input0,
368 const TensorInfo& input1,
369 const TensorInfo& output,
370 Optional<std::string&> reasonIfUnsupported) const
371{
372 FORWARD_WORKLOAD_VALIDATE_FUNC(ClGreaterWorkloadValidate,
373 reasonIfUnsupported,
374 input0,
375 input1,
376 output);
377}
378
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100379bool ClLayerSupport::IsInputSupported(const TensorInfo& input,
380 Optional<std::string&> reasonIfUnsupported) const
381{
382 return IsSupportedForDataTypeCl(reasonIfUnsupported,
383 input.GetDataType(),
384 &TrueFunc<>,
385 &TrueFunc<>);
386}
387
388bool ClLayerSupport::IsL2NormalizationSupported(const TensorInfo& input,
389 const TensorInfo& output,
390 const L2NormalizationDescriptor& descriptor,
391 Optional<std::string&> reasonIfUnsupported) const
392{
393 FORWARD_WORKLOAD_VALIDATE_FUNC(ClL2NormalizationWorkloadValidate,
394 reasonIfUnsupported,
395 input,
396 output,
397 descriptor);
398}
399
400bool ClLayerSupport::IsLstmSupported(const TensorInfo& input,
401 const TensorInfo& outputStateIn,
402 const TensorInfo& cellStateIn,
403 const TensorInfo& scratchBuffer,
404 const TensorInfo& outputStateOut,
405 const TensorInfo& cellStateOut,
406 const TensorInfo& output,
407 const LstmDescriptor& descriptor,
408 const TensorInfo& inputToForgetWeights,
409 const TensorInfo& inputToCellWeights,
410 const TensorInfo& inputToOutputWeights,
411 const TensorInfo& recurrentToForgetWeights,
412 const TensorInfo& recurrentToCellWeights,
413 const TensorInfo& recurrentToOutputWeights,
414 const TensorInfo& forgetGateBias,
415 const TensorInfo& cellBias,
416 const TensorInfo& outputGateBias,
417 const TensorInfo* inputToInputWeights,
418 const TensorInfo* recurrentToInputWeights,
419 const TensorInfo* cellToInputWeights,
420 const TensorInfo* inputGateBias,
421 const TensorInfo* projectionWeights,
422 const TensorInfo* projectionBias,
423 const TensorInfo* cellToForgetWeights,
424 const TensorInfo* cellToOutputWeights,
Jan Eilers38e05bd2019-06-26 13:10:09 +0100425 Optional<std::string&> reasonIfUnsupported,
426 const TensorInfo* inputLayerNormWeights,
427 const TensorInfo* forgetLayerNormWeights,
428 const TensorInfo* cellLayerNormWeights,
429 const TensorInfo* outputLayerNormWeights) const
telsoa01c577f2c2018-08-31 09:22:23 +0100430{
arovir01085f0a42018-10-08 14:48:19 +0100431 FORWARD_WORKLOAD_VALIDATE_FUNC(ClLstmFloatWorkloadValidate,
432 reasonIfUnsupported,
433 input,
434 outputStateIn,
435 cellStateIn,
436 scratchBuffer,
437 outputStateOut,
438 cellStateOut,
439 output,
440 descriptor,
441 inputToForgetWeights,
442 inputToCellWeights,
443 inputToOutputWeights,
444 recurrentToForgetWeights,
445 recurrentToCellWeights,
446 recurrentToOutputWeights,
447 forgetGateBias,
448 cellBias,
449 outputGateBias,
450 inputToInputWeights,
451 recurrentToInputWeights,
452 cellToInputWeights,
453 inputGateBias,
454 projectionWeights,
455 projectionBias,
456 cellToForgetWeights,
457 cellToOutputWeights);
telsoa01c577f2c2018-08-31 09:22:23 +0100458}
459
keidav01a959ee52018-12-19 10:04:58 +0000460bool ClLayerSupport::IsMaximumSupported(const TensorInfo& input0,
461 const TensorInfo& input1,
462 const TensorInfo& output,
463 Optional<std::string&> reasonIfUnsupported) const
464{
465 FORWARD_WORKLOAD_VALIDATE_FUNC(ClMaximumWorkloadValidate,
466 reasonIfUnsupported,
467 input0,
468 input1,
469 output);
470}
471
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100472bool ClLayerSupport::IsMeanSupported(const TensorInfo& input,
473 const TensorInfo& output,
474 const MeanDescriptor& descriptor,
475 Optional<std::string&> reasonIfUnsupported) const
narpra0132b90462018-09-13 11:07:48 +0100476{
Matteo Martincigh28dcab62018-10-19 16:40:03 +0100477 FORWARD_WORKLOAD_VALIDATE_FUNC(ClMeanValidate,
478 reasonIfUnsupported,
479 input,
480 output,
481 descriptor);
narpra0132b90462018-09-13 11:07:48 +0100482}
483
Matteo Martincigh992d6dc2019-01-10 17:34:20 +0000484bool ClLayerSupport::IsMemCopySupported(const TensorInfo &input,
485 const TensorInfo &output,
486 Optional<std::string &> reasonIfUnsupported) const
487{
488 ignore_unused(input);
489 ignore_unused(output);
490 return true;
491}
492
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100493bool ClLayerSupport::IsMergerSupported(const std::vector<const TensorInfo*> inputs,
Nikhil Raj8599a412018-11-19 14:51:07 +0000494 const TensorInfo& output,
Jim Flynne242f2d2019-05-22 14:24:13 +0100495 const MergerDescriptor& descriptor,
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100496 Optional<std::string&> reasonIfUnsupported) const
497{
Jim Flynne242f2d2019-05-22 14:24:13 +0100498 return IsConcatSupported(inputs, output, descriptor, reasonIfUnsupported);
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100499}
500
saoste019292aa32019-01-08 13:55:59 +0000501bool ClLayerSupport::IsMinimumSupported(const TensorInfo& input0,
502 const TensorInfo& input1,
503 const TensorInfo& output,
504 Optional<std::string&> reasonIfUnsupported) const
505{
506 FORWARD_WORKLOAD_VALIDATE_FUNC(ClMinimumWorkloadValidate,
507 reasonIfUnsupported,
508 input0,
509 input1,
510 output);
511}
512
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100513bool ClLayerSupport::IsMultiplicationSupported(const TensorInfo& input0,
514 const TensorInfo& input1,
515 const TensorInfo& output,
516 Optional<std::string&> reasonIfUnsupported) const
517{
518 FORWARD_WORKLOAD_VALIDATE_FUNC(ClMultiplicationWorkloadValidate,
519 reasonIfUnsupported,
520 input0,
521 input1,
522 output);
523}
524
525bool ClLayerSupport::IsNormalizationSupported(const TensorInfo& input,
526 const TensorInfo& output,
527 const NormalizationDescriptor& descriptor,
528 Optional<std::string&> reasonIfUnsupported) const
529{
530 FORWARD_WORKLOAD_VALIDATE_FUNC(ClNormalizationWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
531}
532
533bool ClLayerSupport::IsOutputSupported(const TensorInfo& output,
534 Optional<std::string&> reasonIfUnsupported) const
535{
kevmay012b4d88e2019-01-24 14:05:09 +0000536 return IsClBackendSupported(reasonIfUnsupported) &&
537 IsSupportedForDataTypeGeneric(reasonIfUnsupported,
538 output.GetDataType(),
539 &TrueFunc<>,
540 &TrueFunc<>,
541 &TrueFunc<>,
542 &FalseFuncI32<>,
543 &TrueFunc<>);
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100544}
545
546bool ClLayerSupport::IsPadSupported(const TensorInfo& input,
547 const TensorInfo& output,
548 const PadDescriptor& descriptor,
549 Optional<std::string&> reasonIfUnsupported) const
arovir01085f0a42018-10-08 14:48:19 +0100550{
551 FORWARD_WORKLOAD_VALIDATE_FUNC(ClPadValidate,
552 reasonIfUnsupported,
553 input,
554 output,
555 descriptor);
556}
557
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100558bool ClLayerSupport::IsPermuteSupported(const TensorInfo& input,
559 const TensorInfo& output,
560 const PermuteDescriptor& descriptor,
561 Optional<std::string&> reasonIfUnsupported) const
562{
563 ignore_unused(input);
564 ignore_unused(output);
565 FORWARD_WORKLOAD_VALIDATE_FUNC(ClPermuteWorkloadValidate, reasonIfUnsupported, descriptor);
telsoa014fcda012018-03-09 14:13:49 +0000566}
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100567
568bool ClLayerSupport::IsPooling2dSupported(const TensorInfo& input,
569 const TensorInfo& output,
570 const Pooling2dDescriptor& descriptor,
571 Optional<std::string&> reasonIfUnsupported) const
572{
573 FORWARD_WORKLOAD_VALIDATE_FUNC(ClPooling2dWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
574}
575
Nikhil Raj91e4c6d2019-07-05 12:22:58 +0100576bool ClLayerSupport::IsPreluSupported(const armnn::TensorInfo &input,
577 const armnn::TensorInfo &alpha,
578 const armnn::TensorInfo &output,
579 armnn::Optional<std::string &> reasonIfUnsupported) const
580{
581 FORWARD_WORKLOAD_VALIDATE_FUNC(ClPreluWorkloadValidate, reasonIfUnsupported, input, alpha, output);
582}
583
Sadik Armagan20ec2492019-05-31 09:09:44 +0100584bool ClLayerSupport::IsQuantizeSupported(const TensorInfo& input,
585 const TensorInfo& output,
586 Optional<std::string&> reasonIfUnsupported) const
587{
588 FORWARD_WORKLOAD_VALIDATE_FUNC(ClQuantizeWorkloadValidate,
589 reasonIfUnsupported,
590 input,
591 output);
592}
593
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100594bool ClLayerSupport::IsReshapeSupported(const TensorInfo& input,
Matteo Martincigh992d6dc2019-01-10 17:34:20 +0000595 const ReshapeDescriptor& descriptor,
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100596 Optional<std::string&> reasonIfUnsupported) const
597{
598 ignore_unused(input);
Matteo Martincigh992d6dc2019-01-10 17:34:20 +0000599 ignore_unused(descriptor);
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100600 ignore_unused(reasonIfUnsupported);
601 return true;
602}
603
Aron Virginas-Tar169d2f12019-07-01 19:01:44 +0100604bool ClLayerSupport::IsResizeSupported(const TensorInfo& input,
605 const TensorInfo& output,
606 const ResizeDescriptor& descriptor,
607 Optional<std::string&> reasonIfUnsupported) const
608{
609 ignore_unused(output);
610
611 if (descriptor.m_Method == ResizeMethod::Bilinear)
612 {
613 return IsSupportedForDataTypeCl(reasonIfUnsupported,
614 input.GetDataType(),
615 &TrueFunc<>,
616 &FalseFuncU8<>);
617 }
618
619 return false;
620}
621
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100622bool ClLayerSupport::IsResizeBilinearSupported(const TensorInfo& input,
Sadik Armaganc625f002018-12-17 11:32:16 +0000623 const TensorInfo& output,
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100624 Optional<std::string&> reasonIfUnsupported) const
625{
Sadik Armaganc625f002018-12-17 11:32:16 +0000626 ignore_unused(output);
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100627 return IsSupportedForDataTypeCl(reasonIfUnsupported,
628 input.GetDataType(),
629 &TrueFunc<>,
630 &FalseFuncU8<>);
631}
632
633bool ClLayerSupport::IsSoftmaxSupported(const TensorInfo& input,
634 const TensorInfo& output,
635 const SoftmaxDescriptor& descriptor,
636 Optional<std::string&> reasonIfUnsupported) const
637{
638 ignore_unused(descriptor);
639 FORWARD_WORKLOAD_VALIDATE_FUNC(ClSoftmaxWorkloadValidate, reasonIfUnsupported, input, output);
640}
641
Sadik Armaganf4464322018-12-20 16:19:12 +0000642bool ClLayerSupport::IsSpaceToBatchNdSupported(const TensorInfo& input,
643 const TensorInfo& output,
644 const SpaceToBatchNdDescriptor& descriptor,
645 Optional<std::string&> reasonIfUnsupported) const
646{
647 FORWARD_WORKLOAD_VALIDATE_FUNC(ClSpaceToBatchNdWorkloadValidate,
648 reasonIfUnsupported,
649 input,
650 output,
651 descriptor);
652}
653
James Conroyd2aa85e2019-07-01 17:12:40 +0100654bool ClLayerSupport::IsSpaceToDepthSupported(const TensorInfo& input,
655 const TensorInfo& output,
656 const SpaceToDepthDescriptor& descriptor,
657 Optional<std::string&> reasonIfUnsupported) const
658{
659 FORWARD_WORKLOAD_VALIDATE_FUNC(ClSpaceToDepthWorkloadValidate,
660 reasonIfUnsupported,
661 input,
662 output,
663 descriptor);
664}
665
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100666bool ClLayerSupport::IsSplitterSupported(const TensorInfo& input,
667 const ViewsDescriptor& descriptor,
668 Optional<std::string&> reasonIfUnsupported) const
669{
670 ignore_unused(descriptor);
671 return IsSupportedForDataTypeCl(reasonIfUnsupported,
672 input.GetDataType(),
673 &TrueFunc<>,
674 &TrueFunc<>);
675}
676
Narumol Prangnawarat15eb5832019-05-20 15:31:05 +0100677bool ClLayerSupport::IsSplitterSupported(const TensorInfo& input,
678 const std::vector<std::reference_wrapper<TensorInfo>>& outputs,
679 const ViewsDescriptor& descriptor,
680 Optional<std::string&> reasonIfUnsupported) const
681{
Narumol Prangnawarat74135832019-05-23 15:07:33 +0100682#if defined(ARMCOMPUTECL_ENABLED)
683 // Split along the last dimension, cannot use sub-tensors
684 // as width and height of the sub-tensors do not match
685 // the width and height of the parent tensor
686 // in case of input with more than 2D.
687 std::set<unsigned int> splitAxis = ComputeSplitAxis(descriptor, input.GetShape());
688 if (descriptor.GetNumDimensions() > 2 && splitAxis.size() == 1 &&
689 *splitAxis.begin() == descriptor.GetNumDimensions() - 1 )
690 {
691 FORWARD_WORKLOAD_VALIDATE_FUNC(ClSplitterWorkloadValidate,
692 reasonIfUnsupported,
693 input,
694 outputs,
695 *splitAxis.begin());
696 }
697#endif
698 for (auto output : outputs)
699 {
700 if (!input.IsTypeSpaceMatch(output)) // Cannot use sub-tensors if the types are not same space
701 {
702 SetValueChecked(reasonIfUnsupported, "Cl Splitter: Types and quantization parameters must match.");
703 return false;
704 }
705 }
706 return true;
Narumol Prangnawarat15eb5832019-05-20 15:31:05 +0100707}
708
keidav01d74dc912018-12-10 18:16:07 +0000709bool ClLayerSupport::IsStridedSliceSupported(const TensorInfo& input,
710 const TensorInfo& output,
711 const StridedSliceDescriptor& descriptor,
712 Optional<std::string&> reasonIfUnsupported) const
713{
714 FORWARD_WORKLOAD_VALIDATE_FUNC(ClStridedSliceWorkloadValidate,
715 reasonIfUnsupported,
716 input,
717 output,
718 descriptor);
719}
720
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100721bool ClLayerSupport::IsSubtractionSupported(const TensorInfo& input0,
722 const TensorInfo& input1,
723 const TensorInfo& output,
724 Optional<std::string&> reasonIfUnsupported) const
725{
726 FORWARD_WORKLOAD_VALIDATE_FUNC(ClSubtractionValidate,
727 reasonIfUnsupported,
728 input0,
729 input1,
730 output);
731}
732
Aron Virginas-Tar7a3e2fe2019-06-27 18:54:47 +0100733bool ClLayerSupport::IsTransposeConvolution2dSupported(const TensorInfo& input,
734 const TensorInfo& output,
735 const TransposeConvolution2dDescriptor& descriptor,
736 const TensorInfo& weights,
737 const Optional<TensorInfo>& biases,
738 Optional<std::string&> reasonIfUnsupported) const
739{
740 FORWARD_WORKLOAD_VALIDATE_FUNC(ClTransposeConvolution2dWorkloadValidate,
741 reasonIfUnsupported,
742 input,
743 output,
744 descriptor,
745 weights,
746 biases);
747}
748
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100749} // namespace armnn