From c386bcea2612b3bacdf34352210fd52ad068cd01 Mon Sep 17 00:00:00 2001 From: Evgenii Maltsev Date: Fri, 7 Jun 2024 17:11:52 +0400 Subject: [PATCH] [onert-micro] This PR adds Minimum kernel (#13126) Kernels support. Support for the Minimum kernel for the [issue](https://github.com/Samsung/ONE/issues/12427) ONE-DCO-1.0-Signed-off-by: Evgenii Maltsev e.maltsev@samsung.com --- .../include/pal/common/PALMinimumCommon.h | 52 ++++++ .../include/pal/mcu/KernelsToBuild.lst | 2 +- .../onert-micro/include/pal/mcu/PALMinimum.h | 23 +++ .../test_models/minimum/FloatMinimumKernel.h | 153 ++++++++++++++++++ .../test_models/minimum/NegMinimumKernel.h | 147 +++++++++++++++++ .../test_models/minimum/TestDataMinimumBase.h | 68 ++++++++ .../src/execute/kernels/Minimum.cpp | 107 ++++++++++++ .../execute/kernels/tests/Minimum.test.cpp | 77 +++++++++ .../src/import/kernels/Minimum.cpp | 63 ++++++++ 9 files changed, 691 insertions(+), 1 deletion(-) create mode 100644 onert-micro/onert-micro/include/pal/common/PALMinimumCommon.h create mode 100644 onert-micro/onert-micro/include/pal/mcu/PALMinimum.h create mode 100644 onert-micro/onert-micro/include/test_models/minimum/FloatMinimumKernel.h create mode 100644 onert-micro/onert-micro/include/test_models/minimum/NegMinimumKernel.h create mode 100644 onert-micro/onert-micro/include/test_models/minimum/TestDataMinimumBase.h create mode 100644 onert-micro/onert-micro/src/execute/kernels/Minimum.cpp create mode 100644 onert-micro/onert-micro/src/execute/kernels/tests/Minimum.test.cpp create mode 100644 onert-micro/onert-micro/src/import/kernels/Minimum.cpp diff --git a/onert-micro/onert-micro/include/pal/common/PALMinimumCommon.h b/onert-micro/onert-micro/include/pal/common/PALMinimumCommon.h new file mode 100644 index 00000000000..697c6a51775 --- /dev/null +++ b/onert-micro/onert-micro/include/pal/common/PALMinimumCommon.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ONERT_MICRO_PAL_MINIMUM_COMMON_H +#define ONERT_MICRO_PAL_MINIMUM_COMMON_H + +#include "PALBinaryOpCommon.h" +#include "OMStatus.h" +#include "core/OMRuntimeShape.h" + +namespace onert_micro +{ +namespace execute +{ +namespace pal +{ + +inline OMStatus Minimum(const int flat_size, const float *input1_data, const float *input2_data, + float *output_data) +{ + return BinaryOp>(flat_size, input1_data, input2_data, output_data); +} + +template +inline OMStatus +BroadcastMinimum4DSlow(const core::OMRuntimeShape &input1_shape, const T *input1_data, + const core::OMRuntimeShape &input2_shape, const T *input2_data, + const core::OMRuntimeShape &output_shape, T *output_data) +{ + return BroadcastBinaryOp4DSlow>(input1_shape, input1_data, input2_shape, + input2_data, output_shape, output_data); +} + +} // namespace pal +} // namespace execute +} // namespace onert_micro + +#endif // ONERT_MICRO_PAL_MINIMUM_COMMON_H diff --git a/onert-micro/onert-micro/include/pal/mcu/KernelsToBuild.lst b/onert-micro/onert-micro/include/pal/mcu/KernelsToBuild.lst index 85090a4639c..b718f804705 100644 --- a/onert-micro/onert-micro/include/pal/mcu/KernelsToBuild.lst +++ b/onert-micro/onert-micro/include/pal/mcu/KernelsToBuild.lst @@ -54,7 +54,7 @@ REGISTER_KERNEL(MUL, Mul) REGISTER_KERNEL(MAXIMUM, Maximum) #/*REGISTER_KERNEL(MEAN, Mean)*/ REGISTER_KERNEL(MAX_POOL_2D, MaxPool2D) -#/*REGISTER_KERNEL(MINIMUM, Minimum)*/ +REGISTER_KERNEL(MINIMUM, Minimum) #/*REGISTER_KERNEL(SHAPE, Shape)*/ REGISTER_KERNEL(NOT_EQUAL, NotEqual) REGISTER_KERNEL(SIN, Sin) diff --git a/onert-micro/onert-micro/include/pal/mcu/PALMinimum.h b/onert-micro/onert-micro/include/pal/mcu/PALMinimum.h new file mode 100644 index 00000000000..80d55601923 --- /dev/null +++ b/onert-micro/onert-micro/include/pal/mcu/PALMinimum.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ONERT_MICRO_PAL_MINIMUM_H +#define ONERT_MICRO_PAL_MINIMUM_H + +#include "PALMinimumCommon.h" + +#endif // ONERT_MICRO_PAL_MINIMUM_H diff --git a/onert-micro/onert-micro/include/test_models/minimum/FloatMinimumKernel.h b/onert-micro/onert-micro/include/test_models/minimum/FloatMinimumKernel.h new file mode 100644 index 00000000000..a320572450e --- /dev/null +++ b/onert-micro/onert-micro/include/test_models/minimum/FloatMinimumKernel.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ONERT_MICRO_TEST_MODELS_MINIMUM_KERNEL_FLOAT_H +#define ONERT_MICRO_TEST_MODELS_MINIMUM_KERNEL_FLOAT_H + +#include "TestDataMinimumBase.h" + +namespace onert_micro +{ +namespace test_model +{ +namespace minimum_float_with_broadcasting +{ + +/* + * Minimum Kernel: + * + * Input_1(2, 5) Input_2(2, 1) + * \ / + * Minimum(with broadcast) + * | + * Output(2, 5) + */ +const unsigned char test_kernel_model_circle[] = { + 0x18, 0x00, 0x00, 0x00, 0x43, 0x49, 0x52, 0x30, 0x00, 0x00, 0x0e, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x08, 0x00, 0x10, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x54, 0x01, 0x00, 0x00, 0x70, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x88, 0xff, 0xff, 0xff, 0x8c, 0xff, 0xff, 0xff, 0x90, 0xff, 0xff, 0xff, 0x94, 0xff, 0xff, 0xff, + 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x14, 0x00, + 0x10, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0c, 0x00, + 0x07, 0x00, 0x08, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x10, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xb4, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x6f, 0x66, 0x6d, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xd8, 0xff, 0xff, 0xff, + 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x69, 0x66, 0x6d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x69, 0x66, 0x6d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x0c, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x11, 0x00, 0x00, 0x00, 0x4f, 0x4e, 0x45, 0x2d, + 0x74, 0x66, 0x6c, 0x69, 0x74, 0x65, 0x32, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x00, 0x00, 0x00}; + +const std::vector input1_data = {3.9078786, 4.825119, -6.9444265, 0.5244622, -5.321703, + -9.686515, -1.3499693, -5.8468533, -0.5371767, 8.364615}; +const std::vector input2_data = {-7.73631, 1.0758704}; +const std::vector reference_output_data = {-7.73631, -7.73631, -7.73631, -7.73631, + -7.73631, -9.686515, -1.3499693, -5.8468533, + -0.5371767, 1.0758704}; + +} // namespace minimum_float_with_broadcasting + +namespace minimum_float_no_broadcasting +{ +/* + * Minimum Kernel: + * + * Input_1(2, 3) Input_2(2, 3) + * \ / + * Minimum(no broadcast) + * | + * Output(2, 3) + */ +const unsigned char test_kernel_model_circle[] = { + 0x18, 0x00, 0x00, 0x00, 0x43, 0x49, 0x52, 0x30, 0x00, 0x00, 0x0e, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x08, 0x00, 0x10, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x54, 0x01, 0x00, 0x00, 0x70, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x88, 0xff, 0xff, 0xff, 0x8c, 0xff, 0xff, 0xff, 0x90, 0xff, 0xff, 0xff, 0x94, 0xff, 0xff, 0xff, + 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x14, 0x00, + 0x10, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0c, 0x00, + 0x07, 0x00, 0x08, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x10, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xb4, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x6f, 0x66, 0x6d, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xd8, 0xff, 0xff, 0xff, + 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x69, 0x66, 0x6d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x69, 0x66, 0x6d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x0c, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x11, 0x00, 0x00, 0x00, 0x4f, 0x4e, 0x45, 0x2d, + 0x74, 0x66, 0x6c, 0x69, 0x74, 0x65, 0x32, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x00, 0x00, 0x00}; + +std::vector input1_data = {7.1328354, -3.694989, -7.1043596, + -7.4285483, -7.1077704, 3.0919213}; +std::vector input2_data = {-0.31031138, 4.8659816, -9.223121, + -9.779761, -4.288633, -3.4242167}; +std::vector reference_output_data = {-0.31031138, -3.694989, -9.223121, + -9.779761, -7.1077704, -3.4242167}; + +} // namespace minimum_float_no_broadcasting + +class TestDataFloatMinimum : public TestDataMinimumBase +{ +public: + explicit TestDataFloatMinimum(bool is_with_broadcast) + : TestDataMinimumBase(is_with_broadcast) + { + if (is_with_broadcast) + { + _input1_data = minimum_float_with_broadcasting::input1_data; + _input2_data = minimum_float_with_broadcasting::input2_data; + _reference_output_data = minimum_float_with_broadcasting::reference_output_data; + _test_kernel_model_circle = minimum_float_with_broadcasting::test_kernel_model_circle; + } + else + { + _input1_data = minimum_float_no_broadcasting::input1_data; + _input2_data = minimum_float_no_broadcasting::input2_data; + _reference_output_data = minimum_float_no_broadcasting::reference_output_data; + _test_kernel_model_circle = minimum_float_no_broadcasting::test_kernel_model_circle; + } + } + + ~TestDataFloatMinimum() override = default; +}; + +} // namespace test_model +} // namespace onert_micro + +#endif // ONERT_MICRO_TEST_MODELS_MINIMUM_KERNEL_FLOAT_H diff --git a/onert-micro/onert-micro/include/test_models/minimum/NegMinimumKernel.h b/onert-micro/onert-micro/include/test_models/minimum/NegMinimumKernel.h new file mode 100644 index 00000000000..8cbc7e01f16 --- /dev/null +++ b/onert-micro/onert-micro/include/test_models/minimum/NegMinimumKernel.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ONERT_MICRO_TEST_MODELS_NEG_MINIMUM_KERNEL_H +#define ONERT_MICRO_TEST_MODELS_NEG_MINIMUM_KERNEL_H + +#include "TestDataMinimumBase.h" + +namespace onert_micro +{ +namespace test_model +{ +namespace input_1_wrong_type +{ + +/* + * Minimum Kernel with input type mismatch: + * + * Input_1(2, 5) - Int32 Input_2(2, 1) - Float + * \ / + * Minimum(with broadcast) + * | + * Output(2, 5) + */ +const unsigned char test_kernel_model_circle[] = { + 0x18, 0x00, 0x00, 0x00, 0x43, 0x49, 0x52, 0x30, 0x00, 0x00, 0x0e, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x08, 0x00, 0x10, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x64, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x88, 0xff, 0xff, 0xff, 0x8c, 0xff, 0xff, 0xff, 0x90, 0xff, 0xff, 0xff, 0x94, 0xff, 0xff, 0xff, + 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x14, 0x00, + 0x10, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0c, 0x00, + 0x07, 0x00, 0x08, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x10, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xdc, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x6f, 0x66, 0x6d, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x10, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x69, 0x66, 0x6d, 0x32, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x14, 0x00, 0x10, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x69, 0x66, 0x6d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x0c, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x11, 0x00, 0x00, 0x00, 0x4f, 0x4e, 0x45, 0x2d, + 0x74, 0x66, 0x6c, 0x69, 0x74, 0x65, 0x32, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x00, 0x00, 0x00}; +} // namespace input_1_wrong_type + +namespace input_2_wrong_type +{ + +/* + * Minimum Kernel with input2 type mismatch: + * + * Input_1(2, 5)- Float Input_2(2, 1) - Int32 + * \ / + * Minimum(with broadcast) + * | + * Output(2, 5) - Float + */ +const unsigned char test_kernel_model_circle[] = { + 0x18, 0x00, 0x00, 0x00, 0x43, 0x49, 0x52, 0x30, 0x00, 0x00, 0x0e, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x08, 0x00, 0x10, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x64, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x88, 0xff, 0xff, 0xff, 0x8c, 0xff, 0xff, 0xff, 0x90, 0xff, 0xff, 0xff, 0x94, 0xff, 0xff, 0xff, + 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x14, 0x00, + 0x10, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0c, 0x00, + 0x07, 0x00, 0x08, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x10, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xa4, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x6f, 0x66, 0x6d, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x14, 0x00, + 0x10, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x69, 0x66, 0x6d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x69, 0x66, 0x6d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x0c, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x11, 0x00, 0x00, 0x00, 0x4f, 0x4e, 0x45, 0x2d, + 0x74, 0x66, 0x6c, 0x69, 0x74, 0x65, 0x32, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x00, 0x00, 0x00}; +} // namespace input_2_wrong_type + +class NegTestDataInput1WrongTypeMinimum : public NegTestDataBase +{ +public: + NegTestDataInput1WrongTypeMinimum() + { + _test_kernel_model_circle = input_1_wrong_type::test_kernel_model_circle; + } + + ~NegTestDataInput1WrongTypeMinimum() override = default; + + const unsigned char *get_model_ptr() override final { return _test_kernel_model_circle; } + +protected: + const unsigned char *_test_kernel_model_circle; +}; + +class NegTestDataInput2WrongTypeMinimum : public NegTestDataBase +{ +public: + NegTestDataInput2WrongTypeMinimum() + { + _test_kernel_model_circle = input_2_wrong_type::test_kernel_model_circle; + } + + ~NegTestDataInput2WrongTypeMinimum() override = default; + + const unsigned char *get_model_ptr() override final { return _test_kernel_model_circle; } + +protected: + const unsigned char *_test_kernel_model_circle; +}; + +} // namespace test_model +} // namespace onert_micro + +#endif // ONERT_MICRO_TEST_MODELS_NEG_MINIMUM_KERNEL_H diff --git a/onert-micro/onert-micro/include/test_models/minimum/TestDataMinimumBase.h b/onert-micro/onert-micro/include/test_models/minimum/TestDataMinimumBase.h new file mode 100644 index 00000000000..35a9a49ec0f --- /dev/null +++ b/onert-micro/onert-micro/include/test_models/minimum/TestDataMinimumBase.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ONERT_MICRO_TEST_MODELS_MINIMUM_KERNEL_BASE_H +#define ONERT_MICRO_TEST_MODELS_MINIMUM_KERNEL_BASE_H + +#include "test_models/TestDataBase.h" + +namespace onert_micro +{ +namespace test_model +{ + +template class TestDataMinimumBase : public TestDataBase +{ +public: + explicit TestDataMinimumBase(bool) + { + // Do nothing + } + + TestDataMinimumBase() = delete; + + const unsigned char *get_model_ptr() override final { return _test_kernel_model_circle; } + + const std::vector &get_input_data_by_index(int i) override final + { + switch (i) + { + case 0: + return _input1_data; + case 1: + return _input2_data; + default: + assert(false && "Wrong input index"); + } + } + + const std::vector &get_output_data_by_index(int i) override final + { + assert(i == 0); + return _reference_output_data; + } + +protected: + std::vector _input1_data; + std::vector _input2_data; + std::vector _reference_output_data; + const unsigned char *_test_kernel_model_circle; +}; + +} // namespace test_model +} // namespace onert_micro + +#endif // ONERT_MICRO_TEST_MODELS_MINIMUM_KERNEL_BASE_H diff --git a/onert-micro/onert-micro/src/execute/kernels/Minimum.cpp b/onert-micro/onert-micro/src/execute/kernels/Minimum.cpp new file mode 100644 index 00000000000..8974f5a12b0 --- /dev/null +++ b/onert-micro/onert-micro/src/execute/kernels/Minimum.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "execute/OMKernelExecutionBuilder.h" +#include "OMStatus.h" +#include "execute/OMRuntimeKernel.h" +#include "core/OMUtils.h" +#include "PALMinimum.h" + +using namespace onert_micro; +using namespace onert_micro::core; +using namespace onert_micro::execute; + +namespace +{ + +constexpr uint32_t input1TensorIdx = 0; +constexpr uint32_t input2TensorIdx = 1; +constexpr uint32_t outputTensorIdx = 0; + +} // namespace + +OMStatus onert_micro::execute::execute_kernel_CircleMinimum(const OMExecuteArgs &execute_args) +{ + core::OMRuntimeContext &runtime_context = execute_args.runtime_context; + core::OMRuntimeStorage &runtime_storage = execute_args.runtime_storage; + uint16_t op_index = execute_args.kernel_index; + + OMStatus status = Ok; + + const circle::Tensor *input1 = nullptr; + const circle::Tensor *input2 = nullptr; + const circle::Tensor *output = nullptr; + + uint8_t *input_data1; + uint8_t *input_data2; + uint8_t *output_data; + + OMRuntimeKernel runtime_kernel; + runtime_kernel.readKernel(op_index, runtime_context); + + status = runtime_kernel.getDataFromStorage(op_index, runtime_storage, runtime_context); + if (status != Ok) + return status; + + input1 = runtime_kernel.inputs[input1TensorIdx]; + input2 = runtime_kernel.inputs[input2TensorIdx]; + output = runtime_kernel.outputs[outputTensorIdx]; + + assert(input1 != nullptr); + assert(input2 != nullptr); + assert(output != nullptr); + + input_data1 = runtime_kernel.inputs_data[input1TensorIdx]; + input_data2 = runtime_kernel.inputs_data[input2TensorIdx]; + output_data = runtime_kernel.outputs_data[outputTensorIdx]; + + assert(input_data1 != nullptr); + assert(input_data2 != nullptr); + assert(output_data != nullptr); + + OMRuntimeShape input_shape1(input1); + OMRuntimeShape input_shape2(input2); + OMRuntimeShape output_shape(output); + + switch (input1->type()) + { +#ifndef DIS_FLOAT + case circle::TensorType_FLOAT32: + { + // check that input and output dimensions are equal + if (input_shape1 == input_shape2) + { + const int flat_size = input_shape1.flatSize(); + status = pal::Minimum(flat_size, utils::castInputData(input_data1), + utils::castInputData(input_data2), + utils::castOutputData(output_data)); + } + else + { + status = + pal::BroadcastMinimum4DSlow(input_shape1, utils::castInputData(input_data1), + input_shape2, utils::castInputData(input_data2), + output_shape, utils::castOutputData(output_data)); + } + } + break; +#endif // DIS_FLOAT + default: + assert(false && "Unsupported type."); + } + + return status; +} diff --git a/onert-micro/onert-micro/src/execute/kernels/tests/Minimum.test.cpp b/onert-micro/onert-micro/src/execute/kernels/tests/Minimum.test.cpp new file mode 100644 index 00000000000..9a296037928 --- /dev/null +++ b/onert-micro/onert-micro/src/execute/kernels/tests/Minimum.test.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved + * Copyright 2017 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "execute/OMTestUtils.h" +#include "test_models/minimum/FloatMinimumKernel.h" +#include "test_models/minimum/NegMinimumKernel.h" + +namespace onert_micro +{ +namespace execute +{ +namespace testing +{ +using namespace testing; + +class MinimumTest : public ::testing::Test +{ + // Do nothing +}; + +TEST_F(MinimumTest, Float_P) +{ + // No broadcast + { + const bool is_with_broadcast = false; + onert_micro::test_model::TestDataFloatMinimum test_data_kernel(is_with_broadcast); + + std::vector output_data_vector = + onert_micro::execute::testing::checkKernel(2, &test_data_kernel); + + EXPECT_THAT(output_data_vector, + FloatArrayNear(test_data_kernel.get_output_data_by_index(0), 0.0001f)); + } + // With broadcast + { + const bool is_with_broadcast = true; + onert_micro::test_model::TestDataFloatMinimum test_data_kernel(is_with_broadcast); + + std::vector output_data_vector = + onert_micro::execute::testing::checkKernel(2, &test_data_kernel); + + EXPECT_THAT(output_data_vector, + FloatArrayNear(test_data_kernel.get_output_data_by_index(0), 0.0001f)); + } +} + +TEST_F(MinimumTest, Wrong_Input1_Type_NEG) +{ + onert_micro::test_model::NegTestDataInput1WrongTypeMinimum test_data_kernel; + + EXPECT_DEATH(checkNEGSISOKernel(&test_data_kernel), ""); +} + +TEST_F(MinimumTest, Wrong_Input2_Type_NEG) +{ + onert_micro::test_model::NegTestDataInput2WrongTypeMinimum test_data_kernel; + + EXPECT_DEATH(checkNEGSISOKernel(&test_data_kernel), ""); +} + +} // namespace testing +} // namespace execute +} // namespace onert_micro diff --git a/onert-micro/onert-micro/src/import/kernels/Minimum.cpp b/onert-micro/onert-micro/src/import/kernels/Minimum.cpp new file mode 100644 index 00000000000..3aa3d07584a --- /dev/null +++ b/onert-micro/onert-micro/src/import/kernels/Minimum.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "import/OMKernelConfigureBuilder.h" +#include "core/OMUtils.h" +#include "OMStatus.h" +#include "execute/OMRuntimeKernel.h" + +using namespace onert_micro; +using namespace onert_micro::core; + +namespace +{ + +constexpr uint32_t input1TensorIdx = 0; +constexpr uint32_t input2TensorIdx = 1; +constexpr uint32_t outputTensorIdx = 0; + +} // namespace + +OMStatus onert_micro::import::configure_kernel_CircleMinimum(const OMConfigureArgs &config_args) +{ + + OMRuntimeContext &runtime_context = config_args.runtime_context; + uint16_t op_index = config_args.kernel_index; + + onert_micro::execute::OMRuntimeKernel runtime_kernel; + + OMStatus status = runtime_kernel.readKernel(op_index, runtime_context); + if (status != Ok) + return status; + + const circle::Tensor *input1 = runtime_kernel.inputs[input1TensorIdx]; + const circle::Tensor *input2 = runtime_kernel.inputs[input2TensorIdx]; + const circle::Tensor *output = runtime_kernel.outputs[outputTensorIdx]; + + assert(input1 != nullptr); + assert(input2 != nullptr); + assert(output != nullptr); + + status = utils::checkCondition(input1->type() == input2->type()); + if (status != Ok) + return status; + + status = utils::checkCondition(input1->type() == output->type()); + if (status != Ok) + return status; + + return status; +}