blob: 4b285fc2bea0568476190615a0a88f0f39cb3697 [file] [log] [blame]
giuros0192fd9432018-12-03 17:30:00 +00001/*
Dana Zlotnikd5c496d2021-11-28 14:46:12 +02002 * Copyright (c) 2018-2022 Arm Limited.
giuros0192fd9432018-12-03 17:30:00 +00003 *
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 */
Georgios Pinitas7891a732021-08-20 21:39:25 +010024#include "src/cpu/kernels/CpuElementwiseKernel.h"
giuros0192fd9432018-12-03 17:30:00 +000025
giuros0192fd9432018-12-03 17:30:00 +000026#include "arm_compute/core/Helpers.h"
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010027#include "src/core/CPP/Validate.h"
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000028#include "src/core/common/Registrars.h"
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010029#include "src/core/helpers/AutoConfiguration.h"
30#include "src/core/helpers/WindowHelpers.h"
Dana Zlotnikd5c496d2021-11-28 14:46:12 +020031#include "src/cpu/kernels/elementwise_binary/list.h"
giuros0192fd9432018-12-03 17:30:00 +000032
giuros0192fd9432018-12-03 17:30:00 +000033#include <arm_neon.h>
giuros0192fd9432018-12-03 17:30:00 +000034
35namespace arm_compute
36{
Sang-Hoon Park63001ac2021-01-18 14:20:27 +000037namespace cpu
38{
39namespace kernels
40{
giuros0192fd9432018-12-03 17:30:00 +000041namespace
42{
Dana Zlotnik6a2df882022-01-17 09:54:26 +020043template <ArithmeticOperation op>
44const std::vector<CpuElementwiseKernel<CpuArithmeticKernel>::ElementwiseKernel> available_kernels_arithmetic =
Michalis Spyrou20fca522021-06-07 14:23:57 +010045{
Dana Zlotnik6a2df882022-01-17 09:54:26 +020046 {
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 },
Michalis Spyrou20fca522021-06-07 14:23:57 +0100143};
Dana Zlotnik6a2df882022-01-17 09:54:26 +0200144template <ComparisonOperation op>
145const std::vector<CpuElementwiseKernel<CpuComparisonKernel>::ElementwiseKernel> available_kernels_comperison =
giuros0192fd9432018-12-03 17:30:00 +0000146{
Dana Zlotnik6a2df882022-01-17 09:54:26 +0200147 {
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 },
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000259};
George Wortd88590f2018-12-12 17:39:58 +0000260} // namespace
261
Dana Zlotnik6a2df882022-01-17 09:54:26 +0200262const 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
277const 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
290template <class Derived>
291Status CpuElementwiseKernel<Derived>::validate_arguments_common(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst)
George Wortd88590f2018-12-12 17:39:58 +0000292{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000293 ARM_COMPUTE_RETURN_ERROR_ON_CPU_F16_UNSUPPORTED(&src0);
294 ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(&src0, &src1);
giuros0192fd9432018-12-03 17:30:00 +0000295
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000296 const TensorShape out_shape = TensorShape::broadcast_shape(src0.tensor_shape(), src1.tensor_shape());
giuros0192fd9432018-12-03 17:30:00 +0000297
298 ARM_COMPUTE_RETURN_ERROR_ON_MSG(out_shape.total_size() == 0, "Inputs are not broadcast compatible");
299
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000300 // Validate in case of configured dst
301 if(dst.total_size() > 0)
giuros0192fd9432018-12-03 17:30:00 +0000302 {
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000303 ARM_COMPUTE_RETURN_ERROR_ON_MSG(detail::have_different_dimensions(out_shape, dst.tensor_shape(), 0),
giuros0192fd9432018-12-03 17:30:00 +0000304 "Wrong shape for output");
305 }
306
307 return Status{};
308}
giuros0192fd9432018-12-03 17:30:00 +0000309
Dana Zlotnik6a2df882022-01-17 09:54:26 +0200310void CpuArithmeticKernel::configure_common(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
giuros0192fd9432018-12-03 17:30:00 +0000311{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000312 ARM_COMPUTE_ERROR_ON_NULLPTR(src0, src1, dst);
giuros0192fd9432018-12-03 17:30:00 +0000313
Dana Zlotnik6a2df882022-01-17 09:54:26 +0200314 const auto *uk = CpuArithmeticKernel::get_implementation(ElementwiseDataTypeISASelectorData{ src0->data_type(), CPUInfo::get().get_isa(), static_cast<int>(_op) });
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100315
Dana Zlotnik6a2df882022-01-17 09:54:26 +0200316 ARM_COMPUTE_ERROR_ON(uk == nullptr || uk->ukernel == nullptr);
317
318 _run_method = uk->ukernel;
319 _name = std::string("CpuArithmeticKernel").append("/").append(uk->name);
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100320
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000321 // 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 }
giuros0192fd9432018-12-03 17:30:00 +0000326
Sang-Hoon Parkd0b7b4b2021-03-09 10:47:30 +0000327 auto shape_and_window = compute_output_shape_and_window(src0->tensor_shape(), src1->tensor_shape());
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000328 auto_init_if_empty(*dst, shape_and_window.first, 1, src0->data_type());
329 ICpuKernel::configure(shape_and_window.second);
giuros0192fd9432018-12-03 17:30:00 +0000330}
331
Dana Zlotnik6a2df882022-01-17 09:54:26 +0200332void 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
354template <class Derived>
355void CpuElementwiseKernel<Derived>::run_op(ITensorPack &tensors, const Window &window, const ThreadInfo &info)
giuros0192fd9432018-12-03 17:30:00 +0000356{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000357 ARM_COMPUTE_UNUSED(info);
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100358 ARM_COMPUTE_ERROR_ON(_run_method == nullptr);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000359
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
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100364 _run_method(src0, src1, dst, window);
365}
Dana Zlotnik6a2df882022-01-17 09:54:26 +0200366template void CpuElementwiseKernel<CpuArithmeticKernel>::run_op(ITensorPack &tensors, const Window &window, const ThreadInfo &info);
367template void CpuElementwiseKernel<CpuComparisonKernel>::run_op(ITensorPack &tensors, const Window &window, const ThreadInfo &info);
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100368
Dana Zlotnik6a2df882022-01-17 09:54:26 +0200369template <class Derived>
370const char *CpuElementwiseKernel<Derived>::name() const
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100371{
372 return _name.c_str();
giuros0192fd9432018-12-03 17:30:00 +0000373}
Dana Zlotnik6a2df882022-01-17 09:54:26 +0200374template const char *CpuElementwiseKernel<CpuArithmeticKernel>::name() const;
375template const char *CpuElementwiseKernel<CpuComparisonKernel>::name() const;
giuros0192fd9432018-12-03 17:30:00 +0000376
377/** Arithmetic operators (min, max, squared_diff) */
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000378void CpuArithmeticKernel::configure(ArithmeticOperation op, const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
giuros0192fd9432018-12-03 17:30:00 +0000379{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000380 ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*src0, *src1, *dst));
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000381 _op = op;
Dana Zlotnik6a2df882022-01-17 09:54:26 +0200382 CpuArithmeticKernel::configure_common(src0, src1, dst);
giuros0192fd9432018-12-03 17:30:00 +0000383}
384
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000385Status CpuArithmeticKernel::validate_arguments(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst)
George Wortd88590f2018-12-12 17:39:58 +0000386{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000387 ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&src0, 1, DataType::QASYMM8, DataType::QASYMM8_SIGNED, DataType::S16, DataType::F16, DataType::S32, DataType::F32);
388 // Validate in case of configured dst
389 if(dst.total_size() > 0)
George Wortd88590f2018-12-12 17:39:58 +0000390 {
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000391 ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(&src0, &dst);
George Wortd88590f2018-12-12 17:39:58 +0000392 }
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000393 return validate_arguments_common(src0, src1, dst);
George Wortd88590f2018-12-12 17:39:58 +0000394}
395
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000396Status CpuArithmeticKernel::validate(ArithmeticOperation op, const ITensorInfo *src0, const ITensorInfo *src1, const ITensorInfo *dst)
giuros0192fd9432018-12-03 17:30:00 +0000397{
398 ARM_COMPUTE_UNUSED(op);
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000399 ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src0, src1, dst);
400 ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(*src0, *src1, *dst));
giuros0192fd9432018-12-03 17:30:00 +0000401 return Status{};
402}
403
George Worta1e7e282019-01-15 11:00:29 +0000404/** The division operator */
405
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000406void CpuDivisionKernel::configure(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
George Worta1e7e282019-01-15 11:00:29 +0000407{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000408 ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*src0, *src1, *dst));
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000409 _op = ArithmeticOperation::DIV;
Dana Zlotnik6a2df882022-01-17 09:54:26 +0200410 CpuArithmeticKernel::configure_common(src0, src1, dst);
George Worta1e7e282019-01-15 11:00:29 +0000411}
412
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000413Status CpuDivisionKernel::validate_arguments(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst)
George Worta1e7e282019-01-15 11:00:29 +0000414{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000415 ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&src0, 1, DataType::S32, DataType::F16, DataType::F32);
416 return CpuArithmeticKernel::validate_arguments(src0, src1, dst);
George Worta1e7e282019-01-15 11:00:29 +0000417}
418
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000419Status CpuDivisionKernel::validate(const ITensorInfo *src0, const ITensorInfo *src1, const ITensorInfo *dst)
George Worta1e7e282019-01-15 11:00:29 +0000420{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000421 ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src0, src1, dst);
422 ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(*src0, *src1, *dst));
George Worta1e7e282019-01-15 11:00:29 +0000423 return Status{};
424}
425
Usama Arif81e671e2019-05-13 13:33:14 +0100426/** The power operator */
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000427void CpuPowerKernel::configure(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
Usama Arif81e671e2019-05-13 13:33:14 +0100428{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000429 ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*src0, *src1, *dst));
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000430 _op = ArithmeticOperation::POWER;
Dana Zlotnik6a2df882022-01-17 09:54:26 +0200431 CpuArithmeticKernel::configure_common(src0, src1, dst);
Usama Arif81e671e2019-05-13 13:33:14 +0100432}
433
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000434Status CpuPowerKernel::validate_arguments(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst)
Usama Arif81e671e2019-05-13 13:33:14 +0100435{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000436 ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&src0, 1, DataType::F16, DataType::F32);
437 return CpuArithmeticKernel::validate_arguments(src0, src1, dst);
Usama Arif81e671e2019-05-13 13:33:14 +0100438}
439
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000440Status CpuPowerKernel::validate(const ITensorInfo *src0, const ITensorInfo *src1, const ITensorInfo *dst)
Usama Arif81e671e2019-05-13 13:33:14 +0100441{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000442 ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src0, src1, dst);
443 ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(*src0, *src1, *dst));
Usama Arif81e671e2019-05-13 13:33:14 +0100444 return Status{};
445}
446
George Wortd88590f2018-12-12 17:39:58 +0000447/** Comparison operators (equal, not equal, less than, greater than, less than or equal, greater than or equal) */
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000448void CpuComparisonKernel::configure(ComparisonOperation op, const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
giuros0192fd9432018-12-03 17:30:00 +0000449{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000450 ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*src0, *src1, *dst));
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000451 _op = op;
Dana Zlotnik6a2df882022-01-17 09:54:26 +0200452 CpuComparisonKernel::configure_common(src0, src1, dst);
George Wortd88590f2018-12-12 17:39:58 +0000453}
454
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000455Status CpuComparisonKernel::validate_arguments(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst)
George Wortd88590f2018-12-12 17:39:58 +0000456{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000457 ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&src0, 1, DataType::U8, DataType::QASYMM8, DataType::QASYMM8_SIGNED, DataType::S16, DataType::F16, DataType::S32, DataType::F32);
458 // Validate in case of configured dst
459 if(dst.total_size() > 0)
George Wortd88590f2018-12-12 17:39:58 +0000460 {
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000461 ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&dst, 1, DataType::U8);
George Wortd88590f2018-12-12 17:39:58 +0000462 }
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000463 return validate_arguments_common(src0, src1, dst);
George Wortd88590f2018-12-12 17:39:58 +0000464}
465
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000466Status CpuComparisonKernel::validate(ComparisonOperation op, const ITensorInfo *src0, const ITensorInfo *src1, const ITensorInfo *dst)
George Wortd88590f2018-12-12 17:39:58 +0000467{
468 ARM_COMPUTE_UNUSED(op);
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000469 ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src0, src1, dst);
470 ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(*src0, *src1, *dst));
George Wortd88590f2018-12-12 17:39:58 +0000471 return Status{};
giuros0192fd9432018-12-03 17:30:00 +0000472}
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000473} // namespace kernels
474} // namespace cpu
giuros0192fd9432018-12-03 17:30:00 +0000475} // namespace arm_compute