blob: ddbc48feb897c568ed21324a43771c4d07ad688e [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{
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000046using ElementwiseSelector = std::add_pointer<bool(DataType)>::type;
Sang-Hoon Park63001ac2021-01-18 14:20:27 +000047using UKernelType = CpuElementwiseKernel::ElementwiseFunction;
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000048struct ElementwiseKernel
giuros0192fd9432018-12-03 17:30:00 +000049{
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000050 const char *name;
51 const ElementwiseSelector is_selected;
52 UKernelType *ukernel;
53};
54
55template <DataType dt>
56inline bool is_selected(DataType data_type)
57{
58 return dt == data_type;
giuros0192fd9432018-12-03 17:30:00 +000059}
60
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000061template <DataType input_data_type, DataType output_data_type = input_data_type>
62static ElementwiseKernel generate_kernel(UKernelType *ukernel)
Michalis Spyrou8d4d1b82019-11-28 11:31:23 +000063{
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000064 std::string kernel_name("op_");
65 kernel_name += string_from_data_type(input_data_type) + "_";
66 kernel_name += string_from_data_type(input_data_type) + "_";
67 kernel_name += string_from_data_type(output_data_type);
Michalis Spyrou8d4d1b82019-11-28 11:31:23 +000068
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000069 return { kernel_name.c_str(), is_selected<input_data_type>, ukernel };
George Wortd88590f2018-12-12 17:39:58 +000070}
71
72template <ArithmeticOperation op>
73std::function<void(const ITensor *, const ITensor *, ITensor *, const Window &)>
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +000074configure_arithm_func(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
George Wortd88590f2018-12-12 17:39:58 +000075{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +000076 ARM_COMPUTE_UNUSED(src1, dst);
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000077 static ElementwiseKernel kernels[] =
George Wortd88590f2018-12-12 17:39:58 +000078 {
Sang-Hoon Park5db75c32021-01-07 16:59:32 +000079#if defined(__ARM_FEATURE_SVE)
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000080 generate_kernel<DataType::F32>(REGISTER_FP32_SVE((arm_compute::cpu::sve::elementwise_arithmetic_op<op, float32_t>))),
81 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 +000082#else /* defined(__ARM_FEATURE_SVE) */
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000083 generate_kernel<DataType::F32>(REGISTER_FP32_NEON((arm_compute::cpu::elementwise_arithm_op<op, typename wrapper::traits::neon_vector<float, 4>>))),
84 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 +000085#endif /* defined(__ARM_FEATURE_SVE) */
Sang-Hoon Parkd23a2512021-01-11 22:19:49 +000086#if defined(__ARM_FEATURE_SVE2)
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000087 generate_kernel<DataType::QASYMM8>(REGISTER_QASYMM8_SVE((arm_compute::cpu::sve::elementwise_arithmetic_quantized_op<op, uint8_t>))),
88 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 +000089#else /* defined(__ARM_FEATURE_SVE2) */
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000090 generate_kernel<DataType::QASYMM8>(REGISTER_QASYMM8_NEON((arm_compute::cpu::elementwise_arithm_op_quantized<op>))),
91 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 +000092#endif /* defined(__ARM_FEATURE_SVE2) */
George Wortd88590f2018-12-12 17:39:58 +000093#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
Sang-Hoon Park5db75c32021-01-07 16:59:32 +000094#if defined(__ARM_FEATURE_SVE)
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000095 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 +000096#else /* defined(__ARM_FEATURE_SVE) */
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +000097 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 +000098#endif /* defined(__ARM_FEATURE_SVE) */
George Wortd88590f2018-12-12 17:39:58 +000099#endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000100 generate_kernel<DataType::S16>(REGISTER_INTEGER_NEON((arm_compute::cpu::elementwise_arithm_op<op, typename wrapper::traits::neon_vector<int16_t, 8>>))),
101 };
George Wortd88590f2018-12-12 17:39:58 +0000102
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000103 for(const auto &uk : kernels)
104 {
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000105 if(uk.is_selected(src0->data_type()))
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000106 {
107 return uk.ukernel;
108 }
109 }
110
111 return nullptr;
George Wortd88590f2018-12-12 17:39:58 +0000112}
113
114template <ComparisonOperation op>
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000115std::function<void(const ITensor *, const ITensor *, ITensor *, const Window &)>
116configure_comp_func(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
George Wortd88590f2018-12-12 17:39:58 +0000117{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000118 ARM_COMPUTE_UNUSED(src1, dst);
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000119 static ElementwiseKernel kernels[] =
George Wortd88590f2018-12-12 17:39:58 +0000120 {
Sang-Hoon Park5db75c32021-01-07 16:59:32 +0000121#if defined(__ARM_FEATURE_SVE)
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000122 generate_kernel<DataType::U8, DataType::U8>(REGISTER_INTEGER_SVE((arm_compute::cpu::sve::elementwise_comparison_op<op, uint8_t>))),
123 generate_kernel<DataType::F32, DataType::U8>(REGISTER_FP32_SVE((arm_compute::cpu::sve::elementwise_comparison_op<op, float>))),
124 generate_kernel<DataType::S16, DataType::U8>(REGISTER_INTEGER_SVE((arm_compute::cpu::sve::elementwise_comparison_op<op, int16_t>))),
125 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 +0000126#else /* defined(__ARM_FEATURE_SVE) */
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000127 generate_kernel<DataType::U8, DataType::U8>(REGISTER_INTEGER_NEON((arm_compute::cpu::elementwise_comp_op_8<op, uint8_t, uint8x16_t>))),
128 generate_kernel<DataType::F32, DataType::U8>(REGISTER_FP32_NEON((arm_compute::cpu::elementwise_comp_op_32<op, float, float32x4_t>))),
129 generate_kernel<DataType::S16, DataType::U8>(REGISTER_INTEGER_NEON((arm_compute::cpu::elementwise_comp_op_16<op, int16_t, int16x8_t>))),
130 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 +0000131#endif /* defined(__ARM_FEATURE_SVE) */
Sang-Hoon Parkd23a2512021-01-11 22:19:49 +0000132#if defined(__ARM_FEATURE_SVE2)
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000133 generate_kernel<DataType::QASYMM8_SIGNED, DataType::U8>(REGISTER_QASYMM8_SIGNED_SVE((arm_compute::cpu::sve::elementwise_comparison_quantized_op<op, int8_t>))),
134 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 +0000135#else /* defined(__ARM_FEATURE_SVE2) */
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000136 generate_kernel<DataType::QASYMM8_SIGNED, DataType::U8>(REGISTER_QASYMM8_SIGNED_NEON((arm_compute::cpu::elementwise_comp_op_quantized_signed<op>))),
137 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 +0000138#endif /* defined(__ARM_FEATURE_SVE2) */
George Wortd88590f2018-12-12 17:39:58 +0000139#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
Sang-Hoon Park5db75c32021-01-07 16:59:32 +0000140#if defined(__ARM_FEATURE_SVE)
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000141 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 +0000142#else /* defined(__ARM_FEATURE_SVE) */
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000143 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 +0000144#endif /* defined(__ARM_FEATURE_SVE) */
George Wortd88590f2018-12-12 17:39:58 +0000145#endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000146 };
George Wortd88590f2018-12-12 17:39:58 +0000147
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000148 for(const auto &uk : kernels)
149 {
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000150 if(uk.is_selected(src0->data_type()))
Sang-Hoon Parkd2447bb2021-01-18 09:41:37 +0000151 {
152 return uk.ukernel;
153 }
154 }
155
156 return nullptr;
George Wortd88590f2018-12-12 17:39:58 +0000157}
158} // namespace
159
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000160Status CpuElementwiseKernel::validate_arguments_common(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst)
George Wortd88590f2018-12-12 17:39:58 +0000161{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000162 ARM_COMPUTE_RETURN_ERROR_ON_CPU_F16_UNSUPPORTED(&src0);
163 ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(&src0, &src1);
giuros0192fd9432018-12-03 17:30:00 +0000164
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000165 const TensorShape out_shape = TensorShape::broadcast_shape(src0.tensor_shape(), src1.tensor_shape());
giuros0192fd9432018-12-03 17:30:00 +0000166
167 ARM_COMPUTE_RETURN_ERROR_ON_MSG(out_shape.total_size() == 0, "Inputs are not broadcast compatible");
168
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000169 // Validate in case of configured dst
170 if(dst.total_size() > 0)
giuros0192fd9432018-12-03 17:30:00 +0000171 {
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000172 ARM_COMPUTE_RETURN_ERROR_ON_MSG(detail::have_different_dimensions(out_shape, dst.tensor_shape(), 0),
giuros0192fd9432018-12-03 17:30:00 +0000173 "Wrong shape for output");
174 }
175
176 return Status{};
177}
giuros0192fd9432018-12-03 17:30:00 +0000178
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000179void CpuElementwiseKernel::configure_common(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
giuros0192fd9432018-12-03 17:30:00 +0000180{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000181 ARM_COMPUTE_ERROR_ON_NULLPTR(src0, src1, dst);
giuros0192fd9432018-12-03 17:30:00 +0000182
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000183 // If any of shapes is dynamic, expect a configured window and dst at run-time.
184 if(src0->is_dynamic() || src1->is_dynamic())
185 {
186 return;
187 }
giuros0192fd9432018-12-03 17:30:00 +0000188
Sang-Hoon Parkd0b7b4b2021-03-09 10:47:30 +0000189 auto shape_and_window = compute_output_shape_and_window(src0->tensor_shape(), src1->tensor_shape());
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000190 auto_init_if_empty(*dst, shape_and_window.first, 1, src0->data_type());
191 ICpuKernel::configure(shape_and_window.second);
giuros0192fd9432018-12-03 17:30:00 +0000192}
193
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000194void CpuElementwiseKernel::run_op(ITensorPack &tensors, const Window &window, const ThreadInfo &info)
giuros0192fd9432018-12-03 17:30:00 +0000195{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000196 ARM_COMPUTE_UNUSED(info);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000197
198 auto src0 = tensors.get_const_tensor(TensorType::ACL_SRC_0);
199 auto src1 = tensors.get_const_tensor(TensorType::ACL_SRC_1);
200 auto dst = tensors.get_tensor(TensorType::ACL_DST);
201
202 auto function = get_implementation(src0->info(), src1->info(), dst->info());
203 ARM_COMPUTE_ERROR_ON(function == nullptr);
204 function(src0, src1, dst, window);
giuros0192fd9432018-12-03 17:30:00 +0000205}
206
207/** Arithmetic operators (min, max, squared_diff) */
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000208void CpuArithmeticKernel::configure(ArithmeticOperation op, const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
giuros0192fd9432018-12-03 17:30:00 +0000209{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000210 ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*src0, *src1, *dst));
211 configure_common(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000212 _op = op;
giuros0192fd9432018-12-03 17:30:00 +0000213}
214
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000215Status CpuArithmeticKernel::validate_arguments(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst)
George Wortd88590f2018-12-12 17:39:58 +0000216{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000217 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);
218 // Validate in case of configured dst
219 if(dst.total_size() > 0)
George Wortd88590f2018-12-12 17:39:58 +0000220 {
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000221 ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(&src0, &dst);
George Wortd88590f2018-12-12 17:39:58 +0000222 }
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000223 return validate_arguments_common(src0, src1, dst);
George Wortd88590f2018-12-12 17:39:58 +0000224}
225
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000226Status CpuArithmeticKernel::validate(ArithmeticOperation op, const ITensorInfo *src0, const ITensorInfo *src1, const ITensorInfo *dst)
giuros0192fd9432018-12-03 17:30:00 +0000227{
228 ARM_COMPUTE_UNUSED(op);
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000229 ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src0, src1, dst);
230 ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(*src0, *src1, *dst));
giuros0192fd9432018-12-03 17:30:00 +0000231 return Status{};
232}
233
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000234std::function<CpuElementwiseKernel::ElementwiseFunction>
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000235CpuArithmeticKernel::get_implementation(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000236{
237 switch(_op)
238 {
239 case ArithmeticOperation::MAX:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000240 return configure_arithm_func<ArithmeticOperation::MAX>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000241 case ArithmeticOperation::MIN:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000242 return configure_arithm_func<ArithmeticOperation::MIN>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000243 case ArithmeticOperation::SQUARED_DIFF:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000244 return configure_arithm_func<ArithmeticOperation::SQUARED_DIFF>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000245 case ArithmeticOperation::PRELU:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000246 return configure_arithm_func<ArithmeticOperation::PRELU>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000247 case ArithmeticOperation::DIV:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000248 return configure_arithm_func<ArithmeticOperation::DIV>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000249 case ArithmeticOperation::POWER:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000250 return configure_arithm_func<ArithmeticOperation::POWER>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000251 default:
252 ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
253 }
254 return nullptr;
255}
256
George Worta1e7e282019-01-15 11:00:29 +0000257/** The division operator */
258
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000259void CpuDivisionKernel::configure(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
George Worta1e7e282019-01-15 11:00:29 +0000260{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000261 ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*src0, *src1, *dst));
262 configure_common(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000263 _op = ArithmeticOperation::DIV;
George Worta1e7e282019-01-15 11:00:29 +0000264}
265
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000266Status CpuDivisionKernel::validate_arguments(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst)
George Worta1e7e282019-01-15 11:00:29 +0000267{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000268 ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&src0, 1, DataType::S32, DataType::F16, DataType::F32);
269 return CpuArithmeticKernel::validate_arguments(src0, src1, dst);
George Worta1e7e282019-01-15 11:00:29 +0000270}
271
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000272Status CpuDivisionKernel::validate(const ITensorInfo *src0, const ITensorInfo *src1, const ITensorInfo *dst)
George Worta1e7e282019-01-15 11:00:29 +0000273{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000274 ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src0, src1, dst);
275 ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(*src0, *src1, *dst));
George Worta1e7e282019-01-15 11:00:29 +0000276 return Status{};
277}
278
Usama Arif81e671e2019-05-13 13:33:14 +0100279/** The power operator */
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000280void CpuPowerKernel::configure(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
Usama Arif81e671e2019-05-13 13:33:14 +0100281{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000282 ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*src0, *src1, *dst));
283 configure_common(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000284 _op = ArithmeticOperation::POWER;
Usama Arif81e671e2019-05-13 13:33:14 +0100285}
286
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000287Status CpuPowerKernel::validate_arguments(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst)
Usama Arif81e671e2019-05-13 13:33:14 +0100288{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000289 ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&src0, 1, DataType::F16, DataType::F32);
290 return CpuArithmeticKernel::validate_arguments(src0, src1, dst);
Usama Arif81e671e2019-05-13 13:33:14 +0100291}
292
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000293Status CpuPowerKernel::validate(const ITensorInfo *src0, const ITensorInfo *src1, const ITensorInfo *dst)
Usama Arif81e671e2019-05-13 13:33:14 +0100294{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000295 ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src0, src1, dst);
296 ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(*src0, *src1, *dst));
Usama Arif81e671e2019-05-13 13:33:14 +0100297 return Status{};
298}
299
George Wortd88590f2018-12-12 17:39:58 +0000300/** 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 +0000301void CpuComparisonKernel::configure(ComparisonOperation op, const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
giuros0192fd9432018-12-03 17:30:00 +0000302{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000303 ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*src0, *src1, *dst));
304 configure_common(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000305 _op = op;
George Wortd88590f2018-12-12 17:39:58 +0000306}
307
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000308Status CpuComparisonKernel::validate_arguments(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst)
George Wortd88590f2018-12-12 17:39:58 +0000309{
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000310 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);
311 // Validate in case of configured dst
312 if(dst.total_size() > 0)
George Wortd88590f2018-12-12 17:39:58 +0000313 {
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000314 ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&dst, 1, DataType::U8);
George Wortd88590f2018-12-12 17:39:58 +0000315 }
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000316 return validate_arguments_common(src0, src1, dst);
George Wortd88590f2018-12-12 17:39:58 +0000317}
318
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000319Status CpuComparisonKernel::validate(ComparisonOperation op, const ITensorInfo *src0, const ITensorInfo *src1, const ITensorInfo *dst)
George Wortd88590f2018-12-12 17:39:58 +0000320{
321 ARM_COMPUTE_UNUSED(op);
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000322 ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src0, src1, dst);
323 ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(*src0, *src1, *dst));
George Wortd88590f2018-12-12 17:39:58 +0000324 return Status{};
giuros0192fd9432018-12-03 17:30:00 +0000325}
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000326
327std::function<CpuElementwiseKernel::ElementwiseFunction>
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000328CpuComparisonKernel::get_implementation(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst)
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000329{
330 switch(_op)
331 {
332 case ComparisonOperation::Equal:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000333 return configure_comp_func<ComparisonOperation::Equal>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000334 case ComparisonOperation::NotEqual:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000335 return configure_comp_func<ComparisonOperation::NotEqual>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000336 case ComparisonOperation::Greater:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000337 return configure_comp_func<ComparisonOperation::Greater>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000338 case ComparisonOperation::GreaterEqual:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000339 return configure_comp_func<ComparisonOperation::GreaterEqual>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000340 case ComparisonOperation::Less:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000341 return configure_comp_func<ComparisonOperation::Less>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000342 case ComparisonOperation::LessEqual:
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000343 return configure_comp_func<ComparisonOperation::LessEqual>(src0, src1, dst);
Sang-Hoon Park63001ac2021-01-18 14:20:27 +0000344 default:
345 ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
346 }
347 return nullptr;
348}
349} // namespace kernels
350} // namespace cpu
giuros0192fd9432018-12-03 17:30:00 +0000351} // namespace arm_compute