blob: a877a5f25f71c2475dfc4050e6d13991bf4fd09f [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
17#ifdef 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"
arovir01085f0a42018-10-08 14:48:19 +010028#include "workloads/ClL2NormalizationFloatWorkload.hpp"
29#include "workloads/ClLstmFloatWorkload.hpp"
Matteo Martincigh28dcab62018-10-19 16:40:03 +010030#include "workloads/ClMeanWorkload.hpp"
Nikhil Raj8599a412018-11-19 14:51:07 +000031#include "workloads/ClMergerWorkload.hpp"
arovir01085f0a42018-10-08 14:48:19 +010032#include "workloads/ClMultiplicationWorkload.hpp"
David Beckac42efd2018-09-26 17:41:13 +010033#include "workloads/ClNormalizationFloatWorkload.hpp"
arovir01085f0a42018-10-08 14:48:19 +010034#include "workloads/ClPadWorkload.hpp"
35#include "workloads/ClPermuteWorkload.hpp"
Nattapat Chaimanowongac9e0962018-10-10 17:18:35 +010036#include "workloads/ClPooling2dWorkload.hpp"
David Beckac42efd2018-09-26 17:41:13 +010037#include "workloads/ClSoftmaxBaseWorkload.hpp"
38#include "workloads/ClSubtractionWorkload.hpp"
telsoa014fcda012018-03-09 14:13:49 +000039#endif
40
41using namespace boost;
42
43namespace armnn
44{
arovir017c22c702018-10-09 11:16:46 +010045
telsoa014fcda012018-03-09 14:13:49 +000046namespace
47{
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +010048
telsoa014fcda012018-03-09 14:13:49 +000049template<unsigned int FilterSize>
50bool IsMatchingSize2d(const TensorInfo& weightInfo)
51{
telsoa01c577f2c2018-08-31 09:22:23 +010052 // Width & Height must match.
telsoa014fcda012018-03-09 14:13:49 +000053 return (weightInfo.GetShape()[3] == FilterSize) && (weightInfo.GetShape()[2] == FilterSize);
54}
55
56template<uint32_t ValidStride>
57bool IsMatchingStride(uint32_t actualStride)
58{
59 return ValidStride == actualStride;
60}
61
62template<uint32_t FirstStride, uint32_t SecondStride, uint32_t... ValidStrides>
63bool IsMatchingStride(uint32_t actualStride)
64{
65 return IsMatchingStride<FirstStride>(actualStride) || IsMatchingStride<SecondStride, ValidStrides...>(actualStride);
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +010066}
telsoa014fcda012018-03-09 14:13:49 +000067
arovir01085f0a42018-10-08 14:48:19 +010068bool IsClBackendSupported(Optional<std::string&> reasonIfUnsupported)
telsoa014fcda012018-03-09 14:13:49 +000069{
70#if ARMCOMPUTECL_ENABLED
71 return true;
72#else
arovir01085f0a42018-10-08 14:48:19 +010073 if (reasonIfUnsupported)
telsoa014fcda012018-03-09 14:13:49 +000074 {
arovir01085f0a42018-10-08 14:48:19 +010075 reasonIfUnsupported.value() = "The armnn library has been built without CL support";
telsoa014fcda012018-03-09 14:13:49 +000076 }
77 return false;
78#endif
79}
80
81#if ARMCOMPUTECL_ENABLED
82#define FORWARD_CL_LAYER_SUPPORT_FUNC(expr) (expr)
83#else
84#define FORWARD_CL_LAYER_SUPPORT_FUNC(expr) IsClBackendSupported(reasonIfUnsupported)
85#endif
86
87#if ARMCOMPUTECL_ENABLED
88template<class FuncType, class... Args>
arovir01085f0a42018-10-08 14:48:19 +010089inline bool IsWorkloadSupported(FuncType&& func, Optional<std::string&> reasonIfUnsupported, Args&&... args)
telsoa014fcda012018-03-09 14:13:49 +000090{
91 arm_compute::Status aclStatus = func(std::forward<Args>(args)...);
92 const bool supported = (aclStatus.error_code() == arm_compute::ErrorCode::OK);
93 if (!supported && reasonIfUnsupported)
94 {
arovir01085f0a42018-10-08 14:48:19 +010095 reasonIfUnsupported.value() = aclStatus.error_description();
telsoa014fcda012018-03-09 14:13:49 +000096 }
97 return supported;
98}
99
100#define FORWARD_WORKLOAD_VALIDATE_FUNC(func, reasonIfUnsupported, ...) \
101 return IsWorkloadSupported(func, reasonIfUnsupported, __VA_ARGS__);
102#else
103#define FORWARD_WORKLOAD_VALIDATE_FUNC(func, reasonIfUnsupported, ...) \
104 return IsClBackendSupported(reasonIfUnsupported);
105#endif
106
telsoa01c577f2c2018-08-31 09:22:23 +0100107template<typename FloatFunc, typename Uint8Func, typename ... Params>
arovir01085f0a42018-10-08 14:48:19 +0100108bool IsSupportedForDataTypeCl(Optional<std::string&> reasonIfUnsupported,
telsoa014fcda012018-03-09 14:13:49 +0000109 DataType dataType,
telsoa01c577f2c2018-08-31 09:22:23 +0100110 FloatFunc floatFuncPtr,
telsoa014fcda012018-03-09 14:13:49 +0000111 Uint8Func uint8FuncPtr,
112 Params&&... params)
113{
114 return IsClBackendSupported(reasonIfUnsupported) &&
115 IsSupportedForDataTypeGeneric(reasonIfUnsupported,
116 dataType,
117 floatFuncPtr,
telsoa01c577f2c2018-08-31 09:22:23 +0100118 floatFuncPtr,
telsoa014fcda012018-03-09 14:13:49 +0000119 uint8FuncPtr,
120 std::forward<Params>(params)...);
121}
122
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100123} // anonymous namespace
124
125bool ClLayerSupport::IsActivationSupported(const TensorInfo& input,
126 const TensorInfo& output,
127 const ActivationDescriptor& descriptor,
128 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000129{
telsoa01c577f2c2018-08-31 09:22:23 +0100130 FORWARD_WORKLOAD_VALIDATE_FUNC(ClActivationWorkloadValidate,
131 reasonIfUnsupported,
132 input,
133 output,
134 descriptor);
telsoa014fcda012018-03-09 14:13:49 +0000135}
136
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100137bool ClLayerSupport::IsAdditionSupported(const TensorInfo& input0,
138 const TensorInfo& input1,
139 const TensorInfo& output,
140 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000141{
arovir01085f0a42018-10-08 14:48:19 +0100142 FORWARD_WORKLOAD_VALIDATE_FUNC(ClAdditionValidate,
143 reasonIfUnsupported,
144 input0,
145 input1,
146 output);
telsoa014fcda012018-03-09 14:13:49 +0000147}
148
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100149bool ClLayerSupport::IsBatchNormalizationSupported(const TensorInfo& input,
150 const TensorInfo& output,
151 const TensorInfo& mean,
152 const TensorInfo& var,
153 const TensorInfo& beta,
154 const TensorInfo& gamma,
155 const BatchNormalizationDescriptor& descriptor,
156 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000157{
telsoa01c577f2c2018-08-31 09:22:23 +0100158 FORWARD_WORKLOAD_VALIDATE_FUNC(ClBatchNormalizationValidate,
159 reasonIfUnsupported,
160 input,
161 output,
162 mean,
163 var,
164 beta,
165 gamma,
166 descriptor);
telsoa014fcda012018-03-09 14:13:49 +0000167}
168
Mike Kelly831faed2018-11-28 11:52:08 +0000169bool ClLayerSupport::IsBatchToSpaceNdSupported(const TensorInfo& input,
170 const TensorInfo& output,
171 const BatchToSpaceNdDescriptor& descriptor,
172 Optional<std::string&> reasonIfUnsupported) const
173{
174 FORWARD_WORKLOAD_VALIDATE_FUNC(ClBatchToSpaceNdWorkloadValidate,
175 reasonIfUnsupported,
176 input,
177 output,
178 descriptor);
179}
180
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100181bool ClLayerSupport::IsConstantSupported(const TensorInfo& output,
182 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000183{
184 return IsSupportedForDataTypeCl(reasonIfUnsupported,
185 output.GetDataType(),
186 &TrueFunc<>,
187 &FalseFuncU8<>);
188}
189
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100190bool ClLayerSupport::IsConvertFp16ToFp32Supported(const TensorInfo& input,
191 const TensorInfo& output,
192 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000193{
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100194 FORWARD_WORKLOAD_VALIDATE_FUNC(ClConvertFp16ToFp32WorkloadValidate,
195 reasonIfUnsupported,
196 input,
197 output);
telsoa014fcda012018-03-09 14:13:49 +0000198}
199
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100200bool ClLayerSupport::IsConvertFp32ToFp16Supported(const TensorInfo& input,
201 const TensorInfo& output,
202 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000203{
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100204 FORWARD_WORKLOAD_VALIDATE_FUNC(ClConvertFp32ToFp16WorkloadValidate,
205 reasonIfUnsupported,
206 input,
207 output);
telsoa014fcda012018-03-09 14:13:49 +0000208}
209
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100210bool ClLayerSupport::IsConvolution2dSupported(const TensorInfo& input,
211 const TensorInfo& output,
212 const Convolution2dDescriptor& descriptor,
213 const TensorInfo& weights,
214 const Optional<TensorInfo>& biases,
215 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000216{
surmeh013537c2c2018-05-18 16:31:43 +0100217 FORWARD_WORKLOAD_VALIDATE_FUNC(ClConvolution2dWorkloadValidate,
218 reasonIfUnsupported,
219 input,
220 output,
221 descriptor,
222 weights,
223 biases);
telsoa014fcda012018-03-09 14:13:49 +0000224}
225
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100226bool ClLayerSupport::IsDepthwiseConvolutionSupported(const TensorInfo& input,
227 const TensorInfo& output,
228 const DepthwiseConvolution2dDescriptor& descriptor,
229 const TensorInfo& weights,
230 const Optional<TensorInfo>& biases,
231 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000232{
telsoa01c577f2c2018-08-31 09:22:23 +0100233 FORWARD_WORKLOAD_VALIDATE_FUNC(ClDepthwiseConvolutionWorkloadValidate,
234 reasonIfUnsupported,
235 input,
236 output,
237 descriptor,
238 weights,
239 biases);
telsoa014fcda012018-03-09 14:13:49 +0000240}
241
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100242bool ClLayerSupport::IsDivisionSupported(const TensorInfo& input0,
243 const TensorInfo& input1,
244 const TensorInfo& output,
245 Optional<std::string&> reasonIfUnsupported) const
Francis Murtaghe7a86a42018-08-29 12:42:10 +0100246{
247 FORWARD_WORKLOAD_VALIDATE_FUNC(ClDivisionWorkloadValidate,
248 reasonIfUnsupported,
249 input0,
250 input1,
251 output);
252}
253
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100254bool ClLayerSupport::IsFakeQuantizationSupported(const TensorInfo& input,
255 const FakeQuantizationDescriptor& descriptor,
256 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000257{
258 ignore_unused(input);
259 ignore_unused(descriptor);
arovir01085f0a42018-10-08 14:48:19 +0100260 ignore_unused(reasonIfUnsupported);
telsoa014fcda012018-03-09 14:13:49 +0000261 return false;
262}
263
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100264bool ClLayerSupport::IsFloorSupported(const TensorInfo& input,
265 const TensorInfo& output,
266 Optional<std::string&> reasonIfUnsupported) const
telsoa014fcda012018-03-09 14:13:49 +0000267{
268 ignore_unused(output);
telsoa01c577f2c2018-08-31 09:22:23 +0100269 return IsClBackendSupported(reasonIfUnsupported) &&
270 IsSupportedForDataTypeGeneric(reasonIfUnsupported,
271 input.GetDataType(),
272 &FalseFuncF16<>,
273 &TrueFunc<>,
274 &FalseFuncU8<>);
275}
276
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100277bool ClLayerSupport::IsFullyConnectedSupported(const TensorInfo& input,
278 const TensorInfo& output,
279 const TensorInfo& weights,
280 const TensorInfo& biases,
281 const FullyConnectedDescriptor& descriptor,
282 Optional<std::string&> reasonIfUnsupported) const
283{
284 FORWARD_WORKLOAD_VALIDATE_FUNC(ClFullyConnectedWorkloadValidate,
285 reasonIfUnsupported,
286 input,
287 output,
288 weights,
289 biases,
290 descriptor);
291}
292
293bool ClLayerSupport::IsInputSupported(const TensorInfo& input,
294 Optional<std::string&> reasonIfUnsupported) const
295{
296 return IsSupportedForDataTypeCl(reasonIfUnsupported,
297 input.GetDataType(),
298 &TrueFunc<>,
299 &TrueFunc<>);
300}
301
302bool ClLayerSupport::IsL2NormalizationSupported(const TensorInfo& input,
303 const TensorInfo& output,
304 const L2NormalizationDescriptor& descriptor,
305 Optional<std::string&> reasonIfUnsupported) const
306{
307 FORWARD_WORKLOAD_VALIDATE_FUNC(ClL2NormalizationWorkloadValidate,
308 reasonIfUnsupported,
309 input,
310 output,
311 descriptor);
312}
313
314bool ClLayerSupport::IsLstmSupported(const TensorInfo& input,
315 const TensorInfo& outputStateIn,
316 const TensorInfo& cellStateIn,
317 const TensorInfo& scratchBuffer,
318 const TensorInfo& outputStateOut,
319 const TensorInfo& cellStateOut,
320 const TensorInfo& output,
321 const LstmDescriptor& descriptor,
322 const TensorInfo& inputToForgetWeights,
323 const TensorInfo& inputToCellWeights,
324 const TensorInfo& inputToOutputWeights,
325 const TensorInfo& recurrentToForgetWeights,
326 const TensorInfo& recurrentToCellWeights,
327 const TensorInfo& recurrentToOutputWeights,
328 const TensorInfo& forgetGateBias,
329 const TensorInfo& cellBias,
330 const TensorInfo& outputGateBias,
331 const TensorInfo* inputToInputWeights,
332 const TensorInfo* recurrentToInputWeights,
333 const TensorInfo* cellToInputWeights,
334 const TensorInfo* inputGateBias,
335 const TensorInfo* projectionWeights,
336 const TensorInfo* projectionBias,
337 const TensorInfo* cellToForgetWeights,
338 const TensorInfo* cellToOutputWeights,
339 Optional<std::string&> reasonIfUnsupported) const
telsoa01c577f2c2018-08-31 09:22:23 +0100340{
arovir01085f0a42018-10-08 14:48:19 +0100341 FORWARD_WORKLOAD_VALIDATE_FUNC(ClLstmFloatWorkloadValidate,
342 reasonIfUnsupported,
343 input,
344 outputStateIn,
345 cellStateIn,
346 scratchBuffer,
347 outputStateOut,
348 cellStateOut,
349 output,
350 descriptor,
351 inputToForgetWeights,
352 inputToCellWeights,
353 inputToOutputWeights,
354 recurrentToForgetWeights,
355 recurrentToCellWeights,
356 recurrentToOutputWeights,
357 forgetGateBias,
358 cellBias,
359 outputGateBias,
360 inputToInputWeights,
361 recurrentToInputWeights,
362 cellToInputWeights,
363 inputGateBias,
364 projectionWeights,
365 projectionBias,
366 cellToForgetWeights,
367 cellToOutputWeights);
telsoa01c577f2c2018-08-31 09:22:23 +0100368}
369
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100370bool ClLayerSupport::IsMeanSupported(const TensorInfo& input,
371 const TensorInfo& output,
372 const MeanDescriptor& descriptor,
373 Optional<std::string&> reasonIfUnsupported) const
narpra0132b90462018-09-13 11:07:48 +0100374{
Matteo Martincigh28dcab62018-10-19 16:40:03 +0100375 FORWARD_WORKLOAD_VALIDATE_FUNC(ClMeanValidate,
376 reasonIfUnsupported,
377 input,
378 output,
379 descriptor);
narpra0132b90462018-09-13 11:07:48 +0100380}
381
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100382bool ClLayerSupport::IsMergerSupported(const std::vector<const TensorInfo*> inputs,
Nikhil Raj8599a412018-11-19 14:51:07 +0000383 const TensorInfo& output,
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100384 const OriginsDescriptor& descriptor,
385 Optional<std::string&> reasonIfUnsupported) const
386{
Nikhil Raj8599a412018-11-19 14:51:07 +0000387 if(descriptor.GetNumDimensions() - descriptor.GetConcatAxis() == 1)
388 {
389 FORWARD_WORKLOAD_VALIDATE_FUNC(ClMergerWorkloadValidate,
390 reasonIfUnsupported,
391 inputs,
392 output,
393 descriptor);
394 }
395 else
396 {
397 return IsSupportedForDataTypeCl(reasonIfUnsupported,
398 inputs[0]->GetDataType(),
399 &TrueFunc<>,
narpra0163b08822018-11-20 11:29:12 +0000400 &TrueFunc<>);
Nikhil Raj8599a412018-11-19 14:51:07 +0000401 }
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100402}
403
404bool ClLayerSupport::IsMultiplicationSupported(const TensorInfo& input0,
405 const TensorInfo& input1,
406 const TensorInfo& output,
407 Optional<std::string&> reasonIfUnsupported) const
408{
409 FORWARD_WORKLOAD_VALIDATE_FUNC(ClMultiplicationWorkloadValidate,
410 reasonIfUnsupported,
411 input0,
412 input1,
413 output);
414}
415
416bool ClLayerSupport::IsNormalizationSupported(const TensorInfo& input,
417 const TensorInfo& output,
418 const NormalizationDescriptor& descriptor,
419 Optional<std::string&> reasonIfUnsupported) const
420{
421 FORWARD_WORKLOAD_VALIDATE_FUNC(ClNormalizationWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
422}
423
424bool ClLayerSupport::IsOutputSupported(const TensorInfo& output,
425 Optional<std::string&> reasonIfUnsupported) const
426{
427 return IsSupportedForDataTypeCl(reasonIfUnsupported,
428 output.GetDataType(),
429 &TrueFunc<>,
430 &TrueFunc<>);
431}
432
433bool ClLayerSupport::IsPadSupported(const TensorInfo& input,
434 const TensorInfo& output,
435 const PadDescriptor& descriptor,
436 Optional<std::string&> reasonIfUnsupported) const
arovir01085f0a42018-10-08 14:48:19 +0100437{
438 FORWARD_WORKLOAD_VALIDATE_FUNC(ClPadValidate,
439 reasonIfUnsupported,
440 input,
441 output,
442 descriptor);
443}
444
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100445bool ClLayerSupport::IsPermuteSupported(const TensorInfo& input,
446 const TensorInfo& output,
447 const PermuteDescriptor& descriptor,
448 Optional<std::string&> reasonIfUnsupported) const
449{
450 ignore_unused(input);
451 ignore_unused(output);
452 FORWARD_WORKLOAD_VALIDATE_FUNC(ClPermuteWorkloadValidate, reasonIfUnsupported, descriptor);
telsoa014fcda012018-03-09 14:13:49 +0000453}
Aron Virginas-Tarbcf9f162018-10-15 11:47:37 +0100454
455bool ClLayerSupport::IsPooling2dSupported(const TensorInfo& input,
456 const TensorInfo& output,
457 const Pooling2dDescriptor& descriptor,
458 Optional<std::string&> reasonIfUnsupported) const
459{
460 FORWARD_WORKLOAD_VALIDATE_FUNC(ClPooling2dWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
461}
462
463bool ClLayerSupport::IsReshapeSupported(const TensorInfo& input,
464 Optional<std::string&> reasonIfUnsupported) const
465{
466 ignore_unused(input);
467 ignore_unused(reasonIfUnsupported);
468 return true;
469}
470
471bool ClLayerSupport::IsResizeBilinearSupported(const TensorInfo& input,
472 Optional<std::string&> reasonIfUnsupported) const
473{
474 return IsSupportedForDataTypeCl(reasonIfUnsupported,
475 input.GetDataType(),
476 &TrueFunc<>,
477 &FalseFuncU8<>);
478}
479
480bool ClLayerSupport::IsSoftmaxSupported(const TensorInfo& input,
481 const TensorInfo& output,
482 const SoftmaxDescriptor& descriptor,
483 Optional<std::string&> reasonIfUnsupported) const
484{
485 ignore_unused(descriptor);
486 FORWARD_WORKLOAD_VALIDATE_FUNC(ClSoftmaxWorkloadValidate, reasonIfUnsupported, input, output);
487}
488
489bool ClLayerSupport::IsSplitterSupported(const TensorInfo& input,
490 const ViewsDescriptor& descriptor,
491 Optional<std::string&> reasonIfUnsupported) const
492{
493 ignore_unused(descriptor);
494 return IsSupportedForDataTypeCl(reasonIfUnsupported,
495 input.GetDataType(),
496 &TrueFunc<>,
497 &TrueFunc<>);
498}
499
500bool ClLayerSupport::IsSubtractionSupported(const TensorInfo& input0,
501 const TensorInfo& input1,
502 const TensorInfo& output,
503 Optional<std::string&> reasonIfUnsupported) const
504{
505 FORWARD_WORKLOAD_VALIDATE_FUNC(ClSubtractionValidate,
506 reasonIfUnsupported,
507 input0,
508 input1,
509 output);
510}
511
512} // namespace armnn