Compute Library
 22.11
CpuElementwiseKernel.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-2022 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
25 
27 #include "src/core/CPP/Validate.h"
32 
33 #include <arm_neon.h>
34 
35 namespace arm_compute
36 {
37 namespace cpu
38 {
39 namespace kernels
40 {
41 namespace
42 {
43 template <ArithmeticOperation op>
44 const std::vector<CpuElementwiseKernel<CpuArithmeticKernel>::ElementwiseKernel> available_kernels_arithmetic =
45 {
46  {
47  "sve2_qu8_arithmetic",
48  [](const ElementwiseDataTypeISASelectorData & data)
49  {
50  return data.dt == DataType::QASYMM8 && data.isa.sve2 && static_cast<ArithmeticOperation>(data.op) == op;
51  },
52  REGISTER_QASYMM8_SVE2(sve2_qasymm8_elementwise_binary<op>)
53  },
54  {
55  "sve2_qs8_arithmetic",
56  [](const ElementwiseDataTypeISASelectorData & data)
57  {
58  return data.dt == DataType::QASYMM8_SIGNED && data.isa.sve2 && static_cast<ArithmeticOperation>(data.op) == op;
59  },
60  REGISTER_QASYMM8_SIGNED_SVE2(sve2_qasymm8_signed_elementwise_binary<op>)
61  },
62  {
63  "sve_fp32_arithmetic",
64  [](const ElementwiseDataTypeISASelectorData & data)
65  {
66  return data.dt == DataType::F32 && data.isa.sve && static_cast<ArithmeticOperation>(data.op) == op;
67  },
68  REGISTER_FP32_SVE(sve_fp32_elementwise_binary<op>)
69  },
70  {
71  "sve_s32_arithmetic",
72  [](const ElementwiseDataTypeISASelectorData & data)
73  {
74  return data.dt == DataType::S32 && data.isa.sve && static_cast<ArithmeticOperation>(data.op) == op;
75  },
76  REGISTER_INTEGER_SVE(sve_s32_elementwise_binary<op>)
77  },
78  {
79  "sve_s16_arithmetic",
80  [](const ElementwiseDataTypeISASelectorData & data)
81  {
82  return data.dt == DataType::S16 && data.isa.sve && static_cast<ArithmeticOperation>(data.op) == op;
83  },
84  REGISTER_INTEGER_SVE(sve_s16_elementwise_binary<op>)
85  },
86  {
87  "sve_fp16_arithmetic",
88  [](const ElementwiseDataTypeISASelectorData & data)
89  {
90  return data.dt == DataType::F16 && data.isa.sve && data.isa.fp16 && static_cast<ArithmeticOperation>(data.op) == op;
91  },
92  REGISTER_FP16_SVE(sve_fp16_elementwise_binary<op>)
93  },
94  {
95  "neon_fp32_arithmetic",
96 
97  [](const ElementwiseDataTypeISASelectorData & data)
98  {
99  return data.dt == DataType::F32 && static_cast<ArithmeticOperation>(data.op) == op;
100  },
101  REGISTER_FP32_NEON(neon_fp32_elementwise_binary<op>)
102  },
103  {
104  "neon_s32_arithmetic",
105  [](const ElementwiseDataTypeISASelectorData & data)
106  {
107  return data.dt == DataType::S32 && static_cast<ArithmeticOperation>(data.op) == op;
108  },
109  REGISTER_INTEGER_NEON(neon_s32_elementwise_binary<op>)
110  },
111  {
112  "neon_fp16_arithmetic",
113  [](const ElementwiseDataTypeISASelectorData & data)
114  {
115  return data.dt == DataType::F16 && data.isa.fp16 && static_cast<ArithmeticOperation>(data.op) == op;
116  },
117  REGISTER_FP16_NEON(neon_fp16_elementwise_binary<op>)
118  },
119  {
120  "neon_s16_arithmetic",
121  [](const ElementwiseDataTypeISASelectorData & data)
122  {
123  return data.dt == DataType::S16 && static_cast<ArithmeticOperation>(data.op) == op;
124  },
125  REGISTER_INTEGER_NEON(neon_s16_elementwise_binary<op>)
126  },
127  {
128  "neon_qu8_arithmetic",
129  [](const ElementwiseDataTypeISASelectorData & data)
130  {
131  return data.dt == DataType::QASYMM8 && static_cast<ArithmeticOperation>(data.op) == op;
132  },
133  REGISTER_QASYMM8_NEON(neon_qasymm8_elementwise_binary<op>)
134  },
135  {
136  "neon_qs8_arithmetic",
137  [](const ElementwiseDataTypeISASelectorData & data)
138  {
139  return data.dt == DataType::QASYMM8_SIGNED && static_cast<ArithmeticOperation>(data.op) == op;
140  },
141  REGISTER_QASYMM8_SIGNED_NEON(neon_qasymm8_signed_elementwise_binary<op>)
142  },
143 };
144 template <ComparisonOperation op>
145 const std::vector<CpuElementwiseKernel<CpuComparisonKernel>::ElementwiseKernel> available_kernels_comperison =
146 {
147  {
148  "sve2_qu8_comparison",
149  [](const ElementwiseDataTypeISASelectorData & data)
150  {
151  return data.dt == DataType::QASYMM8 && data.isa.sve2 && static_cast<ComparisonOperation>(data.op) == op;
152  },
153  REGISTER_QASYMM8_SVE2(sve2_qasymm8_comparison_elementwise_binary<op>)
154  },
155  {
156  "sve2_qs8_comparison",
157  [](const ElementwiseDataTypeISASelectorData & data)
158  {
159  return data.dt == DataType::QASYMM8_SIGNED && data.isa.sve2 && static_cast<ComparisonOperation>(data.op) == op;
160  },
161  REGISTER_QASYMM8_SIGNED_SVE2(sve2_qasymm8_signed_comparison_elementwise_binary<op>)
162  },
163  {
164  "sve_u8_comparison",
165  [](const ElementwiseDataTypeISASelectorData & data)
166  {
167  return data.dt == DataType::U8 && data.isa.sve && static_cast<ComparisonOperation>(data.op) == op;
168  },
169  REGISTER_INTEGER_SVE(sve_u8_comparison_elementwise_binary<op>)
170  },
171  {
172  "sve_fp32_comparison",
173  [](const ElementwiseDataTypeISASelectorData & data)
174  {
175  return data.dt == DataType::F32 && data.isa.sve && static_cast<ComparisonOperation>(data.op) == op;
176  },
177  REGISTER_FP32_SVE(sve_fp32_comparison_elementwise_binary<op>)
178  },
179  {
180  "sve_s16_comparison",
181  [](const ElementwiseDataTypeISASelectorData & data)
182  {
183  return data.dt == DataType::S16 && data.isa.sve && static_cast<ComparisonOperation>(data.op) == op;
184  },
185  REGISTER_INTEGER_SVE(sve_s16_comparison_elementwise_binary<op>)
186  },
187  {
188  "sve_s32_comparison",
189  [](const ElementwiseDataTypeISASelectorData & data)
190  {
191  return data.dt == DataType::S32 && data.isa.sve && static_cast<ComparisonOperation>(data.op) == op;
192  },
193  REGISTER_INTEGER_SVE(sve_s32_comparison_elementwise_binary<op>)
194  },
195  {
196  "sve_fp16_comparison",
197  [](const ElementwiseDataTypeISASelectorData & data)
198  {
199  return data.dt == DataType::F16 && data.isa.sve && data.isa.fp16 && static_cast<ComparisonOperation>(data.op) == op;
200  },
201  REGISTER_FP16_SVE(sve_fp16_comparison_elementwise_binary<op>)
202  },
203  {
204  "neon_u8_comparison",
205  [](const ElementwiseDataTypeISASelectorData & data)
206  {
207  return data.dt == DataType::U8 && static_cast<ComparisonOperation>(data.op) == op;
208  },
209  REGISTER_INTEGER_NEON(neon_u8_comparison_elementwise_binary<op>)
210  },
211  {
212  "neon_fp32_comparison",
213  [](const ElementwiseDataTypeISASelectorData & data)
214  {
215  return data.dt == DataType::F32 && static_cast<ComparisonOperation>(data.op) == op;
216  },
217  REGISTER_FP32_NEON(neon_fp32_comparison_elementwise_binary<op>)
218  },
219  {
220  "neon_s16_comparison",
221  [](const ElementwiseDataTypeISASelectorData & data)
222  {
223  return data.dt == DataType::S16 && static_cast<ComparisonOperation>(data.op) == op;
224  },
225  REGISTER_INTEGER_NEON(neon_s16_comparison_elementwise_binary<op>)
226  },
227  {
228  "neon_s32_comparison",
229  [](const ElementwiseDataTypeISASelectorData & data)
230  {
231  return data.dt == DataType::S32 && static_cast<ComparisonOperation>(data.op) == op;
232  },
233  REGISTER_INTEGER_NEON(neon_s32_comparison_elementwise_binary<op>)
234  },
235  {
236  "neon_qu8_comparison",
237  [](const ElementwiseDataTypeISASelectorData & data)
238  {
239  return data.dt == DataType::QASYMM8 && static_cast<ComparisonOperation>(data.op) == op;
240  },
241  REGISTER_QASYMM8_NEON(neon_qasymm8_comparison_elementwise_binary<op>)
242  },
243  {
244  "neon_qs8_comparison",
245  [](const ElementwiseDataTypeISASelectorData & data)
246  {
247  return data.dt == DataType::QASYMM8_SIGNED && static_cast<ComparisonOperation>(data.op) == op;
248  },
249  REGISTER_QASYMM8_SIGNED_NEON(neon_qasymm8_signed_comparison_elementwise_binary<op>)
250  },
251  {
252  "neon_fp16_comparison",
253  [](const ElementwiseDataTypeISASelectorData & data)
254  {
255  return data.dt == DataType::F16 && data.isa.fp16 && static_cast<ComparisonOperation>(data.op) == op;
256  },
257  REGISTER_FP16_NEON(neon_fp16_comparison_elementwise_binary<op>)
258  },
259 };
260 } // namespace
261 
262 const std::vector<CpuElementwiseKernel<CpuArithmeticKernel>::ElementwiseKernel> &CpuArithmeticKernel::get_available_kernels()
263 {
264  static std::vector<CpuElementwiseKernel<CpuArithmeticKernel>::ElementwiseKernel> available_kernels;
265  std::move(available_kernels_arithmetic<ArithmeticOperation::ADD>.begin(), available_kernels_arithmetic<ArithmeticOperation::ADD>.end(), std::back_inserter(available_kernels));
266  std::move(available_kernels_arithmetic<ArithmeticOperation::SUB>.begin(), available_kernels_arithmetic<ArithmeticOperation::SUB>.end(), std::back_inserter(available_kernels));
267  std::move(available_kernels_arithmetic<ArithmeticOperation::DIV>.begin(), available_kernels_arithmetic<ArithmeticOperation::DIV>.end(), std::back_inserter(available_kernels));
268  std::move(available_kernels_arithmetic<ArithmeticOperation::MIN>.begin(), available_kernels_arithmetic<ArithmeticOperation::MIN>.end(), std::back_inserter(available_kernels));
269  std::move(available_kernels_arithmetic<ArithmeticOperation::MAX>.begin(), available_kernels_arithmetic<ArithmeticOperation::MAX>.end(), std::back_inserter(available_kernels));
270  std::move(available_kernels_arithmetic<ArithmeticOperation::SQUARED_DIFF>.begin(), available_kernels_arithmetic<ArithmeticOperation::SQUARED_DIFF>.end(), std::back_inserter(available_kernels));
271  std::move(available_kernels_arithmetic<ArithmeticOperation::POWER>.begin(), available_kernels_arithmetic<ArithmeticOperation::POWER>.end(), std::back_inserter(available_kernels));
272  std::move(available_kernels_arithmetic<ArithmeticOperation::PRELU>.begin(), available_kernels_arithmetic<ArithmeticOperation::PRELU>.end(), std::back_inserter(available_kernels));
273 
274  return available_kernels;
275 }
276 
277 const std::vector<CpuElementwiseKernel<CpuComparisonKernel>::ElementwiseKernel> &CpuComparisonKernel::get_available_kernels()
278 {
279  static std::vector<CpuElementwiseKernel<CpuComparisonKernel>::ElementwiseKernel> available_kernels;
280  std::move(available_kernels_comperison<ComparisonOperation::Equal>.begin(), available_kernels_comperison<ComparisonOperation::Equal>.end(), std::back_inserter(available_kernels));
281  std::move(available_kernels_comperison<ComparisonOperation::NotEqual>.begin(), available_kernels_comperison<ComparisonOperation::NotEqual>.end(), std::back_inserter(available_kernels));
282  std::move(available_kernels_comperison<ComparisonOperation::Greater>.begin(), available_kernels_comperison<ComparisonOperation::Greater>.end(), std::back_inserter(available_kernels));
283  std::move(available_kernels_comperison<ComparisonOperation::GreaterEqual>.begin(), available_kernels_comperison<ComparisonOperation::GreaterEqual>.end(), std::back_inserter(available_kernels));
284  std::move(available_kernels_comperison<ComparisonOperation::Less>.begin(), available_kernels_comperison<ComparisonOperation::Less>.end(), std::back_inserter(available_kernels));
285  std::move(available_kernels_comperison<ComparisonOperation::LessEqual>.begin(), available_kernels_comperison<ComparisonOperation::LessEqual>.end(), std::back_inserter(available_kernels));
286 
287  return available_kernels;
288 }
289 
290 template <class Derived>
292 {
295 
296  const TensorShape out_shape = TensorShape::broadcast_shape(src0.tensor_shape(), src1.tensor_shape());
297 
298  ARM_COMPUTE_RETURN_ERROR_ON_MSG(out_shape.total_size() == 0, "Inputs are not broadcast compatible");
299 
300  // Validate in case of configured dst
301  if(dst.total_size() > 0)
302  {
304  "Wrong shape for output");
305  }
306 
307  return Status{};
308 }
309 
310 void CpuArithmeticKernel::configure_common(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
311 {
312  ARM_COMPUTE_ERROR_ON_NULLPTR(src0, src1, dst);
313 
314  const auto *uk = CpuArithmeticKernel::get_implementation(ElementwiseDataTypeISASelectorData{ src0->data_type(), CPUInfo::get().get_isa(), static_cast<int>(_op) });
315 
316  ARM_COMPUTE_ERROR_ON(uk == nullptr || uk->ukernel == nullptr);
317 
318  _run_method = uk->ukernel;
319  _name = std::string("CpuArithmeticKernel").append("/").append(uk->name);
320 
321  // If any of shapes is dynamic, expect a configured window and dst at run-time.
322  if(src0->is_dynamic() || src1->is_dynamic())
323  {
324  return;
325  }
326 
327  auto shape_and_window = compute_output_shape_and_window(src0->tensor_shape(), src1->tensor_shape());
328  auto_init_if_empty(*dst, shape_and_window.first, 1, src0->data_type());
329  ICpuKernel::configure(shape_and_window.second);
330 }
331 
332 void CpuComparisonKernel::configure_common(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
333 {
334  ARM_COMPUTE_ERROR_ON_NULLPTR(src0, src1, dst);
335 
336  const auto *uk = CpuComparisonKernel::get_implementation(ElementwiseDataTypeISASelectorData{ src0->data_type(), CPUInfo::get().get_isa(), static_cast<int>(_op) });
337 
338  ARM_COMPUTE_ERROR_ON(uk == nullptr || uk->ukernel == nullptr);
339 
340  _run_method = uk->ukernel;
341  _name = std::string("CpuComparisonKernel").append("/").append(uk->name);
342 
343  // If any of shapes is dynamic, expect a configured window and dst at run-time.
344  if(src0->is_dynamic() || src1->is_dynamic())
345  {
346  return;
347  }
348 
349  auto shape_and_window = compute_output_shape_and_window(src0->tensor_shape(), src1->tensor_shape());
350  auto_init_if_empty(*dst, shape_and_window.first, 1, src0->data_type());
351  ICpuKernel::configure(shape_and_window.second);
352 }
353 
354 template <class Derived>
356 {
357  ARM_COMPUTE_UNUSED(info);
358  ARM_COMPUTE_ERROR_ON(_run_method == nullptr);
359 
360  auto src0 = tensors.get_const_tensor(TensorType::ACL_SRC_0);
361  auto src1 = tensors.get_const_tensor(TensorType::ACL_SRC_1);
362  auto dst = tensors.get_tensor(TensorType::ACL_DST);
363 
364  _run_method(src0, src1, dst, window);
365 }
367 template void CpuElementwiseKernel<CpuComparisonKernel>::run_op(ITensorPack &tensors, const Window &window, const ThreadInfo &info);
368 
369 template <class Derived>
371 {
372  return _name.c_str();
373 }
374 template const char *CpuElementwiseKernel<CpuArithmeticKernel>::name() const;
375 template const char *CpuElementwiseKernel<CpuComparisonKernel>::name() const;
376 
377 /** Arithmetic operators (min, max, squared_diff) */
379 {
380  ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*src0, *src1, *dst));
381  _op = op;
382  CpuArithmeticKernel::configure_common(src0, src1, dst);
383 }
384 
385 Status CpuArithmeticKernel::validate_arguments(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst)
386 {
388  // Validate in case of configured dst
389  if(dst.total_size() > 0)
390  {
392  }
393  return validate_arguments_common(src0, src1, dst);
394 }
395 
397 {
398  ARM_COMPUTE_UNUSED(op);
399  ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src0, src1, dst);
400  ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(*src0, *src1, *dst));
401  return Status{};
402 }
403 
404 /** The division operator */
405 
407 {
408  ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*src0, *src1, *dst));
410  CpuArithmeticKernel::configure_common(src0, src1, dst);
411 }
412 
413 Status CpuDivisionKernel::validate_arguments(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst)
414 {
416  return CpuArithmeticKernel::validate_arguments(src0, src1, dst);
417 }
418 
420 {
421  ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src0, src1, dst);
422  ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(*src0, *src1, *dst));
423  return Status{};
424 }
425 
426 /** The power operator */
427 void CpuPowerKernel::configure(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
428 {
429  ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*src0, *src1, *dst));
431  CpuArithmeticKernel::configure_common(src0, src1, dst);
432 }
433 
434 Status CpuPowerKernel::validate_arguments(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst)
435 {
437  return CpuArithmeticKernel::validate_arguments(src0, src1, dst);
438 }
439 
441 {
442  ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src0, src1, dst);
443  ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(*src0, *src1, *dst));
444  return Status{};
445 }
446 
447 /** Comparison operators (equal, not equal, less than, greater than, less than or equal, greater than or equal) */
449 {
450  ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*src0, *src1, *dst));
451  _op = op;
452  CpuComparisonKernel::configure_common(src0, src1, dst);
453 }
454 
455 Status CpuComparisonKernel::validate_arguments(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst)
456 {
458  // Validate in case of configured dst
459  if(dst.total_size() > 0)
460  {
462  }
463  return validate_arguments_common(src0, src1, dst);
464 }
465 
467 {
468  ARM_COMPUTE_UNUSED(op);
469  ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src0, src1, dst);
470  ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(*src0, *src1, *dst));
471  return Status{};
472 }
473 } // namespace kernels
474 } // namespace cpu
475 } // namespace arm_compute
ArithmeticOperation
Available element-wise operations.
Definition: Types.h:489
const Window & window() const
The maximum window the kernel can be executed on.
Definition: IKernel.cpp:28
Shape of a tensor.
Definition: TensorShape.h:39
static const auto * get_implementation(const SelectorType &selector, KernelSelectionType selection_type=KernelSelectionType::Supported)
Micro-kernel selector.
Definition: ICpuKernel.h:53
void configure(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
Configure kernel.
void configure(ArithmeticOperation op, const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
Configure kernel.
#define ARM_COMPUTE_RETURN_ERROR_ON_CPU_F16_UNSUPPORTED(tensor)
Definition: Validate.h:115
#define REGISTER_FP16_NEON(func_name)
Definition: Registrars.h:48
Interface for an element-wise operation kernel.
1 channel, 1 U8 per channel
#define REGISTER_FP32_NEON(func_name)
Definition: Registrars.h:74
#define ARM_COMPUTE_RETURN_ON_ERROR(status)
Checks if a status contains an error and returns it.
Definition: Error.h:204
virtual DataType data_type() const =0
Data type used for each element of the tensor.
1 channel, 1 F32 per channel
#define REGISTER_FP32_SVE(func_name)
Definition: Registrars.h:75
static TensorShape broadcast_shape(const Shapes &... shapes)
If shapes are broadcast compatible, return the broadcasted shape.
Definition: TensorShape.h:211
#define ARM_COMPUTE_ERROR_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
Definition: Error.h:466
#define REGISTER_QASYMM8_SIGNED_NEON(func_name)
Definition: Registrars.h:96
static Status validate(const ITensorInfo *src0, const ITensorInfo *src1, const ITensorInfo *dst)
Static function to check if given info will lead to a valid configuration.
Store the tensor&#39;s metadata.
Definition: ITensorInfo.h:40
#define ARM_COMPUTE_ERROR_THROW_ON(status)
Definition: Error.h:455
virtual bool is_dynamic() const =0
Flag indicating whether the shape of the tensor is dynamic, meaning that it can change on kernel/func...
Status class.
Definition: Error.h:52
void configure(ComparisonOperation op, const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
Configure kernel.
Copyright (c) 2017-2022 Arm Limited.
1 channel, 1 F16 per channel
static Status validate(ArithmeticOperation op, const ITensorInfo *src0, const ITensorInfo *src1, const ITensorInfo *dst)
Static function to check if given info will lead to a valid configuration.
#define REGISTER_INTEGER_NEON(func_name)
Definition: Registrars.h:171
const char * name() const override
Name of the kernel.
static const std::vector< CpuElementwiseKernel< CpuComparisonKernel >::ElementwiseKernel > & get_available_kernels()
#define ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(...)
Definition: Validate.h:159
1 channel, 1 S32 per channel
const ITensor * get_const_tensor(int id) const
Get constant tensor of a given id.
Definition: ITensorPack.cpp:54
#define ARM_COMPUTE_UNUSED(...)
To avoid unused variables warnings.
Definition: Error.h:152
void configure(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
Configure kernel.
#define REGISTER_QASYMM8_NEON(func_name)
Definition: Registrars.h:117
virtual const TensorShape & tensor_shape() const =0
Size for each dimension of the tensor.
quantized, asymmetric fixed-point 8-bit number unsigned
size_t total_size() const
Collapses all dimensions to a single linear total size.
Definition: TensorShape.h:172
#define REGISTER_INTEGER_SVE(func_name)
Definition: Registrars.h:172
bool auto_init_if_empty(ITensorInfo &info, const TensorShape &shape, int num_channels, DataType data_type, QuantizationInfo quantization_info=QuantizationInfo())
Auto initialize the tensor info (shape, number of channels and data type) if the current assignment i...
static const std::vector< CpuElementwiseKernel< CpuArithmeticKernel >::ElementwiseKernel > & get_available_kernels()
bool have_different_dimensions(const Dimensions< T > &dim1, const Dimensions< T > &dim2, unsigned int upper_dim)
Definition: Validate.h:47
#define REGISTER_QASYMM8_SIGNED_SVE2(func_name)
Definition: Registrars.h:98
void end(TokenStream &in, bool &valid)
Definition: MLGOParser.cpp:290
ComparisonOperation
Supported comparison operations.
Definition: Types.h:173
1 channel, 1 S16 per channel
static Status validate(const ITensorInfo *src0, const ITensorInfo *src1, const ITensorInfo *dst)
Static function to check if given info will lead to a valid configuration.
ScaleKernelInfo info(interpolation_policy, default_border_mode, PixelValue(), sampling_policy, false)
ITensor * get_tensor(int id)
Get tensor of a given id from the pac.
Definition: ITensorPack.cpp:64
Information about executing thread and CPU.
Definition: CPPTypes.h:179
virtual size_t total_size() const =0
Returns the total size of the tensor in bytes.
#define REGISTER_FP16_SVE(func_name)
Definition: Registrars.h:49
void run_op(ITensorPack &tensors, const Window &window, const ThreadInfo &info) override
Execute the kernel on the passed window.
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(...)
Definition: Validate.h:541
#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c,...)
Definition: Validate.h:788
#define ARM_COMPUTE_RETURN_ERROR_ON_MSG(cond, msg)
If the condition is true, an error is returned.
Definition: Error.h:244
Tensor packing service.
Definition: ITensorPack.h:39
#define ARM_COMPUTE_ERROR_ON_NULLPTR(...)
Definition: Validate.h:157
quantized, asymmetric fixed-point 8-bit number signed
static CPUInfo & get()
Access the KernelLibrary singleton.
Definition: CPPTypes.cpp:40
#define REGISTER_QASYMM8_SVE2(func_name)
Definition: Registrars.h:119
Describe a multidimensional execution window.
Definition: Window.h:39
static Status validate(ComparisonOperation op, const ITensorInfo *src0, const ITensorInfo *src1, const ITensorInfo *dst)
Static function to check if given info will lead to a valid configuration.
cpuinfo::CpuIsaInfo get_isa() const
Gets the current cpu&#39;s ISA information.
Definition: CPPTypes.cpp:124