From 506f7b49afc37d885a6ad7203f0689e936ad3353 Mon Sep 17 00:00:00 2001 From: Balyshev Artem <43214667+BalyshevArtem@users.noreply.github.com> Date: Thu, 20 Jun 2024 17:11:42 +0300 Subject: [PATCH] [onert-micro] Add Pad kernel (#13248) This pr adds Pad kernel. ONE-DCO-1.0-Signed-off-by: Artem Balyshev --- .../onert-micro/include/core/OMKernelData.h | 8 ++ .../include/import/helpers/OMPadCommon.h | 38 ++++++ .../onert-micro/include/pal/common/PALPad.h | 118 ++++++++++++++++ .../include/pal/mcu/KernelsToBuild.lst | 2 +- .../include/test_models/pad/FloatPadKernel.h | 105 ++++++++++++++ .../include/test_models/pad/NegPadKernel.h | 92 +++++++++++++ .../include/test_models/pad/TestDataPadBase.h | 60 ++++++++ .../onert-micro/src/execute/kernels/Pad.cpp | 128 ++++++++++++++++++ .../src/execute/kernels/tests/Pad.test.cpp | 53 ++++++++ .../onert-micro/src/import/CMakeLists.txt | 1 + .../src/import/helpers/OMPadCommon.cpp | 75 ++++++++++ .../onert-micro/src/import/kernels/Pad.cpp | 25 ++++ 12 files changed, 704 insertions(+), 1 deletion(-) create mode 100644 onert-micro/onert-micro/include/import/helpers/OMPadCommon.h create mode 100644 onert-micro/onert-micro/include/pal/common/PALPad.h create mode 100644 onert-micro/onert-micro/include/test_models/pad/FloatPadKernel.h create mode 100644 onert-micro/onert-micro/include/test_models/pad/NegPadKernel.h create mode 100644 onert-micro/onert-micro/include/test_models/pad/TestDataPadBase.h create mode 100644 onert-micro/onert-micro/src/execute/kernels/Pad.cpp create mode 100644 onert-micro/onert-micro/src/execute/kernels/tests/Pad.test.cpp create mode 100644 onert-micro/onert-micro/src/import/helpers/OMPadCommon.cpp create mode 100644 onert-micro/onert-micro/src/import/kernels/Pad.cpp diff --git a/onert-micro/onert-micro/include/core/OMKernelData.h b/onert-micro/onert-micro/include/core/OMKernelData.h index d68c8fde6a8..354b4c9be75 100644 --- a/onert-micro/onert-micro/include/core/OMKernelData.h +++ b/onert-micro/onert-micro/include/core/OMKernelData.h @@ -186,6 +186,14 @@ struct FullyConnectedParams int32_t quantized_activation_max; }; +struct PadParams +{ + int32_t left_padding_count; + int32_t left_padding[5]; + int32_t right_padding_count; + int32_t right_padding[5]; +}; + struct ComparisonParams { // uint8_t inference params. diff --git a/onert-micro/onert-micro/include/import/helpers/OMPadCommon.h b/onert-micro/onert-micro/include/import/helpers/OMPadCommon.h new file mode 100644 index 00000000000..eff666fc55a --- /dev/null +++ b/onert-micro/onert-micro/include/import/helpers/OMPadCommon.h @@ -0,0 +1,38 @@ +/* + * 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_IMPORT_HELPERS_CONFIGURE_PAD_KERNEL_COMMON_H +#define ONERT_MICRO_IMPORT_HELPERS_CONFIGURE_PAD_KERNEL_COMMON_H + +#include "import/OMKernelConfigureBuilder.h" +#include "core/OMUtils.h" +#include "OMStatus.h" +#include "execute/OMRuntimeKernel.h" + +namespace onert_micro +{ +namespace import +{ +namespace helpers +{ + +OMStatus configure_pad_kernel_common(const OMConfigureArgs &config_args); + +} // namespace helpers +} // namespace import +} // namespace onert_micro + +#endif // ONERT_MICRO_IMPORT_HELPERS_CONFIGURE_PAD_KERNEL_COMMON_H diff --git a/onert-micro/onert-micro/include/pal/common/PALPad.h b/onert-micro/onert-micro/include/pal/common/PALPad.h new file mode 100644 index 00000000000..11ec1b3c17d --- /dev/null +++ b/onert-micro/onert-micro/include/pal/common/PALPad.h @@ -0,0 +1,118 @@ +/* + * 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_EXECUTE_PAL_PAD_COMMON_H +#define ONERT_MICRO_EXECUTE_PAL_PAD_COMMON_H + +#include "core/OMRuntimeShape.h" +#include "core/OMKernelData.h" +#include "OMStatus.h" + +namespace onert_micro +{ +namespace execute +{ +namespace pal +{ +namespace +{ +constexpr int padKernelMaxDimensionCount = 5; +} // namespace + +OMStatus Pad(const core::PadParams &op_params, const core::OMRuntimeShape &input_shape, + const float *input_data, const float pad_value, + const core::OMRuntimeShape &output_shape, float *output_data) +{ + // Runtime calls are currently fixed at 5 dimensions. Copy inputs so we can + // pad them to 5 dims (yes, we are "padding the padding"). + int left_padding_copy[padKernelMaxDimensionCount]; + for (int &i : left_padding_copy) + { + i = 0; + } + for (int i = 0; i < op_params.left_padding_count; ++i) + { + left_padding_copy[i + padKernelMaxDimensionCount - op_params.left_padding_count] = + op_params.left_padding[i]; + } + int right_padding_copy[padKernelMaxDimensionCount]; + for (int &i : right_padding_copy) + { + i = 0; + } + for (int i = 0; i < op_params.right_padding_count; ++i) + { + right_padding_copy[i + padKernelMaxDimensionCount - op_params.right_padding_count] = + op_params.right_padding[i]; + } + const auto extended_output = + core::OMRuntimeShape::extendedShape(padKernelMaxDimensionCount, output_shape); + const int output_batch = extended_output.dims(0); + const int output_plane = extended_output.dims(1); + const int output_height = extended_output.dims(2); + const int output_width = extended_output.dims(3); + const int output_depth = extended_output.dims(4); + + const int left_b_padding = left_padding_copy[0]; + const int left_p_padding = left_padding_copy[1]; + const int left_h_padding = left_padding_copy[2]; + const int left_w_padding = left_padding_copy[3]; + const int left_d_padding = left_padding_copy[4]; + + const int right_b_padding = right_padding_copy[0]; + const int right_p_padding = right_padding_copy[1]; + const int right_h_padding = right_padding_copy[2]; + const int right_w_padding = right_padding_copy[3]; + const int right_d_padding = right_padding_copy[4]; + + const float *in_ptr = input_data; + float *out_ptr = output_data; + for (int out_b = 0; out_b < output_batch; ++out_b) + { + for (int out_p = 0; out_p < output_plane; ++out_p) + { + for (int out_h = 0; out_h < output_height; ++out_h) + { + for (int out_w = 0; out_w < output_width; ++out_w) + { + for (int out_d = 0; out_d < output_depth; ++out_d) + { + if (out_b < left_b_padding || out_b >= output_batch - right_b_padding || + out_p < left_p_padding || out_p >= output_plane - right_p_padding || + out_h < left_h_padding || out_h >= output_height - right_h_padding || + out_w < left_w_padding || out_w >= output_width - right_w_padding || + out_d < left_d_padding || out_d >= output_depth - right_d_padding) + { + *out_ptr++ = pad_value; + } + else + { + *out_ptr++ = *in_ptr++; + } + } + } + } + } + } + + return Ok; +} + +} // namespace pal +} // namespace execute +} // namespace onert_micro + +#endif // ONERT_MICRO_EXECUTE_PAL_NEG_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 4088018006f..fdacefa2f4d 100644 --- a/onert-micro/onert-micro/include/pal/mcu/KernelsToBuild.lst +++ b/onert-micro/onert-micro/include/pal/mcu/KernelsToBuild.lst @@ -31,7 +31,7 @@ REGISTER_KERNEL(FLOOR, Floor) REGISTER_KERNEL(FLOOR_DIV, FloorDiv) REGISTER_KERNEL(FLOOR_MOD, FloorMod) #/*REGISTER_KERNEL(PACK, Pack)*/ -#/*REGISTER_KERNEL(PAD, Pad)*/ +REGISTER_KERNEL(PAD, Pad) #/*REGISTER_KERNEL(PADV2, PadV2)*/ #/*REGISTER_KERNEL(PRELU, PRelu)*/ REGISTER_KERNEL(RESHAPE, Reshape) diff --git a/onert-micro/onert-micro/include/test_models/pad/FloatPadKernel.h b/onert-micro/onert-micro/include/test_models/pad/FloatPadKernel.h new file mode 100644 index 00000000000..e8dac6eb1ec --- /dev/null +++ b/onert-micro/onert-micro/include/test_models/pad/FloatPadKernel.h @@ -0,0 +1,105 @@ +/* + * 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_FLOAT_PAD_KERNEL_H +#define ONERT_MICRO_TEST_MODELS_FLOAT_PAD_KERNEL_H + +#include "TestDataPadBase.h" + +namespace onert_micro +{ +namespace test_model +{ +namespace pad_float +{ +/* + * Pad Kernel: + * + * Input(1, 3, 3, 2) + * | + * Pad + * | + * Output(1, 3, 3, 2) + */ +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, + 0x60, 0x00, 0x00, 0x00, 0x9c, 0x01, 0x00, 0x00, 0xb8, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x4c, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x08, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 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, + 0x00, 0x00, 0x00, 0x00, 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, 0x68, 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, 0x16, 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, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x9c, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x6f, 0x66, 0x6d, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x14, 0x00, 0x10, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x02, 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, + 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x66, 0x6d, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 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, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, + 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 input_data = { + -0.7942257, -1.3318212, -0.7918672, -1.0024637, -0.23364098, 0.49224994, + -0.23747201, -0.14768714, 1.4870708, -0.79761434, -0.27848604, 1.1856802, + 1.1039438, -0.34465268, -1.5857629, 3.0654314, 0.13304773, 0.067413524}; + +const std::vector reference_output_data = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, -0.7942257, -1.3318212, -0.7918672, + -1.0024637, -0.23364098, 0.49224994, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, -0.23747201, -0.14768714, 1.4870708, + -0.79761434, -0.27848604, 1.1856802, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 1.1039438, -0.34465268, -1.5857629, + 3.0654314, 0.13304773, 0.067413524, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; +} // namespace pad_float + +class TestDataFloatPad : public TestDataPadBase +{ +public: + TestDataFloatPad() + { + _input_data = pad_float::input_data; + _reference_output_data = pad_float::reference_output_data; + _test_kernel_model_circle = pad_float::test_kernel_model_circle; + } + + ~TestDataFloatPad() override = default; +}; + +} // namespace test_model +} // namespace onert_micro + +#endif // ONERT_MICRO_TEST_MODELS_FLOAT_PAD_KERNEL_H diff --git a/onert-micro/onert-micro/include/test_models/pad/NegPadKernel.h b/onert-micro/onert-micro/include/test_models/pad/NegPadKernel.h new file mode 100644 index 00000000000..69453ad02a1 --- /dev/null +++ b/onert-micro/onert-micro/include/test_models/pad/NegPadKernel.h @@ -0,0 +1,92 @@ +/* + * 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_PAD_KERNEL_H +#define ONERT_MICRO_TEST_MODELS_NEG_PAD_KERNEL_H + +#include "test_models/TestDataBase.h" + +namespace onert_micro +{ +namespace test_model +{ +namespace neg_input_output_type_mismatch_pad_kernel +{ +/* + * Pad Kernel with input output type mismatch (should be equal): + * + * Input(1, 3, 3, 2) - Float + * | + * Pad + * | + * Output(1, 3, 3, 2) - Int + */ +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, + 0x60, 0x00, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, 0xbc, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x4c, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x08, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 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, + 0x00, 0x00, 0x00, 0x00, 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, 0x68, 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, 0x16, 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, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0xd0, 0xff, 0xff, 0xff, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x6f, 0x66, 0x6d, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x14, 0x00, 0x10, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x04, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x10, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 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, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x66, 0x6d, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 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, 0x22, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x22, 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 neg_input_output_type_mismatch_pad_kernel + +class NegTestDataInputOutputTypeMismatchPadKernel : public NegTestDataBase +{ +public: + NegTestDataInputOutputTypeMismatchPadKernel() + { + _test_kernel_model_circle = neg_input_output_type_mismatch_pad_kernel::test_kernel_model_circle; + } + + ~NegTestDataInputOutputTypeMismatchPadKernel() 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_PAD_KERNEL_H diff --git a/onert-micro/onert-micro/include/test_models/pad/TestDataPadBase.h b/onert-micro/onert-micro/include/test_models/pad/TestDataPadBase.h new file mode 100644 index 00000000000..49de36a1616 --- /dev/null +++ b/onert-micro/onert-micro/include/test_models/pad/TestDataPadBase.h @@ -0,0 +1,60 @@ +/* + * 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_PAD_KERNEL_BASE_H +#define ONERT_MICRO_TEST_MODELS_PAD_KERNEL_BASE_H + +#include "test_models/TestDataBase.h" + +namespace onert_micro +{ +namespace test_model +{ + +template class TestDataPadBase : public TestDataBase +{ +public: + TestDataPadBase() = default; + + 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 _input_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 _input_data; + std::vector _reference_output_data; + const unsigned char *_test_kernel_model_circle; +}; + +} // namespace test_model +} // namespace onert_micro + +#endif // ONERT_MICRO_TEST_MODELS_PAD_KERNEL_BASE_H diff --git a/onert-micro/onert-micro/src/execute/kernels/Pad.cpp b/onert-micro/onert-micro/src/execute/kernels/Pad.cpp new file mode 100644 index 00000000000..586d2e4a372 --- /dev/null +++ b/onert-micro/onert-micro/src/execute/kernels/Pad.cpp @@ -0,0 +1,128 @@ +/* + * 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 "OMStatus.h" + +#include "core/OMUtils.h" +#include "core/OMRuntimeShape.h" + +#include "execute/OMKernelExecutionBuilder.h" +#include "execute/OMRuntimeKernel.h" + +#include "PALPad.h" + +using namespace onert_micro; +using namespace onert_micro::execute; + +namespace +{ + +constexpr uint32_t input1TensorIdx = 0; +constexpr uint32_t input2TensorIdx = 1; +constexpr uint32_t input3TensorIdx = 2; +constexpr uint32_t outputTensorIdx = 0; + +} // namespace + +OMStatus onert_micro::execute::execute_kernel_CirclePad(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; + + const circle::Tensor *input1; + const circle::Tensor *input2; + const circle::Tensor *input3; + const circle::Tensor *output; + + uint8_t *input1_data; + uint8_t *input2_data; + uint8_t *input3_data; + uint8_t *output_data; + + const circle::PadOptions *options; + // Read kernel + { + execute::OMRuntimeKernel runtime_kernel; + runtime_kernel.readKernel(op_index, runtime_context); + + input1 = runtime_kernel.inputs[input1TensorIdx]; + input2 = runtime_kernel.inputs[input2TensorIdx]; + input3 = runtime_kernel.inputs[input3TensorIdx]; + output = runtime_kernel.outputs[outputTensorIdx]; + assert(input1 != nullptr); + assert(input2 != nullptr); + // input3 - can be nullptr + assert(output != nullptr); + + runtime_kernel.getDataFromStorage(op_index, runtime_storage, runtime_context); + + input1_data = runtime_kernel.inputs_data[input1TensorIdx]; + input2_data = runtime_kernel.inputs_data[input2TensorIdx]; + input3_data = runtime_kernel.inputs_data[input3TensorIdx]; + output_data = runtime_kernel.outputs_data[outputTensorIdx]; + assert(input1_data != nullptr); + assert(input2_data != nullptr); + // input3_data can be nullptr + assert(output_data != nullptr); + + options = runtime_kernel.first_operator->builtin_options_as_PadOptions(); + } + + OMStatus status = Ok; + + core::OMRuntimeShape input1_shape(input1); + core::OMRuntimeShape input2_shape(input2); + core::OMRuntimeShape output_shape(output); + + // Create PadParams + core::PadParams pad_params{}; + const auto num_input_dimensions = input1_shape.dimensionsCount(); + assert(num_input_dimensions <= 5); + + if (num_input_dimensions > 5) + return UnsupportedType; + + pad_params.left_padding_count = num_input_dimensions; + pad_params.right_padding_count = num_input_dimensions; + + auto *paddings_data = reinterpret_cast(input2_data); + for (int idx = num_input_dimensions - 1; idx >= 0; --idx) + { + pad_params.left_padding[idx] = paddings_data[idx * 2]; + pad_params.right_padding[idx] = paddings_data[idx * 2 + 1]; + } + + switch (input1->type()) + { +#ifndef DIS_FLOAT + case circle::TensorType_FLOAT32: + { + float pad_value = input3_data == nullptr ? 0.f : *reinterpret_cast(input3_data[0]); + status = pal::Pad(pad_params, input1_shape, core::utils::castInputData(input1_data), + pad_value, output_shape, core::utils::castOutputData(output_data)); + } + break; +#endif // DIS_FLOAT + default: + { + status = UnsupportedType; + assert(false && "Unsupported type"); + } + } + + return status; +} diff --git a/onert-micro/onert-micro/src/execute/kernels/tests/Pad.test.cpp b/onert-micro/onert-micro/src/execute/kernels/tests/Pad.test.cpp new file mode 100644 index 00000000000..519d7a4cc21 --- /dev/null +++ b/onert-micro/onert-micro/src/execute/kernels/tests/Pad.test.cpp @@ -0,0 +1,53 @@ +/* + * 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/OMTestUtils.h" +#include "test_models/pad/FloatPadKernel.h" +#include "test_models/pad/NegPadKernel.h" + +namespace onert_micro +{ +namespace execute +{ +namespace testing +{ + +using namespace testing; + +class PadTest : public ::testing::Test +{ + // Do nothing +}; + +TEST_F(PadTest, Float_P) +{ + onert_micro::test_model::TestDataFloatPad test_data_kernel; + std::vector output_data_vector = + onert_micro::execute::testing::checkKernel(1, &test_data_kernel); + EXPECT_THAT(output_data_vector, + FloatArrayNear(test_data_kernel.get_output_data_by_index(0), 0.0001f)); +} + +TEST_F(PadTest, Input_output_type_mismatch_NEG) +{ + onert_micro::test_model::NegTestDataInputOutputTypeMismatchPadKernel 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/CMakeLists.txt b/onert-micro/onert-micro/src/import/CMakeLists.txt index ae21c0b9c9d..b626bbbf4a3 100644 --- a/onert-micro/onert-micro/src/import/CMakeLists.txt +++ b/onert-micro/onert-micro/src/import/CMakeLists.txt @@ -5,6 +5,7 @@ set(SOURCES OMKernelConfiguration.cpp OMKernelConfigureBuilder.cpp helpers/OMConfigureSISOKernel.cpp + helpers/OMPadCommon.cpp helpers/OMConfigureTISOKernel.cpp ) diff --git a/onert-micro/onert-micro/src/import/helpers/OMPadCommon.cpp b/onert-micro/onert-micro/src/import/helpers/OMPadCommon.cpp new file mode 100644 index 00000000000..3f0805493e6 --- /dev/null +++ b/onert-micro/onert-micro/src/import/helpers/OMPadCommon.cpp @@ -0,0 +1,75 @@ +/* + * 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/helpers/OMPadCommon.h" + +using namespace onert_micro; +using namespace onert_micro::core; + +namespace +{ + +constexpr uint32_t input1TensorIdx = 0; +constexpr uint32_t input2TensorIdx = 1; +constexpr uint32_t input3TensorIdx = 2; +constexpr uint32_t outputTensorIdx = 0; + +} // namespace + +OMStatus +onert_micro::import::helpers::configure_pad_kernel_common(const OMConfigureArgs &config_args) +{ + OMRuntimeContext &runtime_context = config_args.runtime_context; + OMRuntimeStorage &runtime_storage = config_args.runtime_storage; + 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 *input3 = runtime_kernel.inputs[input3TensorIdx]; + const circle::Tensor *output = runtime_kernel.outputs[outputTensorIdx]; + + assert(input1 != nullptr); + assert(input2 != nullptr); + assert(output != nullptr); + + status = utils::checkCondition(input1->type() == output->type()); + if (status != Ok) + return status; + + status = utils::checkCondition(input2->type() == circle::TensorType_INT32); + if (status != Ok) + return status; + + if (input3 != nullptr) + { + status = utils::checkCondition(input3->type() == input1->type()); + if (status != Ok) + return status; + + // Value is scalar + status = utils::checkCondition(OMRuntimeShape(input3).flatSize() == 1); + if (status != Ok) + return status; + } + + return Ok; +} diff --git a/onert-micro/onert-micro/src/import/kernels/Pad.cpp b/onert-micro/onert-micro/src/import/kernels/Pad.cpp new file mode 100644 index 00000000000..2e3e1cb7bf8 --- /dev/null +++ b/onert-micro/onert-micro/src/import/kernels/Pad.cpp @@ -0,0 +1,25 @@ +/* + * 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/helpers/OMPadCommon.h" + +using namespace onert_micro; +using namespace onert_micro::core; + +OMStatus onert_micro::import::configure_kernel_CirclePad(const OMConfigureArgs &config_args) +{ + return onert_micro::import::helpers::configure_pad_kernel_common(config_args); +}