blob: dc574fce651265a59a3a731179f800c2667deb5e [file] [log] [blame]
giuros0192fd9432018-12-03 17:30:00 +00001/*
Sang-Hoon Park5db75c32021-01-07 16:59:32 +00002 * Copyright (c) 2018-2021 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 */
Sang-Hoon Park63001ac2021-01-18 14:20:27 +000024#include "src/core/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 Park63001ac2021-01-18 14:20:27 +000029#include "src/core/cpu/kernels/elementwise/neon/elementwise_list.h"
30#include "src/core/cpu/kernels/elementwise/neon/elementwise_quantized_list.h"
31#include "src/core/cpu/kernels/elementwise/sve/elementwise_list.h"
32#include "src/core/cpu/kernels/elementwise/sve/elementwise_quantized_list.h"
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010033#include "src/core/helpers/AutoConfiguration.h"
34#include "src/core/helpers/WindowHelpers.h"
giuros0192fd9432018-12-03 17:30:00 +000035
giuros0192fd9432018-12-03 17:30:00 +000036#include <arm_neon.h>
giuros0192fd9432018-12-03 17:30:00 +000037
38namespace arm_compute
39{
Sang-Hoon Park63001ac2021-01-18 14:20:27 +000040namespace cpu
41{
42namespace kernels
43{
giuros0192fd9432018-12-03 17:30:00 +000044namespace
45{
Michalis Spyrou20fca522021-06-07 14:23:57 +010046struct ElementwiseSelectorData
47{
48 DataType dt;
49 const CPUInfo &ci;
50};
51
52using ElementwiseSelector = std::add_pointer<bool(const ElementwiseSelectorData &)>::type;
Sang-Hoon Park63001ac2021-01-18 14:20:27 +000053using UKernelType = CpuElementwiseKernel::ElementwiseFunction;
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000054struct ElementwiseKernel
giuros0192fd9432018-12-03 17:30:00 +000055{
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000056 const char *name;
57 const ElementwiseSelector is_selected;
58 UKernelType *ukernel;
59};
60
Georgios Pinitas5fdde992021-06-25 05:42:57 +010061template <ArithmeticOperation op>
62CpuElementwiseKernel::UKernelInfo configure_arithm_func(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
George Wortd88590f2018-12-12 17:39:58 +000063{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +000064 ARM_COMPUTE_UNUSED(src1, dst);
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000065 static ElementwiseKernel kernels[] =
George Wortd88590f2018-12-12 17:39:58 +000066 {
Michalis Spyrou20fca522021-06-07 14:23:57 +010067#if defined(ARM_COMPUTE_ENABLE_SVE)
68 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +010069 "sve_fp32_elementwise",
Michalis Spyrou20fca522021-06-07 14:23:57 +010070 [](const ElementwiseSelectorData & data) { return data.dt == DataType::F32 && data.ci.has_sve(); },
71 REGISTER_FP32_SVE((arm_compute::cpu::elementwise_arithmetic_op<op, float32_t>))
72 },
73 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +010074 "sve_s32_elementwise",
Michalis Spyrou20fca522021-06-07 14:23:57 +010075 [](const ElementwiseSelectorData & data) { return data.dt == DataType::S32 && data.ci.has_sve(); },
76 REGISTER_INTEGER_SVE((arm_compute::cpu::elementwise_arithmetic_op<op, int32_t>))
77 },
78 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +010079 "sve_s16_elementwise",
Michalis Spyrou20fca522021-06-07 14:23:57 +010080 [](const ElementwiseSelectorData & data) { return data.dt == DataType::S16 && data.ci.has_sve(); },
81 REGISTER_INTEGER_SVE((arm_compute::cpu::elementwise_arithmetic_op<op, int16_t>))
82 },
83#endif /* defined(ARM_COMPUTE_ENABLE_SVE) */
84#if defined(ARM_COMPUTE_ENABLE_NEON)
85 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +010086 "neon_fp32_elementwise",
Michalis Spyrou20fca522021-06-07 14:23:57 +010087 [](const ElementwiseSelectorData & data) { return data.dt == DataType::F32; },
88 REGISTER_FP32_NEON((arm_compute::cpu::elementwise_arithm_op<op, typename wrapper::traits::neon_vector<float, 4>>))
89 },
90 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +010091 "neon_s32_elementwise",
Michalis Spyrou20fca522021-06-07 14:23:57 +010092 [](const ElementwiseSelectorData & data) { return data.dt == DataType::S32; },
93 REGISTER_INTEGER_NEON((arm_compute::cpu::elementwise_arithm_op<op, typename wrapper::traits::neon_vector<int32_t, 4>>))
94 },
95#endif /* defined(ARM_COMPUTE_ENABLE_NEON) */
96#if defined(ARM_COMPUTE_ENABLE_SVE2)
97 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +010098 "sve2_qu8_elementwise",
Michalis Spyrou20fca522021-06-07 14:23:57 +010099 [](const ElementwiseSelectorData & data) { return data.dt == DataType::QASYMM8 && data.ci.has_sve2(); },
100 REGISTER_QASYMM8_SVE((arm_compute::cpu::elementwise_arithmetic_quantized_op<op, uint8_t>))
101 },
102 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100103 "sve2_qs8_elementwise",
Michalis Spyrou20fca522021-06-07 14:23:57 +0100104 [](const ElementwiseSelectorData & data) { return data.dt == DataType::QASYMM8_SIGNED && data.ci.has_sve2(); },
105 REGISTER_QASYMM8_SIGNED_SVE((arm_compute::cpu::elementwise_arithmetic_quantized_op<op, int8_t>))
106 },
107#endif /* defined(ARM_COMPUTE_ENABLE_SVE2) */
108#if defined(ARM_COMPUTE_ENABLE_NEON) || defined(ARM_COMPUTE_ENABLE_SVE)
109 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100110 "neon_qu8_elementwise",
Michalis Spyrou20fca522021-06-07 14:23:57 +0100111 [](const ElementwiseSelectorData & data) { return data.dt == DataType::QASYMM8; },
112 REGISTER_QASYMM8_NEON((arm_compute::cpu::elementwise_arithm_op_quantized<op>))
113 },
114 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100115 "neon_qs8_elementwise",
Michalis Spyrou20fca522021-06-07 14:23:57 +0100116 [](const ElementwiseSelectorData & data) { return data.dt == DataType::QASYMM8_SIGNED; },
117 REGISTER_QASYMM8_SIGNED_NEON((arm_compute::cpu::elementwise_arithm_op_quantized_signed<op>))
118 },
119#endif /* defined(ARM_COMPUTE_ENABLE_NEON) || defined(ARM_COMPUTE_ENABLE_SVE) */
120#if defined(ARM_COMPUTE_ENABLE_SVE)
121 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100122 "sve_fp16_elementwise",
Michalis Spyrou20fca522021-06-07 14:23:57 +0100123 [](const ElementwiseSelectorData & data) { return data.dt == DataType::F16 && data.ci.has_sve(); },
124 REGISTER_FP16_SVE((arm_compute::cpu::elementwise_arithmetic_op<op, float16_t>))
125 },
126#endif /* defined(ARM_COMPUTE_ENABLE_SVE) */
127#if defined(ARM_COMPUTE_ENABLE_NEON)
Georgios Pinitasbdcdc392021-04-22 16:42:03 +0100128#if defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
Michalis Spyrou20fca522021-06-07 14:23:57 +0100129 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100130 "neon_fp16_elementwise",
Michalis Spyrou20fca522021-06-07 14:23:57 +0100131 [](const ElementwiseSelectorData & data) { return data.dt == DataType::F16 && data.ci.has_fp16(); },
132 REGISTER_FP16_NEON((arm_compute::cpu::elementwise_arithm_op<op, typename wrapper::traits::neon_vector<float16_t, 8>>))
133 },
Georgios Pinitasbdcdc392021-04-22 16:42:03 +0100134#endif /* defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) */
Michalis Spyrou20fca522021-06-07 14:23:57 +0100135 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100136 "neon_s16_elementwise",
Michalis Spyrou20fca522021-06-07 14:23:57 +0100137 [](const ElementwiseSelectorData & data) { return data.dt == DataType::S16; },
138 REGISTER_INTEGER_NEON((arm_compute::cpu::elementwise_arithm_op<op, typename wrapper::traits::neon_vector<int16_t, 8>>))
139 },
140#endif /* defined(ARM_COMPUTE_ENABLE_NEON) */
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000141 };
George Wortd88590f2018-12-12 17:39:58 +0000142
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000143 for(const auto &uk : kernels)
144 {
Michalis Spyrou20fca522021-06-07 14:23:57 +0100145 if(uk.is_selected({ src0->data_type(), CPUInfo::get() }))
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000146 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100147 return { uk.name, uk.ukernel };
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000148 }
149 }
150
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100151 return { "", nullptr };
George Wortd88590f2018-12-12 17:39:58 +0000152}
153
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100154template <ComparisonOperation op>
155CpuElementwiseKernel::UKernelInfo configure_comp_func(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
George Wortd88590f2018-12-12 17:39:58 +0000156{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000157 ARM_COMPUTE_UNUSED(src1, dst);
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000158 static ElementwiseKernel kernels[] =
George Wortd88590f2018-12-12 17:39:58 +0000159 {
Michalis Spyrou20fca522021-06-07 14:23:57 +0100160#if defined(ARM_COMPUTE_ENABLE_SVE)
161 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100162 "sve_u8_comparison",
Michalis Spyrou20fca522021-06-07 14:23:57 +0100163 [](const ElementwiseSelectorData & data) { return data.dt == DataType::U8 && data.ci.has_sve(); },
164 REGISTER_INTEGER_SVE((arm_compute::cpu::elementwise_comparison_op<op, uint8_t>))
165 },
166 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100167 "sve_fp32_comparison",
Michalis Spyrou20fca522021-06-07 14:23:57 +0100168 [](const ElementwiseSelectorData & data) { return data.dt == DataType::F32 && data.ci.has_sve(); },
169 REGISTER_FP32_SVE((arm_compute::cpu::elementwise_comparison_op<op, float>))
170 },
171 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100172 "sve_s16_comparison",
Michalis Spyrou20fca522021-06-07 14:23:57 +0100173 [](const ElementwiseSelectorData & data) { return data.dt == DataType::S16 && data.ci.has_sve(); },
174 REGISTER_INTEGER_SVE((arm_compute::cpu::elementwise_comparison_op<op, int16_t>))
175 },
176 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100177 "sve_s32_comparison",
Michalis Spyrou20fca522021-06-07 14:23:57 +0100178 [](const ElementwiseSelectorData & data) { return data.dt == DataType::S32 && data.ci.has_sve(); },
179 REGISTER_INTEGER_SVE((arm_compute::cpu::elementwise_comparison_op<op, int32_t>))
180 },
181#endif /* defined(ARM_COMPUTE_ENABLE_SVE) */
182#if defined(ARM_COMPUTE_ENABLE_NEON)
183 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100184 "neon_u8_comparison",
Michalis Spyrou20fca522021-06-07 14:23:57 +0100185 [](const ElementwiseSelectorData & data) { return data.dt == DataType::U8; },
186 REGISTER_INTEGER_NEON((arm_compute::cpu::elementwise_comp_op_8<op, uint8_t, uint8x16_t>))
187 },
188 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100189 "neon_fp32_comparison",
Michalis Spyrou20fca522021-06-07 14:23:57 +0100190 [](const ElementwiseSelectorData & data) { return data.dt == DataType::F32; },
191 REGISTER_FP32_NEON((arm_compute::cpu::elementwise_comp_op_32<op, float, float32x4_t>))
192 },
193 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100194 "neon_s16_comparison",
Michalis Spyrou20fca522021-06-07 14:23:57 +0100195 [](const ElementwiseSelectorData & data) { return data.dt == DataType::S16; },
196 REGISTER_INTEGER_NEON((arm_compute::cpu::elementwise_comp_op_16<op, int16_t, int16x8_t>))
197 },
198 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100199 "neon_s32_comparison",
Michalis Spyrou20fca522021-06-07 14:23:57 +0100200 [](const ElementwiseSelectorData & data) { return data.dt == DataType::S32; },
201 REGISTER_INTEGER_NEON((arm_compute::cpu::elementwise_comp_op_32<op, int32_t, int32x4_t>))
202 },
203#endif /* defined(ARM_COMPUTE_ENABLE_NEON) */
204#if defined(ARM_COMPUTE_ENABLE_SVE2)
205 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100206 "sve2_qu8_comparison",
Michalis Spyrou20fca522021-06-07 14:23:57 +0100207 [](const ElementwiseSelectorData & data) { return data.dt == DataType::QASYMM8 && data.ci.has_sve2(); },
208 REGISTER_QASYMM8_SVE((arm_compute::cpu::elementwise_comparison_quantized_op<op, uint8_t>))
209 },
210 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100211 "sve2_qs8_comparison",
Michalis Spyrou20fca522021-06-07 14:23:57 +0100212 [](const ElementwiseSelectorData & data) { return data.dt == DataType::QASYMM8_SIGNED && data.ci.has_sve2(); },
213 REGISTER_QASYMM8_SIGNED_SVE((arm_compute::cpu::elementwise_comparison_quantized_op<op, int8_t>))
214 },
215#endif /* defined(ARM_COMPUTE_ENABLE_SVE2) */
216#if defined(ARM_COMPUTE_ENABLE_NEON) || defined(ARM_COMPUTE_ENABLE_SVE)
217 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100218 "neon_qu8_comparison",
Michalis Spyrou20fca522021-06-07 14:23:57 +0100219 [](const ElementwiseSelectorData & data) { return data.dt == DataType::QASYMM8; },
220 REGISTER_QASYMM8_NEON((arm_compute::cpu::elementwise_comp_op_quantized<op>))
221 },
222 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100223 "neon_qs8_comparison",
Michalis Spyrou20fca522021-06-07 14:23:57 +0100224 [](const ElementwiseSelectorData & data) { return data.dt == DataType::QASYMM8_SIGNED; },
225 REGISTER_QASYMM8_SIGNED_NEON((arm_compute::cpu::elementwise_comp_op_quantized_signed<op>))
226 },
227#endif /* defined(ARM_COMPUTE_ENABLE_NEON) || defined(ARM_COMPUTE_ENABLE_SVE) */
228#if defined(ARM_COMPUTE_ENABLE_SVE)
229 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100230 "sve_fp16_comparison",
Michalis Spyrou20fca522021-06-07 14:23:57 +0100231 [](const ElementwiseSelectorData & data) { return data.dt == DataType::F16 && data.ci.has_sve(); },
232 REGISTER_FP16_SVE((arm_compute::cpu::elementwise_comparison_op<op, float16_t>))
233 },
234#endif /* defined(ARM_COMPUTE_ENABLE_SVE) */
235#if defined(ARM_COMPUTE_ENABLE_NEON) && defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
236 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100237 "neon_fp16_comparison",
Michalis Spyrou20fca522021-06-07 14:23:57 +0100238 [](const ElementwiseSelectorData & data) { return data.dt == DataType::F16 && data.ci.has_fp16(); },
239 REGISTER_FP16_NEON((arm_compute::cpu::elementwise_comp_op_16<op, float16_t, float16x8_t>))
240 },
241#endif /* defined(ARM_COMPUTE_ENABLE_NEON) && defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) */
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000242 };
George Wortd88590f2018-12-12 17:39:58 +0000243
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000244 for(const auto &uk : kernels)
245 {
Michalis Spyrou20fca522021-06-07 14:23:57 +0100246 if(uk.is_selected({ src0->data_type(), CPUInfo::get() }))
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000247 {
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100248 return { uk.name, uk.ukernel };
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000249 }
250 }
251
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100252 return { "", nullptr };
George Wortd88590f2018-12-12 17:39:58 +0000253}
254} // namespace
255
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000256Status CpuElementwiseKernel::validate_arguments_common(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst)
George Wortd88590f2018-12-12 17:39:58 +0000257{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000258 ARM_COMPUTE_RETURN_ERROR_ON_CPU_F16_UNSUPPORTED(&src0);
259 ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(&src0, &src1);
giuros0192fd9432018-12-03 17:30:00 +0000260
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000261 const TensorShape out_shape = TensorShape::broadcast_shape(src0.tensor_shape(), src1.tensor_shape());
giuros0192fd9432018-12-03 17:30:00 +0000262
263 ARM_COMPUTE_RETURN_ERROR_ON_MSG(out_shape.total_size() == 0, "Inputs are not broadcast compatible");
264
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000265 // Validate in case of configured dst
266 if(dst.total_size() > 0)
giuros0192fd9432018-12-03 17:30:00 +0000267 {
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000268 ARM_COMPUTE_RETURN_ERROR_ON_MSG(detail::have_different_dimensions(out_shape, dst.tensor_shape(), 0),
giuros0192fd9432018-12-03 17:30:00 +0000269 "Wrong shape for output");
270 }
271
272 return Status{};
273}
giuros0192fd9432018-12-03 17:30:00 +0000274
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000275void CpuElementwiseKernel::configure_common(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
giuros0192fd9432018-12-03 17:30:00 +0000276{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000277 ARM_COMPUTE_ERROR_ON_NULLPTR(src0, src1, dst);
giuros0192fd9432018-12-03 17:30:00 +0000278
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100279 const auto uk = get_implementation(src0, src1, dst);
280
281 _run_method = uk.ukernel;
282 _name = std::string("CpuElementwiseKernel").append("/").append(uk.name);
283
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000284 // If any of shapes is dynamic, expect a configured window and dst at run-time.
285 if(src0->is_dynamic() || src1->is_dynamic())
286 {
287 return;
288 }
giuros0192fd9432018-12-03 17:30:00 +0000289
Sang-Hoon Parkd0b7b4b2021-03-09 10:47:30 +0000290 auto shape_and_window = compute_output_shape_and_window(src0->tensor_shape(), src1->tensor_shape());
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000291 auto_init_if_empty(*dst, shape_and_window.first, 1, src0->data_type());
292 ICpuKernel::configure(shape_and_window.second);
giuros0192fd9432018-12-03 17:30:00 +0000293}
294
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000295void CpuElementwiseKernel::run_op(ITensorPack &tensors, const Window &window, const ThreadInfo &info)
giuros0192fd9432018-12-03 17:30:00 +0000296{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000297 ARM_COMPUTE_UNUSED(info);
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100298 ARM_COMPUTE_ERROR_ON(_run_method == nullptr);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000299
300 auto src0 = tensors.get_const_tensor(TensorType::ACL_SRC_0);
301 auto src1 = tensors.get_const_tensor(TensorType::ACL_SRC_1);
302 auto dst = tensors.get_tensor(TensorType::ACL_DST);
303
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100304 _run_method(src0, src1, dst, window);
305}
306
307const char *CpuElementwiseKernel::name() const
308{
309 return _name.c_str();
giuros0192fd9432018-12-03 17:30:00 +0000310}
311
312/** Arithmetic operators (min, max, squared_diff) */
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000313void CpuArithmeticKernel::configure(ArithmeticOperation op, const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
giuros0192fd9432018-12-03 17:30:00 +0000314{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000315 ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*src0, *src1, *dst));
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000316 _op = op;
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100317 configure_common(src0, src1, dst);
giuros0192fd9432018-12-03 17:30:00 +0000318}
319
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000320Status CpuArithmeticKernel::validate_arguments(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst)
George Wortd88590f2018-12-12 17:39:58 +0000321{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000322 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);
323 // Validate in case of configured dst
324 if(dst.total_size() > 0)
George Wortd88590f2018-12-12 17:39:58 +0000325 {
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000326 ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(&src0, &dst);
George Wortd88590f2018-12-12 17:39:58 +0000327 }
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000328 return validate_arguments_common(src0, src1, dst);
George Wortd88590f2018-12-12 17:39:58 +0000329}
330
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000331Status CpuArithmeticKernel::validate(ArithmeticOperation op, const ITensorInfo *src0, const ITensorInfo *src1, const ITensorInfo *dst)
giuros0192fd9432018-12-03 17:30:00 +0000332{
333 ARM_COMPUTE_UNUSED(op);
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000334 ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src0, src1, dst);
335 ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(*src0, *src1, *dst));
giuros0192fd9432018-12-03 17:30:00 +0000336 return Status{};
337}
338
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100339CpuElementwiseKernel::UKernelInfo CpuArithmeticKernel::get_implementation(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000340{
341 switch(_op)
342 {
343 case ArithmeticOperation::MAX:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000344 return configure_arithm_func<ArithmeticOperation::MAX>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000345 case ArithmeticOperation::MIN:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000346 return configure_arithm_func<ArithmeticOperation::MIN>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000347 case ArithmeticOperation::SQUARED_DIFF:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000348 return configure_arithm_func<ArithmeticOperation::SQUARED_DIFF>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000349 case ArithmeticOperation::PRELU:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000350 return configure_arithm_func<ArithmeticOperation::PRELU>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000351 case ArithmeticOperation::DIV:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000352 return configure_arithm_func<ArithmeticOperation::DIV>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000353 case ArithmeticOperation::POWER:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000354 return configure_arithm_func<ArithmeticOperation::POWER>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000355 default:
356 ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
357 }
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100358 return { "", nullptr };
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000359}
360
George Worta1e7e282019-01-15 11:00:29 +0000361/** The division operator */
362
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000363void CpuDivisionKernel::configure(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
George Worta1e7e282019-01-15 11:00:29 +0000364{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000365 ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*src0, *src1, *dst));
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000366 _op = ArithmeticOperation::DIV;
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100367 configure_common(src0, src1, dst);
George Worta1e7e282019-01-15 11:00:29 +0000368}
369
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000370Status CpuDivisionKernel::validate_arguments(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst)
George Worta1e7e282019-01-15 11:00:29 +0000371{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000372 ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&src0, 1, DataType::S32, DataType::F16, DataType::F32);
373 return CpuArithmeticKernel::validate_arguments(src0, src1, dst);
George Worta1e7e282019-01-15 11:00:29 +0000374}
375
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000376Status CpuDivisionKernel::validate(const ITensorInfo *src0, const ITensorInfo *src1, const ITensorInfo *dst)
George Worta1e7e282019-01-15 11:00:29 +0000377{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000378 ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src0, src1, dst);
379 ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(*src0, *src1, *dst));
George Worta1e7e282019-01-15 11:00:29 +0000380 return Status{};
381}
382
Usama Arif81e671e2019-05-13 13:33:14 +0100383/** The power operator */
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000384void CpuPowerKernel::configure(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
Usama Arif81e671e2019-05-13 13:33:14 +0100385{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000386 ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*src0, *src1, *dst));
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000387 _op = ArithmeticOperation::POWER;
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100388 configure_common(src0, src1, dst);
Usama Arif81e671e2019-05-13 13:33:14 +0100389}
390
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000391Status CpuPowerKernel::validate_arguments(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst)
Usama Arif81e671e2019-05-13 13:33:14 +0100392{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000393 ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&src0, 1, DataType::F16, DataType::F32);
394 return CpuArithmeticKernel::validate_arguments(src0, src1, dst);
Usama Arif81e671e2019-05-13 13:33:14 +0100395}
396
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000397Status CpuPowerKernel::validate(const ITensorInfo *src0, const ITensorInfo *src1, const ITensorInfo *dst)
Usama Arif81e671e2019-05-13 13:33:14 +0100398{
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));
Usama Arif81e671e2019-05-13 13:33:14 +0100401 return Status{};
402}
403
George Wortd88590f2018-12-12 17:39:58 +0000404/** 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 +0000405void CpuComparisonKernel::configure(ComparisonOperation op, const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
giuros0192fd9432018-12-03 17:30:00 +0000406{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000407 ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*src0, *src1, *dst));
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000408 _op = op;
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100409 configure_common(src0, src1, dst);
George Wortd88590f2018-12-12 17:39:58 +0000410}
411
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000412Status CpuComparisonKernel::validate_arguments(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst)
George Wortd88590f2018-12-12 17:39:58 +0000413{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000414 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);
415 // Validate in case of configured dst
416 if(dst.total_size() > 0)
George Wortd88590f2018-12-12 17:39:58 +0000417 {
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000418 ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&dst, 1, DataType::U8);
George Wortd88590f2018-12-12 17:39:58 +0000419 }
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000420 return validate_arguments_common(src0, src1, dst);
George Wortd88590f2018-12-12 17:39:58 +0000421}
422
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000423Status CpuComparisonKernel::validate(ComparisonOperation op, const ITensorInfo *src0, const ITensorInfo *src1, const ITensorInfo *dst)
George Wortd88590f2018-12-12 17:39:58 +0000424{
425 ARM_COMPUTE_UNUSED(op);
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000426 ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src0, src1, dst);
427 ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(*src0, *src1, *dst));
George Wortd88590f2018-12-12 17:39:58 +0000428 return Status{};
giuros0192fd9432018-12-03 17:30:00 +0000429}
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000430
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100431CpuElementwiseKernel::UKernelInfo CpuComparisonKernel::get_implementation(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000432{
433 switch(_op)
434 {
435 case ComparisonOperation::Equal:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000436 return configure_comp_func<ComparisonOperation::Equal>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000437 case ComparisonOperation::NotEqual:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000438 return configure_comp_func<ComparisonOperation::NotEqual>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000439 case ComparisonOperation::Greater:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000440 return configure_comp_func<ComparisonOperation::Greater>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000441 case ComparisonOperation::GreaterEqual:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000442 return configure_comp_func<ComparisonOperation::GreaterEqual>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000443 case ComparisonOperation::Less:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000444 return configure_comp_func<ComparisonOperation::Less>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000445 case ComparisonOperation::LessEqual:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000446 return configure_comp_func<ComparisonOperation::LessEqual>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000447 default:
448 ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
449 }
Georgios Pinitas5fdde992021-06-25 05:42:57 +0100450 return { "", nullptr };
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000451}
452} // namespace kernels
453} // namespace cpu
giuros0192fd9432018-12-03 17:30:00 +0000454} // namespace arm_compute