blob: 23e95f72d7c3638ac2d16e203e33f3433b0e8e60 [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"
27#include "arm_compute/core/IAccessWindow.h"
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010028#include "src/core/CPP/Validate.h"
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000029#include "src/core/common/Registrars.h"
Sang-Hoon Park63001ac2021-01-18 14:20:27 +000030#include "src/core/cpu/kernels/elementwise/neon/elementwise_list.h"
31#include "src/core/cpu/kernels/elementwise/neon/elementwise_quantized_list.h"
32#include "src/core/cpu/kernels/elementwise/sve/elementwise_list.h"
33#include "src/core/cpu/kernels/elementwise/sve/elementwise_quantized_list.h"
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010034#include "src/core/helpers/AutoConfiguration.h"
35#include "src/core/helpers/WindowHelpers.h"
giuros0192fd9432018-12-03 17:30:00 +000036
giuros0192fd9432018-12-03 17:30:00 +000037#include <arm_neon.h>
giuros0192fd9432018-12-03 17:30:00 +000038
39namespace arm_compute
40{
Sang-Hoon Park63001ac2021-01-18 14:20:27 +000041namespace cpu
42{
43namespace kernels
44{
giuros0192fd9432018-12-03 17:30:00 +000045namespace
46{
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000047using ElementwiseSelector = std::add_pointer<bool(DataType)>::type;
Sang-Hoon Park63001ac2021-01-18 14:20:27 +000048using UKernelType = CpuElementwiseKernel::ElementwiseFunction;
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000049struct ElementwiseKernel
giuros0192fd9432018-12-03 17:30:00 +000050{
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000051 const char *name;
52 const ElementwiseSelector is_selected;
53 UKernelType *ukernel;
54};
55
56template <DataType dt>
57inline bool is_selected(DataType data_type)
58{
59 return dt == data_type;
giuros0192fd9432018-12-03 17:30:00 +000060}
61
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000062template <DataType input_data_type, DataType output_data_type = input_data_type>
63static ElementwiseKernel generate_kernel(UKernelType *ukernel)
Michalis Spyrou8d4d1b82019-11-28 11:31:23 +000064{
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000065 std::string kernel_name("op_");
66 kernel_name += string_from_data_type(input_data_type) + "_";
67 kernel_name += string_from_data_type(input_data_type) + "_";
68 kernel_name += string_from_data_type(output_data_type);
Michalis Spyrou8d4d1b82019-11-28 11:31:23 +000069
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000070 return { kernel_name.c_str(), is_selected<input_data_type>, ukernel };
George Wortd88590f2018-12-12 17:39:58 +000071}
72
73template <ArithmeticOperation op>
74std::function<void(const ITensor *, const ITensor *, ITensor *, const Window &)>
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +000075configure_arithm_func(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
George Wortd88590f2018-12-12 17:39:58 +000076{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +000077 ARM_COMPUTE_UNUSED(src1, dst);
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000078 static ElementwiseKernel kernels[] =
George Wortd88590f2018-12-12 17:39:58 +000079 {
Sang-Hoon Park5db75c32021-01-07 16:59:32 +000080#if defined(__ARM_FEATURE_SVE)
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000081 generate_kernel<DataType::F32>(REGISTER_FP32_SVE((arm_compute::cpu::sve::elementwise_arithmetic_op<op, float32_t>))),
82 generate_kernel<DataType::S32>(REGISTER_INTEGER_SVE((arm_compute::cpu::sve::elementwise_arithmetic_op<op, int32_t>))),
Sang-Hoon Park5db75c32021-01-07 16:59:32 +000083#else /* defined(__ARM_FEATURE_SVE) */
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000084 generate_kernel<DataType::F32>(REGISTER_FP32_NEON((arm_compute::cpu::elementwise_arithm_op<op, typename wrapper::traits::neon_vector<float, 4>>))),
85 generate_kernel<DataType::S32>(REGISTER_INTEGER_NEON((arm_compute::cpu::elementwise_arithm_op<op, typename wrapper::traits::neon_vector<int32_t, 4>>))),
Sang-Hoon Park5db75c32021-01-07 16:59:32 +000086#endif /* defined(__ARM_FEATURE_SVE) */
Sang-Hoon Parkd23a2512021-01-11 22:19:49 +000087#if defined(__ARM_FEATURE_SVE2)
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000088 generate_kernel<DataType::QASYMM8>(REGISTER_QASYMM8_SVE((arm_compute::cpu::sve::elementwise_arithmetic_quantized_op<op, uint8_t>))),
89 generate_kernel<DataType::QASYMM8_SIGNED>(REGISTER_QASYMM8_SIGNED_SVE((arm_compute::cpu::sve::elementwise_arithmetic_quantized_op<op, int8_t>))),
Sang-Hoon Parkd23a2512021-01-11 22:19:49 +000090#else /* defined(__ARM_FEATURE_SVE2) */
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000091 generate_kernel<DataType::QASYMM8>(REGISTER_QASYMM8_NEON((arm_compute::cpu::elementwise_arithm_op_quantized<op>))),
92 generate_kernel<DataType::QASYMM8_SIGNED>(REGISTER_QASYMM8_SIGNED_NEON((arm_compute::cpu::elementwise_arithm_op_quantized_signed<op>))),
Sang-Hoon Parkd23a2512021-01-11 22:19:49 +000093#endif /* defined(__ARM_FEATURE_SVE2) */
George Wortd88590f2018-12-12 17:39:58 +000094#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
Sang-Hoon Park5db75c32021-01-07 16:59:32 +000095#if defined(__ARM_FEATURE_SVE)
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000096 generate_kernel<DataType::F16>(REGISTER_FP16_SVE((arm_compute::cpu::sve::elementwise_arithmetic_op<op, float16_t>))),
Sang-Hoon Park5db75c32021-01-07 16:59:32 +000097#else /* defined(__ARM_FEATURE_SVE) */
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000098 generate_kernel<DataType::F16>(REGISTER_FP16_NEON((arm_compute::cpu::elementwise_arithm_op<op, typename wrapper::traits::neon_vector<float16_t, 8>>))),
Sang-Hoon Park5db75c32021-01-07 16:59:32 +000099#endif /* defined(__ARM_FEATURE_SVE) */
George Wortd88590f2018-12-12 17:39:58 +0000100#endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000101 generate_kernel<DataType::S16>(REGISTER_INTEGER_NEON((arm_compute::cpu::elementwise_arithm_op<op, typename wrapper::traits::neon_vector<int16_t, 8>>))),
102 };
George Wortd88590f2018-12-12 17:39:58 +0000103
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000104 for(const auto &uk : kernels)
105 {
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000106 if(uk.is_selected(src0->data_type()))
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000107 {
108 return uk.ukernel;
109 }
110 }
111
112 return nullptr;
George Wortd88590f2018-12-12 17:39:58 +0000113}
114
115template <ComparisonOperation op>
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000116std::function<void(const ITensor *, const ITensor *, ITensor *, const Window &)>
117configure_comp_func(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
George Wortd88590f2018-12-12 17:39:58 +0000118{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000119 ARM_COMPUTE_UNUSED(src1, dst);
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000120 static ElementwiseKernel kernels[] =
George Wortd88590f2018-12-12 17:39:58 +0000121 {
Sang-Hoon Park5db75c32021-01-07 16:59:32 +0000122#if defined(__ARM_FEATURE_SVE)
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000123 generate_kernel<DataType::U8, DataType::U8>(REGISTER_INTEGER_SVE((arm_compute::cpu::sve::elementwise_comparison_op<op, uint8_t>))),
124 generate_kernel<DataType::F32, DataType::U8>(REGISTER_FP32_SVE((arm_compute::cpu::sve::elementwise_comparison_op<op, float>))),
125 generate_kernel<DataType::S16, DataType::U8>(REGISTER_INTEGER_SVE((arm_compute::cpu::sve::elementwise_comparison_op<op, int16_t>))),
126 generate_kernel<DataType::S32, DataType::U8>(REGISTER_INTEGER_SVE((arm_compute::cpu::sve::elementwise_comparison_op<op, int32_t>))),
Sang-Hoon Park5db75c32021-01-07 16:59:32 +0000127#else /* defined(__ARM_FEATURE_SVE) */
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000128 generate_kernel<DataType::U8, DataType::U8>(REGISTER_INTEGER_NEON((arm_compute::cpu::elementwise_comp_op_8<op, uint8_t, uint8x16_t>))),
129 generate_kernel<DataType::F32, DataType::U8>(REGISTER_FP32_NEON((arm_compute::cpu::elementwise_comp_op_32<op, float, float32x4_t>))),
130 generate_kernel<DataType::S16, DataType::U8>(REGISTER_INTEGER_NEON((arm_compute::cpu::elementwise_comp_op_16<op, int16_t, int16x8_t>))),
131 generate_kernel<DataType::S32, DataType::U8>(REGISTER_INTEGER_NEON((arm_compute::cpu::elementwise_comp_op_32<op, int32_t, int32x4_t>))),
Sang-Hoon Park5db75c32021-01-07 16:59:32 +0000132#endif /* defined(__ARM_FEATURE_SVE) */
Sang-Hoon Parkd23a2512021-01-11 22:19:49 +0000133#if defined(__ARM_FEATURE_SVE2)
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000134 generate_kernel<DataType::QASYMM8_SIGNED, DataType::U8>(REGISTER_QASYMM8_SIGNED_SVE((arm_compute::cpu::sve::elementwise_comparison_quantized_op<op, int8_t>))),
135 generate_kernel<DataType::QASYMM8, DataType::U8>(REGISTER_QASYMM8_SVE((arm_compute::cpu::sve::elementwise_comparison_quantized_op<op, uint8_t>))),
Sang-Hoon Parkd23a2512021-01-11 22:19:49 +0000136#else /* defined(__ARM_FEATURE_SVE2) */
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000137 generate_kernel<DataType::QASYMM8_SIGNED, DataType::U8>(REGISTER_QASYMM8_SIGNED_NEON((arm_compute::cpu::elementwise_comp_op_quantized_signed<op>))),
138 generate_kernel<DataType::QASYMM8, DataType::U8>(REGISTER_QASYMM8_NEON((arm_compute::cpu::elementwise_comp_op_quantized<op>))),
Sang-Hoon Parkd23a2512021-01-11 22:19:49 +0000139#endif /* defined(__ARM_FEATURE_SVE2) */
George Wortd88590f2018-12-12 17:39:58 +0000140#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
Sang-Hoon Park5db75c32021-01-07 16:59:32 +0000141#if defined(__ARM_FEATURE_SVE)
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000142 generate_kernel<DataType::F16, DataType::U8>(REGISTER_FP16_SVE((arm_compute::cpu::sve::elementwise_comparison_op<op, float16_t>))),
Sang-Hoon Park5db75c32021-01-07 16:59:32 +0000143#else /* defined(__ARM_FEATURE_SVE) */
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000144 generate_kernel<DataType::F16, DataType::U8>(REGISTER_FP16_NEON((arm_compute::cpu::elementwise_comp_op_16<op, float16_t, float16x8_t>))),
Sang-Hoon Park5db75c32021-01-07 16:59:32 +0000145#endif /* defined(__ARM_FEATURE_SVE) */
George Wortd88590f2018-12-12 17:39:58 +0000146#endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000147 };
George Wortd88590f2018-12-12 17:39:58 +0000148
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000149 for(const auto &uk : kernels)
150 {
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000151 if(uk.is_selected(src0->data_type()))
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000152 {
153 return uk.ukernel;
154 }
155 }
156
157 return nullptr;
George Wortd88590f2018-12-12 17:39:58 +0000158}
159} // namespace
160
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000161Status CpuElementwiseKernel::validate_arguments_common(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst)
George Wortd88590f2018-12-12 17:39:58 +0000162{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000163 ARM_COMPUTE_RETURN_ERROR_ON_CPU_F16_UNSUPPORTED(&src0);
164 ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(&src0, &src1);
giuros0192fd9432018-12-03 17:30:00 +0000165
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000166 const TensorShape out_shape = TensorShape::broadcast_shape(src0.tensor_shape(), src1.tensor_shape());
giuros0192fd9432018-12-03 17:30:00 +0000167
168 ARM_COMPUTE_RETURN_ERROR_ON_MSG(out_shape.total_size() == 0, "Inputs are not broadcast compatible");
169
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000170 // Validate in case of configured dst
171 if(dst.total_size() > 0)
giuros0192fd9432018-12-03 17:30:00 +0000172 {
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000173 ARM_COMPUTE_RETURN_ERROR_ON_MSG(detail::have_different_dimensions(out_shape, dst.tensor_shape(), 0),
giuros0192fd9432018-12-03 17:30:00 +0000174 "Wrong shape for output");
175 }
176
177 return Status{};
178}
giuros0192fd9432018-12-03 17:30:00 +0000179
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000180void CpuElementwiseKernel::configure_common(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
giuros0192fd9432018-12-03 17:30:00 +0000181{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000182 ARM_COMPUTE_ERROR_ON_NULLPTR(src0, src1, dst);
giuros0192fd9432018-12-03 17:30:00 +0000183
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000184 // If any of shapes is dynamic, expect a configured window and dst at run-time.
185 if(src0->is_dynamic() || src1->is_dynamic())
186 {
187 return;
188 }
giuros0192fd9432018-12-03 17:30:00 +0000189
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000190 auto shape_and_window = compute_output_shape_and_window(*src0, *src1);
191 auto_init_if_empty(*dst, shape_and_window.first, 1, src0->data_type());
192 ICpuKernel::configure(shape_and_window.second);
giuros0192fd9432018-12-03 17:30:00 +0000193}
194
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000195void CpuElementwiseKernel::run_op(ITensorPack &tensors, const Window &window, const ThreadInfo &info)
giuros0192fd9432018-12-03 17:30:00 +0000196{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000197 ARM_COMPUTE_UNUSED(info);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000198
199 auto src0 = tensors.get_const_tensor(TensorType::ACL_SRC_0);
200 auto src1 = tensors.get_const_tensor(TensorType::ACL_SRC_1);
201 auto dst = tensors.get_tensor(TensorType::ACL_DST);
202
203 auto function = get_implementation(src0->info(), src1->info(), dst->info());
204 ARM_COMPUTE_ERROR_ON(function == nullptr);
205 function(src0, src1, dst, window);
giuros0192fd9432018-12-03 17:30:00 +0000206}
207
208/** Arithmetic operators (min, max, squared_diff) */
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000209void CpuArithmeticKernel::configure(ArithmeticOperation op, const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
giuros0192fd9432018-12-03 17:30:00 +0000210{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000211 ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*src0, *src1, *dst));
212 configure_common(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000213 _op = op;
giuros0192fd9432018-12-03 17:30:00 +0000214}
215
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000216Status CpuArithmeticKernel::validate_arguments(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst)
George Wortd88590f2018-12-12 17:39:58 +0000217{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000218 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);
219 // Validate in case of configured dst
220 if(dst.total_size() > 0)
George Wortd88590f2018-12-12 17:39:58 +0000221 {
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000222 ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(&src0, &dst);
George Wortd88590f2018-12-12 17:39:58 +0000223 }
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000224 return validate_arguments_common(src0, src1, dst);
George Wortd88590f2018-12-12 17:39:58 +0000225}
226
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000227Status CpuArithmeticKernel::validate(ArithmeticOperation op, const ITensorInfo *src0, const ITensorInfo *src1, const ITensorInfo *dst)
giuros0192fd9432018-12-03 17:30:00 +0000228{
229 ARM_COMPUTE_UNUSED(op);
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000230 ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src0, src1, dst);
231 ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(*src0, *src1, *dst));
giuros0192fd9432018-12-03 17:30:00 +0000232 return Status{};
233}
234
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000235std::function<CpuElementwiseKernel::ElementwiseFunction>
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000236CpuArithmeticKernel::get_implementation(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000237{
238 switch(_op)
239 {
240 case ArithmeticOperation::MAX:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000241 return configure_arithm_func<ArithmeticOperation::MAX>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000242 case ArithmeticOperation::MIN:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000243 return configure_arithm_func<ArithmeticOperation::MIN>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000244 case ArithmeticOperation::SQUARED_DIFF:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000245 return configure_arithm_func<ArithmeticOperation::SQUARED_DIFF>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000246 case ArithmeticOperation::PRELU:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000247 return configure_arithm_func<ArithmeticOperation::PRELU>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000248 case ArithmeticOperation::DIV:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000249 return configure_arithm_func<ArithmeticOperation::DIV>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000250 case ArithmeticOperation::POWER:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000251 return configure_arithm_func<ArithmeticOperation::POWER>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000252 default:
253 ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
254 }
255 return nullptr;
256}
257
George Worta1e7e282019-01-15 11:00:29 +0000258/** The division operator */
259
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000260void CpuDivisionKernel::configure(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
George Worta1e7e282019-01-15 11:00:29 +0000261{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000262 ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*src0, *src1, *dst));
263 configure_common(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000264 _op = ArithmeticOperation::DIV;
George Worta1e7e282019-01-15 11:00:29 +0000265}
266
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000267Status CpuDivisionKernel::validate_arguments(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst)
George Worta1e7e282019-01-15 11:00:29 +0000268{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000269 ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&src0, 1, DataType::S32, DataType::F16, DataType::F32);
270 return CpuArithmeticKernel::validate_arguments(src0, src1, dst);
George Worta1e7e282019-01-15 11:00:29 +0000271}
272
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000273Status CpuDivisionKernel::validate(const ITensorInfo *src0, const ITensorInfo *src1, const ITensorInfo *dst)
George Worta1e7e282019-01-15 11:00:29 +0000274{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000275 ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src0, src1, dst);
276 ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(*src0, *src1, *dst));
George Worta1e7e282019-01-15 11:00:29 +0000277 return Status{};
278}
279
Usama Arif81e671e2019-05-13 13:33:14 +0100280/** The power operator */
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000281void CpuPowerKernel::configure(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
Usama Arif81e671e2019-05-13 13:33:14 +0100282{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000283 ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*src0, *src1, *dst));
284 configure_common(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000285 _op = ArithmeticOperation::POWER;
Usama Arif81e671e2019-05-13 13:33:14 +0100286}
287
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000288Status CpuPowerKernel::validate_arguments(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst)
Usama Arif81e671e2019-05-13 13:33:14 +0100289{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000290 ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&src0, 1, DataType::F16, DataType::F32);
291 return CpuArithmeticKernel::validate_arguments(src0, src1, dst);
Usama Arif81e671e2019-05-13 13:33:14 +0100292}
293
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000294Status CpuPowerKernel::validate(const ITensorInfo *src0, const ITensorInfo *src1, const ITensorInfo *dst)
Usama Arif81e671e2019-05-13 13:33:14 +0100295{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000296 ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src0, src1, dst);
297 ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(*src0, *src1, *dst));
Usama Arif81e671e2019-05-13 13:33:14 +0100298 return Status{};
299}
300
George Wortd88590f2018-12-12 17:39:58 +0000301/** 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 +0000302void CpuComparisonKernel::configure(ComparisonOperation op, const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
giuros0192fd9432018-12-03 17:30:00 +0000303{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000304 ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*src0, *src1, *dst));
305 configure_common(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000306 _op = op;
George Wortd88590f2018-12-12 17:39:58 +0000307}
308
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000309Status CpuComparisonKernel::validate_arguments(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst)
George Wortd88590f2018-12-12 17:39:58 +0000310{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000311 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);
312 // Validate in case of configured dst
313 if(dst.total_size() > 0)
George Wortd88590f2018-12-12 17:39:58 +0000314 {
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000315 ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&dst, 1, DataType::U8);
George Wortd88590f2018-12-12 17:39:58 +0000316 }
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000317 return validate_arguments_common(src0, src1, dst);
George Wortd88590f2018-12-12 17:39:58 +0000318}
319
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000320Status CpuComparisonKernel::validate(ComparisonOperation op, const ITensorInfo *src0, const ITensorInfo *src1, const ITensorInfo *dst)
George Wortd88590f2018-12-12 17:39:58 +0000321{
322 ARM_COMPUTE_UNUSED(op);
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000323 ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src0, src1, dst);
324 ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(*src0, *src1, *dst));
George Wortd88590f2018-12-12 17:39:58 +0000325 return Status{};
giuros0192fd9432018-12-03 17:30:00 +0000326}
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000327
328std::function<CpuElementwiseKernel::ElementwiseFunction>
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000329CpuComparisonKernel::get_implementation(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000330{
331 switch(_op)
332 {
333 case ComparisonOperation::Equal:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000334 return configure_comp_func<ComparisonOperation::Equal>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000335 case ComparisonOperation::NotEqual:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000336 return configure_comp_func<ComparisonOperation::NotEqual>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000337 case ComparisonOperation::Greater:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000338 return configure_comp_func<ComparisonOperation::Greater>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000339 case ComparisonOperation::GreaterEqual:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000340 return configure_comp_func<ComparisonOperation::GreaterEqual>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000341 case ComparisonOperation::Less:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000342 return configure_comp_func<ComparisonOperation::Less>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000343 case ComparisonOperation::LessEqual:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000344 return configure_comp_func<ComparisonOperation::LessEqual>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000345 default:
346 ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
347 }
348 return nullptr;
349}
350} // namespace kernels
351} // namespace cpu
giuros0192fd9432018-12-03 17:30:00 +0000352} // namespace arm_compute