blob: cfc0f11d25106c63e276e32a640e101745a8e192 [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)
David Beckac42efd2018-09-26 17:41:13 +010018#include "workloads/ClAdditionWorkload.hpp"
Nattapat Chaimanowonge06757e2018-10-11 15:39:18 +010019#include "workloads/ClActivationWorkload.hpp"
David Beckac42efd2018-09-26 17:41:13 +010020#include "workloads/ClBatchNormalizationFloatWorkload.hpp"
Mike Kelly831faed2018-11-28 11:52:08 +000021#include "workloads/ClBatchToSpaceNdWorkload.hpp"
David Beckac42efd2018-09-26 17:41:13 +010022#include "workloads/ClConvertFp16ToFp32Workload.hpp"
23#include "workloads/ClConvertFp32ToFp16Workload.hpp"
Matthew Benthamd8067922018-10-03 17:18:04 +010024#include "workloads/ClConvolution2dWorkload.hpp"
Matthew Benthamd8777392018-10-08 09:38:55 +010025#include "workloads/ClDepthwiseConvolutionWorkload.hpp"
David Beckac42efd2018-09-26 17:41:13 +010026#include "workloads/ClDivisionFloatWorkload.hpp"
David Beckac42efd2018-09-26 17:41:13 +010027#include "workloads/ClFullyConnectedWorkload.hpp"
Nattapat Chaimanowongc6a41ff2019-01-29 09:56:02 +000028#include "workloads/ClGreaterWorkload.hpp"
arovir01085f0a42018-10-08 14:48:19 +010029#include "workloads/ClL2NormalizationFloatWorkload.hpp"
30#include "workloads/ClLstmFloatWorkload.hpp"
keidav01a959ee52018-12-19 10:04:58 +000031#include "workloads/ClMaximumWorkload.hpp"
Matteo Martincigh28dcab62018-10-19 16:40:03 +010032#include "workloads/ClMeanWorkload.hpp"
Nikhil Raj8599a412018-11-19 14:51:07 +000033#include "workloads/ClMergerWorkload.hpp"
saoste019292aa32019-01-08 13:55:59 +000034#include "workloads/ClMinimumWorkload.hpp"
arovir01085f0a42018-10-08 14:48:19 +010035#include "workloads/ClMultiplicationWorkload.hpp"
David Beckac42efd2018-09-26 17:41:13 +010036#include "workloads/ClNormalizationFloatWorkload.hpp"
arovir01085f0a42018-10-08 14:48:19 +010037#include "workloads/ClPadWorkload.hpp"
38#include "workloads/ClPermuteWorkload.hpp"
Nattapat Chaimanowongac9e0962018-10-10 17:18:35 +010039#include "workloads/ClPooling2dWorkload.hpp"
David Beckac42efd2018-09-26 17:41:13 +010040#include "workloads/ClSoftmaxBaseWorkload.hpp"
Sadik Armaganf4464322018-12-20 16:19:12 +000041#include "workloads/ClSpaceToBatchNdWorkload.hpp"
keidav01d74dc912018-12-10 18:16:07 +000042#include "workloads/ClStridedSliceWorkload.hpp"
David Beckac42efd2018-09-26 17:41:13 +010043#include "workloads/ClSubtractionWorkload.hpp"
telsoa014fcda012018-03-09 14:13:49 +000044#endif
45
46using namespace boost;
47
48namespace armnn
49{
arovir017c22c702018-10-09 11:16:46 +010050
telsoa014fcda012018-03-09 14:13:49 +000051namespace
52{
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +010053
telsoa014fcda012018-03-09 14:13:49 +000054template<unsigned int FilterSize>
55bool IsMatchingSize2d(const TensorInfo& weightInfo)
56{
telsoa01c577f2c2018-08-31 09:22:23 +010057 // Width & Height must match.
telsoa014fcda012018-03-09 14:13:49 +000058 return (weightInfo.GetShape()[3] == FilterSize) && (weightInfo.GetShape()[2] == FilterSize);
59}
60
61template<uint32_t ValidStride>
62bool IsMatchingStride(uint32_t actualStride)
63{
64 return ValidStride == actualStride;
65}
66
67template<uint32_t FirstStride, uint32_t SecondStride, uint32_t... ValidStrides>
68bool IsMatchingStride(uint32_t actualStride)
69{
70 return IsMatchingStride<FirstStride>(actualStride) || IsMatchingStride<SecondStride, ValidStrides...>(actualStride);
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +010071}
telsoa014fcda012018-03-09 14:13:49 +000072
arovir01085f0a42018-10-08 14:48:19 +010073bool IsClBackendSupported(Optional<std::string&> reasonIfUnsupported)
telsoa014fcda012018-03-09 14:13:49 +000074{
Matteo Martincighd95e9062019-01-31 15:35:59 +000075#if defined(ARMCOMPUTECL_ENABLED)
telsoa014fcda012018-03-09 14:13:49 +000076 return true;
77#else
arovir01085f0a42018-10-08 14:48:19 +010078 if (reasonIfUnsupported)
telsoa014fcda012018-03-09 14:13:49 +000079 {
arovir01085f0a42018-10-08 14:48:19 +010080 reasonIfUnsupported.value() = "The armnn library has been built without CL support";
telsoa014fcda012018-03-09 14:13:49 +000081 }
82 return false;
83#endif
84}
85
Matteo Martincighd95e9062019-01-31 15:35:59 +000086#if defined(ARMCOMPUTECL_ENABLED)
telsoa014fcda012018-03-09 14:13:49 +000087#define FORWARD_CL_LAYER_SUPPORT_FUNC(expr) (expr)
88#else
89#define FORWARD_CL_LAYER_SUPPORT_FUNC(expr) IsClBackendSupported(reasonIfUnsupported)
90#endif
91
Matteo Martincighd95e9062019-01-31 15:35:59 +000092#if defined(ARMCOMPUTECL_ENABLED)
telsoa014fcda012018-03-09 14:13:49 +000093template<class FuncType, class... Args>
arovir01085f0a42018-10-08 14:48:19 +010094inline bool IsWorkloadSupported(FuncType&& func, Optional<std::string&> reasonIfUnsupported, Args&&... args)
telsoa014fcda012018-03-09 14:13:49 +000095{
96 arm_compute::Status aclStatus = func(std::forward<Args>(args)...);
97 const bool supported = (aclStatus.error_code() == arm_compute::ErrorCode::OK);
98 if (!supported && reasonIfUnsupported)
99 {
arovir01085f0a42018-10-08 14:48:19 +0100100 reasonIfUnsupported.value() = aclStatus.error_description();
telsoa014fcda012018-03-09 14:13:49 +0000101 }
102 return supported;
103}
104
105#define FORWARD_WORKLOAD_VALIDATE_FUNC(func, reasonIfUnsupported, ...) \
106 return IsWorkloadSupported(func, reasonIfUnsupported, __VA_ARGS__);
107#else
108#define FORWARD_WORKLOAD_VALIDATE_FUNC(func, reasonIfUnsupported, ...) \
109 return IsClBackendSupported(reasonIfUnsupported);
110#endif
111
telsoa01c577f2c2018-08-31 09:22:23 +0100112template<typename FloatFunc, typename Uint8Func, typename ... Params>
arovir01085f0a42018-10-08 14:48:19 +0100113bool IsSupportedForDataTypeCl(Optional<std::string&> reasonIfUnsupported,
telsoa014fcda012018-03-09 14:13:49 +0000114 DataType dataType,
telsoa01c577f2c2018-08-31 09:22:23 +0100115 FloatFunc floatFuncPtr,
telsoa014fcda012018-03-09 14:13:49 +0000116 Uint8Func uint8FuncPtr,
117 Params&&... params)
118{
119 return IsClBackendSupported(reasonIfUnsupported) &&
120 IsSupportedForDataTypeGeneric(reasonIfUnsupported,
121 dataType,
122 floatFuncPtr,
telsoa01c577f2c2018-08-31 09:22:23 +0100123 floatFuncPtr,
telsoa014fcda012018-03-09 14:13:49 +0000124 uint8FuncPtr,
narpra01db2b1602019-01-23 15:23:11 +0000125 &FalseFunc<>,
kevmay012b4d88e2019-01-24 14:05:09 +0000126 &FalseFunc<>,
telsoa014fcda012018-03-09 14:13:49 +0000127 std::forward<Params>(params)...);
128}
129
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100130} // anonymous namespace
131
132bool ClLayerSupport::IsActivationSupported(const TensorInfo& input,
133 const TensorInfo& output,
134 const ActivationDescriptor& descriptor,
135 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000136{
telsoa01c577f2c2018-08-31 09:22:23 +0100137 FORWARD_WORKLOAD_VALIDATE_FUNC(ClActivationWorkloadValidate,
138 reasonIfUnsupported,
139 input,
140 output,
141 descriptor);
telsoa014fcda012018-03-09 14:13:49 +0000142}
143
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100144bool ClLayerSupport::IsAdditionSupported(const TensorInfo& input0,
145 const TensorInfo& input1,
146 const TensorInfo& output,
147 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000148{
arovir01085f0a42018-10-08 14:48:19 +0100149 FORWARD_WORKLOAD_VALIDATE_FUNC(ClAdditionValidate,
150 reasonIfUnsupported,
151 input0,
152 input1,
153 output);
telsoa014fcda012018-03-09 14:13:49 +0000154}
155
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100156bool ClLayerSupport::IsBatchNormalizationSupported(const TensorInfo& input,
157 const TensorInfo& output,
158 const TensorInfo& mean,
159 const TensorInfo& var,
160 const TensorInfo& beta,
161 const TensorInfo& gamma,
162 const BatchNormalizationDescriptor& descriptor,
163 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000164{
telsoa01c577f2c2018-08-31 09:22:23 +0100165 FORWARD_WORKLOAD_VALIDATE_FUNC(ClBatchNormalizationValidate,
166 reasonIfUnsupported,
167 input,
168 output,
169 mean,
170 var,
171 beta,
172 gamma,
173 descriptor);
telsoa014fcda012018-03-09 14:13:49 +0000174}
175
Mike Kelly831faed2018-11-28 11:52:08 +0000176bool ClLayerSupport::IsBatchToSpaceNdSupported(const TensorInfo& input,
177 const TensorInfo& output,
178 const BatchToSpaceNdDescriptor& descriptor,
179 Optional<std::string&> reasonIfUnsupported) const
180{
181 FORWARD_WORKLOAD_VALIDATE_FUNC(ClBatchToSpaceNdWorkloadValidate,
182 reasonIfUnsupported,
183 input,
184 output,
185 descriptor);
186}
187
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100188bool ClLayerSupport::IsConstantSupported(const TensorInfo& output,
189 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000190{
191 return IsSupportedForDataTypeCl(reasonIfUnsupported,
192 output.GetDataType(),
193 &TrueFunc<>,
194 &FalseFuncU8<>);
195}
196
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100197bool ClLayerSupport::IsConvertFp16ToFp32Supported(const TensorInfo& input,
198 const TensorInfo& output,
199 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000200{
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100201 FORWARD_WORKLOAD_VALIDATE_FUNC(ClConvertFp16ToFp32WorkloadValidate,
202 reasonIfUnsupported,
203 input,
204 output);
telsoa014fcda012018-03-09 14:13:49 +0000205}
206
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100207bool ClLayerSupport::IsConvertFp32ToFp16Supported(const TensorInfo& input,
208 const TensorInfo& output,
209 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000210{
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100211 FORWARD_WORKLOAD_VALIDATE_FUNC(ClConvertFp32ToFp16WorkloadValidate,
212 reasonIfUnsupported,
213 input,
214 output);
telsoa014fcda012018-03-09 14:13:49 +0000215}
216
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100217bool ClLayerSupport::IsConvolution2dSupported(const TensorInfo& input,
218 const TensorInfo& output,
219 const Convolution2dDescriptor& descriptor,
220 const TensorInfo& weights,
221 const Optional<TensorInfo>& biases,
222 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000223{
surmeh013537c2c2018-05-18 16:31:43 +0100224 FORWARD_WORKLOAD_VALIDATE_FUNC(ClConvolution2dWorkloadValidate,
225 reasonIfUnsupported,
226 input,
227 output,
228 descriptor,
229 weights,
230 biases);
telsoa014fcda012018-03-09 14:13:49 +0000231}
232
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100233bool ClLayerSupport::IsDepthwiseConvolutionSupported(const TensorInfo& input,
234 const TensorInfo& output,
235 const DepthwiseConvolution2dDescriptor& descriptor,
236 const TensorInfo& weights,
237 const Optional<TensorInfo>& biases,
238 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000239{
telsoa01c577f2c2018-08-31 09:22:23 +0100240 FORWARD_WORKLOAD_VALIDATE_FUNC(ClDepthwiseConvolutionWorkloadValidate,
241 reasonIfUnsupported,
242 input,
243 output,
244 descriptor,
245 weights,
246 biases);
telsoa014fcda012018-03-09 14:13:49 +0000247}
248
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100249bool ClLayerSupport::IsDivisionSupported(const TensorInfo& input0,
250 const TensorInfo& input1,
251 const TensorInfo& output,
252 Optional<std::string&> reasonIfUnsupported) const
Francis Murtaghe7a86a42018-08-29 12:42:10 +0100253{
254 FORWARD_WORKLOAD_VALIDATE_FUNC(ClDivisionWorkloadValidate,
255 reasonIfUnsupported,
256 input0,
257 input1,
258 output);
259}
260
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100261bool ClLayerSupport::IsFloorSupported(const TensorInfo& input,
262 const TensorInfo& output,
263 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000264{
265 ignore_unused(output);
telsoa01c577f2c2018-08-31 09:22:23 +0100266 return IsClBackendSupported(reasonIfUnsupported) &&
267 IsSupportedForDataTypeGeneric(reasonIfUnsupported,
268 input.GetDataType(),
269 &FalseFuncF16<>,
270 &TrueFunc<>,
narpra01db2b1602019-01-23 15:23:11 +0000271 &FalseFuncU8<>,
kevmay012b4d88e2019-01-24 14:05:09 +0000272 &FalseFuncI32<>,
273 &FalseFuncU8<>);
telsoa01c577f2c2018-08-31 09:22:23 +0100274}
275
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100276bool ClLayerSupport::IsFullyConnectedSupported(const TensorInfo& input,
277 const TensorInfo& output,
278 const TensorInfo& weights,
279 const TensorInfo& biases,
280 const FullyConnectedDescriptor& descriptor,
281 Optional<std::string&> reasonIfUnsupported) const
282{
283 FORWARD_WORKLOAD_VALIDATE_FUNC(ClFullyConnectedWorkloadValidate,
284 reasonIfUnsupported,
285 input,
286 output,
287 weights,
288 biases,
289 descriptor);
290}
291
Nattapat Chaimanowongc6a41ff2019-01-29 09:56:02 +0000292bool ClLayerSupport::IsGreaterSupported(const TensorInfo& input0,
293 const TensorInfo& input1,
294 const TensorInfo& output,
295 Optional<std::string&> reasonIfUnsupported) const
296{
297 FORWARD_WORKLOAD_VALIDATE_FUNC(ClGreaterWorkloadValidate,
298 reasonIfUnsupported,
299 input0,
300 input1,
301 output);
302}
303
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100304bool ClLayerSupport::IsInputSupported(const TensorInfo& input,
305 Optional<std::string&> reasonIfUnsupported) const
306{
307 return IsSupportedForDataTypeCl(reasonIfUnsupported,
308 input.GetDataType(),
309 &TrueFunc<>,
310 &TrueFunc<>);
311}
312
313bool ClLayerSupport::IsL2NormalizationSupported(const TensorInfo& input,
314 const TensorInfo& output,
315 const L2NormalizationDescriptor& descriptor,
316 Optional<std::string&> reasonIfUnsupported) const
317{
318 FORWARD_WORKLOAD_VALIDATE_FUNC(ClL2NormalizationWorkloadValidate,
319 reasonIfUnsupported,
320 input,
321 output,
322 descriptor);
323}
324
325bool ClLayerSupport::IsLstmSupported(const TensorInfo& input,
326 const TensorInfo& outputStateIn,
327 const TensorInfo& cellStateIn,
328 const TensorInfo& scratchBuffer,
329 const TensorInfo& outputStateOut,
330 const TensorInfo& cellStateOut,
331 const TensorInfo& output,
332 const LstmDescriptor& descriptor,
333 const TensorInfo& inputToForgetWeights,
334 const TensorInfo& inputToCellWeights,
335 const TensorInfo& inputToOutputWeights,
336 const TensorInfo& recurrentToForgetWeights,
337 const TensorInfo& recurrentToCellWeights,
338 const TensorInfo& recurrentToOutputWeights,
339 const TensorInfo& forgetGateBias,
340 const TensorInfo& cellBias,
341 const TensorInfo& outputGateBias,
342 const TensorInfo* inputToInputWeights,
343 const TensorInfo* recurrentToInputWeights,
344 const TensorInfo* cellToInputWeights,
345 const TensorInfo* inputGateBias,
346 const TensorInfo* projectionWeights,
347 const TensorInfo* projectionBias,
348 const TensorInfo* cellToForgetWeights,
349 const TensorInfo* cellToOutputWeights,
350 Optional<std::string&> reasonIfUnsupported) const
telsoa01c577f2c2018-08-31 09:22:23 +0100351{
arovir01085f0a42018-10-08 14:48:19 +0100352 FORWARD_WORKLOAD_VALIDATE_FUNC(ClLstmFloatWorkloadValidate,
353 reasonIfUnsupported,
354 input,
355 outputStateIn,
356 cellStateIn,
357 scratchBuffer,
358 outputStateOut,
359 cellStateOut,
360 output,
361 descriptor,
362 inputToForgetWeights,
363 inputToCellWeights,
364 inputToOutputWeights,
365 recurrentToForgetWeights,
366 recurrentToCellWeights,
367 recurrentToOutputWeights,
368 forgetGateBias,
369 cellBias,
370 outputGateBias,
371 inputToInputWeights,
372 recurrentToInputWeights,
373 cellToInputWeights,
374 inputGateBias,
375 projectionWeights,
376 projectionBias,
377 cellToForgetWeights,
378 cellToOutputWeights);
telsoa01c577f2c2018-08-31 09:22:23 +0100379}
380
keidav01a959ee52018-12-19 10:04:58 +0000381bool ClLayerSupport::IsMaximumSupported(const TensorInfo& input0,
382 const TensorInfo& input1,
383 const TensorInfo& output,
384 Optional<std::string&> reasonIfUnsupported) const
385{
386 FORWARD_WORKLOAD_VALIDATE_FUNC(ClMaximumWorkloadValidate,
387 reasonIfUnsupported,
388 input0,
389 input1,
390 output);
391}
392
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100393bool ClLayerSupport::IsMeanSupported(const TensorInfo& input,
394 const TensorInfo& output,
395 const MeanDescriptor& descriptor,
396 Optional<std::string&> reasonIfUnsupported) const
narpra0132b90462018-09-13 11:07:48 +0100397{
Matteo Martincigh28dcab62018-10-19 16:40:03 +0100398 FORWARD_WORKLOAD_VALIDATE_FUNC(ClMeanValidate,
399 reasonIfUnsupported,
400 input,
401 output,
402 descriptor);
narpra0132b90462018-09-13 11:07:48 +0100403}
404
Matteo Martincigh992d6dc2019-01-10 17:34:20 +0000405bool ClLayerSupport::IsMemCopySupported(const TensorInfo &input,
406 const TensorInfo &output,
407 Optional<std::string &> reasonIfUnsupported) const
408{
409 ignore_unused(input);
410 ignore_unused(output);
411 return true;
412}
413
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100414bool ClLayerSupport::IsMergerSupported(const std::vector<const TensorInfo*> inputs,
Nikhil Raj8599a412018-11-19 14:51:07 +0000415 const TensorInfo& output,
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100416 const OriginsDescriptor& descriptor,
417 Optional<std::string&> reasonIfUnsupported) const
418{
Nikhil Raj8599a412018-11-19 14:51:07 +0000419 if(descriptor.GetNumDimensions() - descriptor.GetConcatAxis() == 1)
420 {
421 FORWARD_WORKLOAD_VALIDATE_FUNC(ClMergerWorkloadValidate,
422 reasonIfUnsupported,
423 inputs,
424 output,
425 descriptor);
426 }
427 else
428 {
429 return IsSupportedForDataTypeCl(reasonIfUnsupported,
430 inputs[0]->GetDataType(),
431 &TrueFunc<>,
narpra0163b08822018-11-20 11:29:12 +0000432 &TrueFunc<>);
Nikhil Raj8599a412018-11-19 14:51:07 +0000433 }
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100434}
435
saoste019292aa32019-01-08 13:55:59 +0000436bool ClLayerSupport::IsMinimumSupported(const TensorInfo& input0,
437 const TensorInfo& input1,
438 const TensorInfo& output,
439 Optional<std::string&> reasonIfUnsupported) const
440{
441 FORWARD_WORKLOAD_VALIDATE_FUNC(ClMinimumWorkloadValidate,
442 reasonIfUnsupported,
443 input0,
444 input1,
445 output);
446}
447
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100448bool ClLayerSupport::IsMultiplicationSupported(const TensorInfo& input0,
449 const TensorInfo& input1,
450 const TensorInfo& output,
451 Optional<std::string&> reasonIfUnsupported) const
452{
453 FORWARD_WORKLOAD_VALIDATE_FUNC(ClMultiplicationWorkloadValidate,
454 reasonIfUnsupported,
455 input0,
456 input1,
457 output);
458}
459
460bool ClLayerSupport::IsNormalizationSupported(const TensorInfo& input,
461 const TensorInfo& output,
462 const NormalizationDescriptor& descriptor,
463 Optional<std::string&> reasonIfUnsupported) const
464{
465 FORWARD_WORKLOAD_VALIDATE_FUNC(ClNormalizationWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
466}
467
468bool ClLayerSupport::IsOutputSupported(const TensorInfo& output,
469 Optional<std::string&> reasonIfUnsupported) const
470{
kevmay012b4d88e2019-01-24 14:05:09 +0000471 return IsClBackendSupported(reasonIfUnsupported) &&
472 IsSupportedForDataTypeGeneric(reasonIfUnsupported,
473 output.GetDataType(),
474 &TrueFunc<>,
475 &TrueFunc<>,
476 &TrueFunc<>,
477 &FalseFuncI32<>,
478 &TrueFunc<>);
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100479}
480
481bool ClLayerSupport::IsPadSupported(const TensorInfo& input,
482 const TensorInfo& output,
483 const PadDescriptor& descriptor,
484 Optional<std::string&> reasonIfUnsupported) const
arovir01085f0a42018-10-08 14:48:19 +0100485{
486 FORWARD_WORKLOAD_VALIDATE_FUNC(ClPadValidate,
487 reasonIfUnsupported,
488 input,
489 output,
490 descriptor);
491}
492
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100493bool ClLayerSupport::IsPermuteSupported(const TensorInfo& input,
494 const TensorInfo& output,
495 const PermuteDescriptor& descriptor,
496 Optional<std::string&> reasonIfUnsupported) const
497{
498 ignore_unused(input);
499 ignore_unused(output);
500 FORWARD_WORKLOAD_VALIDATE_FUNC(ClPermuteWorkloadValidate, reasonIfUnsupported, descriptor);
telsoa014fcda012018-03-09 14:13:49 +0000501}
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100502
503bool ClLayerSupport::IsPooling2dSupported(const TensorInfo& input,
504 const TensorInfo& output,
505 const Pooling2dDescriptor& descriptor,
506 Optional<std::string&> reasonIfUnsupported) const
507{
508 FORWARD_WORKLOAD_VALIDATE_FUNC(ClPooling2dWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
509}
510
511bool ClLayerSupport::IsReshapeSupported(const TensorInfo& input,
Matteo Martincigh992d6dc2019-01-10 17:34:20 +0000512 const ReshapeDescriptor& descriptor,
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100513 Optional<std::string&> reasonIfUnsupported) const
514{
515 ignore_unused(input);
Matteo Martincigh992d6dc2019-01-10 17:34:20 +0000516 ignore_unused(descriptor);
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100517 ignore_unused(reasonIfUnsupported);
518 return true;
519}
520
521bool ClLayerSupport::IsResizeBilinearSupported(const TensorInfo& input,
Sadik Armaganc625f002018-12-17 11:32:16 +0000522 const TensorInfo& output,
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100523 Optional<std::string&> reasonIfUnsupported) const
524{
Sadik Armaganc625f002018-12-17 11:32:16 +0000525 ignore_unused(output);
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100526 return IsSupportedForDataTypeCl(reasonIfUnsupported,
527 input.GetDataType(),
528 &TrueFunc<>,
529 &FalseFuncU8<>);
530}
531
532bool ClLayerSupport::IsSoftmaxSupported(const TensorInfo& input,
533 const TensorInfo& output,
534 const SoftmaxDescriptor& descriptor,
535 Optional<std::string&> reasonIfUnsupported) const
536{
537 ignore_unused(descriptor);
538 FORWARD_WORKLOAD_VALIDATE_FUNC(ClSoftmaxWorkloadValidate, reasonIfUnsupported, input, output);
539}
540
Sadik Armaganf4464322018-12-20 16:19:12 +0000541bool ClLayerSupport::IsSpaceToBatchNdSupported(const TensorInfo& input,
542 const TensorInfo& output,
543 const SpaceToBatchNdDescriptor& descriptor,
544 Optional<std::string&> reasonIfUnsupported) const
545{
546 FORWARD_WORKLOAD_VALIDATE_FUNC(ClSpaceToBatchNdWorkloadValidate,
547 reasonIfUnsupported,
548 input,
549 output,
550 descriptor);
551}
552
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100553bool ClLayerSupport::IsSplitterSupported(const TensorInfo& input,
554 const ViewsDescriptor& descriptor,
555 Optional<std::string&> reasonIfUnsupported) const
556{
557 ignore_unused(descriptor);
558 return IsSupportedForDataTypeCl(reasonIfUnsupported,
559 input.GetDataType(),
560 &TrueFunc<>,
561 &TrueFunc<>);
562}
563
keidav01d74dc912018-12-10 18:16:07 +0000564bool ClLayerSupport::IsStridedSliceSupported(const TensorInfo& input,
565 const TensorInfo& output,
566 const StridedSliceDescriptor& descriptor,
567 Optional<std::string&> reasonIfUnsupported) const
568{
569 FORWARD_WORKLOAD_VALIDATE_FUNC(ClStridedSliceWorkloadValidate,
570 reasonIfUnsupported,
571 input,
572 output,
573 descriptor);
574}
575
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100576bool ClLayerSupport::IsSubtractionSupported(const TensorInfo& input0,
577 const TensorInfo& input1,
578 const TensorInfo& output,
579 Optional<std::string&> reasonIfUnsupported) const
580{
581 FORWARD_WORKLOAD_VALIDATE_FUNC(ClSubtractionValidate,
582 reasonIfUnsupported,
583 input0,
584 input1,
585 output);
586}
587
588} // namespace armnn