From 386652ba6907116a16f29f7a20ba5ad1e382dadf Mon Sep 17 00:00:00 2001 From: Balyshev Artem <43214667+BalyshevArtem@users.noreply.github.com> Date: Fri, 21 Jun 2024 12:40:14 +0300 Subject: [PATCH] [onert-micro] Add Unpack kernel (#13260) This pr adds Unpack kernel. ONE-DCO-1.0-Signed-off-by: Artem Balyshev --- .../include/pal/common/PALUnpack.h | 77 +++++++++++++ .../include/pal/mcu/KernelsToBuild.lst | 2 +- .../test_models/unpack/FloatUnpackKernel.h | 103 +++++++++++++++++ .../test_models/unpack/NegUnpackKernel.h | 90 +++++++++++++++ .../test_models/unpack/TestDataUnpackBase.h | 69 ++++++++++++ .../src/execute/kernels/Unpack.cpp | 104 ++++++++++++++++++ .../src/execute/kernels/tests/Unpack.test.cpp | 52 +++++++++ .../onert-micro/src/import/kernels/Unpack.cpp | 100 +++++++++++++++++ 8 files changed, 596 insertions(+), 1 deletion(-) create mode 100644 onert-micro/onert-micro/include/pal/common/PALUnpack.h create mode 100644 onert-micro/onert-micro/include/test_models/unpack/FloatUnpackKernel.h create mode 100644 onert-micro/onert-micro/include/test_models/unpack/NegUnpackKernel.h create mode 100644 onert-micro/onert-micro/include/test_models/unpack/TestDataUnpackBase.h create mode 100644 onert-micro/onert-micro/src/execute/kernels/Unpack.cpp create mode 100644 onert-micro/onert-micro/src/execute/kernels/tests/Unpack.test.cpp create mode 100644 onert-micro/onert-micro/src/import/kernels/Unpack.cpp diff --git a/onert-micro/onert-micro/include/pal/common/PALUnpack.h b/onert-micro/onert-micro/include/pal/common/PALUnpack.h new file mode 100644 index 00000000000..1bbdcd8b6bf --- /dev/null +++ b/onert-micro/onert-micro/include/pal/common/PALUnpack.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved + * Copyright 2020 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_UNPACK_COMMON_H +#define ONERT_MICRO_PAL_UNPACK_COMMON_H + +#include "core/OMKernelData.h" + +namespace onert_micro +{ +namespace execute +{ +namespace pal +{ + +template +OMStatus Unpack(const core::SplitParams ¶ms, const core::OMRuntimeShape &input_shape, + const T *input_data, const core::OMRuntimeShape &output_shape, int32_t axis_value) +{ + const auto dimensions = input_shape.dimensionsCount(); + + if (axis_value < 0) + { + axis_value += dimensions; + } + + int outer_size = 1; + for (int i = 0; i < axis_value; ++i) + { + outer_size *= input_shape.dims(i); + } + int copy_size = 1; + for (int i = axis_value + 1; i < dimensions; ++i) + { + copy_size *= input_shape.dims(i); + } + int output_size = 1; + for (int i = 0; i < output_shape.dimensionsCount(); ++i) + { + output_size *= output_shape.dims(i); + } + + for (int i = 0; i < params.num_outputs; ++i) + { + T *output_data = core::utils::castOutputData(params.output_data[i]); + assert(output_data != nullptr); + for (int k = 0; k < outer_size; ++k) + { + T *output_ptr = output_data + copy_size * k; + int loc = k * params.num_outputs * copy_size + i * copy_size; + const T *input_ptr = input_data + loc; + for (int j = 0; j < copy_size; ++j) + output_ptr[j] = input_ptr[j]; + } + } + return Ok; +} + +} // namespace pal +} // namespace execute +} // namespace onert_micro + +#endif // ONERT_MICRO_PAL_UNPACK_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 d52df3a0899..8d812812530 100644 --- a/onert-micro/onert-micro/include/pal/mcu/KernelsToBuild.lst +++ b/onert-micro/onert-micro/include/pal/mcu/KernelsToBuild.lst @@ -84,4 +84,4 @@ REGISTER_KERNEL(RSQRT, Rsqrt) REGISTER_KERNEL(NEG, Neg) #/*REGISTER_KERNEL(ZEROS_LIKE, ZerosLike)*/ #/*REGISTER_KERNEL(SQUEEZE, Squeeze)*/ -#/*REGISTER_KERNEL(UNPACK, Unpack)*/ +REGISTER_KERNEL(UNPACK, Unpack) diff --git a/onert-micro/onert-micro/include/test_models/unpack/FloatUnpackKernel.h b/onert-micro/onert-micro/include/test_models/unpack/FloatUnpackKernel.h new file mode 100644 index 00000000000..806f82dfcdf --- /dev/null +++ b/onert-micro/onert-micro/include/test_models/unpack/FloatUnpackKernel.h @@ -0,0 +1,103 @@ +/* + * 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_SQRT_KERNEL_H +#define ONERT_MICRO_TEST_MODELS_FLOAT_SQRT_KERNEL_H + +#include "TestDataUnpackBase.h" + +namespace onert_micro +{ +namespace test_model +{ +namespace unpack_float +{ +/* + * Unpack Kernel: + * + * Input(2, 2, 3, 4) + * | + * Unpack(num=2, axis=0) + * / \ + * Output1(2, 3, 4) Output1(2, 3, 4) + */ +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, + 0x34, 0x00, 0x00, 0x00, 0x6c, 0x01, 0x00, 0x00, 0x88, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xf4, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0x04, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x00, 0x00, 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, 0x68, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x74, 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, 0x16, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x08, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x14, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, + 0x08, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0xac, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x6f, 0x66, 0x6d, 0x3a, 0x31, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xd8, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x6f, 0x66, 0x6d, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x04, 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, + 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 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, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, + 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 = { + 80.8925, -4.4767537, 38.051624, 69.14668, -23.124884, -8.138234, 79.53351, 40.877926, + -12.0593405, 41.621094, 69.482895, 7.9741273, 3.7500796, -80.87057, 10.576268, -16.321995, + -12.388415, -20.782156, 47.479202, -56.73159, 81.99104, 70.61185, 32.652695, -93.72114, + -75.67862, -70.78546, -42.199966, -12.66376, 21.785488, -7.168219, -19.772392, -17.600962, + 64.1301, -4.7490916, 76.81972, -41.70657, -83.13318, 45.003937, 85.05216, -29.184652, + 40.685417, -35.482887, -60.648735, -0.268777, -0.59301615, -19.212725, 87.67197, -37.269848}; +const std::vector reference_output_data_1 = { + 80.8925, -4.4767537, 38.051624, 69.14668, -23.124884, -8.138234, 79.53351, 40.877926, + -12.0593405, 41.621094, 69.482895, 7.9741273, 3.7500796, -80.87057, 10.576268, -16.321995, + -12.388415, -20.782156, 47.479202, -56.73159, 81.99104, 70.61185, 32.652695, -93.72114}; +const std::vector reference_output_data_2 = { + -75.67862, -70.78546, -42.199966, -12.66376, 21.785488, -7.168219, -19.772392, -17.600962, + 64.1301, -4.7490916, 76.81972, -41.70657, -83.13318, 45.003937, 85.05216, -29.184652, + 40.685417, -35.482887, -60.648735, -0.268777, -0.59301615, -19.212725, 87.67197, -37.269848}; + +} // namespace unpack_float + +class TestDataFloatUnpack : public TestDataUnpackBase +{ +public: + TestDataFloatUnpack() + { + _input_data = unpack_float::input_data; + _reference_output_data_1 = unpack_float::reference_output_data_1; + _reference_output_data_2 = unpack_float::reference_output_data_2; + _test_kernel_model_circle = unpack_float::test_kernel_model_circle; + } + + ~TestDataFloatUnpack() override = default; +}; + +} // namespace test_model +} // namespace onert_micro + +#endif // ONERT_MICRO_TEST_MODELS_FLOAT_SQRT_KERNEL_H diff --git a/onert-micro/onert-micro/include/test_models/unpack/NegUnpackKernel.h b/onert-micro/onert-micro/include/test_models/unpack/NegUnpackKernel.h new file mode 100644 index 00000000000..1ea99db1f00 --- /dev/null +++ b/onert-micro/onert-micro/include/test_models/unpack/NegUnpackKernel.h @@ -0,0 +1,90 @@ +/* + * 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_UNPACK_KERNEL_H +#define ONERT_MICRO_TEST_MODELS_NEG_UNPACK_KERNEL_H + +#include "TestDataUnpackBase.h" + +namespace onert_micro +{ +namespace test_model +{ +namespace neg_unpack_input_type_mismatch +{ + +/* + * Unpack Kernel with input type mismatch (input_type should be equal to output_type): + * + * Input(2, 2, 3, 4) - Int32 + * | + * Unpack(num=2, axis=0) + * / \ + * Output1(2, 3, 4)-Float32 Output1(2, 3, 4) - Float32 + */ +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, + 0x34, 0x00, 0x00, 0x00, 0x7c, 0x01, 0x00, 0x00, 0x98, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xf4, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0x04, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x00, 0x00, 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, 0x68, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x74, 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, 0x16, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x08, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x14, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, + 0x08, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0xd4, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x6f, 0x66, 0x6d, 0x3a, 0x31, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 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, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x6f, 0x66, 0x6d, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x04, 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, + 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x66, 0x6d, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 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, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, + 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_unpack_input_type_mismatch + +class NegTestDataInputOutputTypeMismatchUnpackKernel : public NegTestDataBase +{ +public: + NegTestDataInputOutputTypeMismatchUnpackKernel() + { + _test_kernel_model_circle = neg_unpack_input_type_mismatch::test_kernel_model_circle; + } + + ~NegTestDataInputOutputTypeMismatchUnpackKernel() 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_UNPACK_KERNEL_H diff --git a/onert-micro/onert-micro/include/test_models/unpack/TestDataUnpackBase.h b/onert-micro/onert-micro/include/test_models/unpack/TestDataUnpackBase.h new file mode 100644 index 00000000000..b7840c6afd8 --- /dev/null +++ b/onert-micro/onert-micro/include/test_models/unpack/TestDataUnpackBase.h @@ -0,0 +1,69 @@ +/* + * 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_UNPACK_KERNEL_BASE_H +#define ONERT_MICRO_TEST_MODELS_UNPACK_KERNEL_BASE_H + +#include "test_models/TestDataBase.h" +#include + +namespace onert_micro +{ +namespace test_model +{ + +template class TestDataUnpackBase : public TestDataBase +{ +public: + TestDataUnpackBase() = 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 + { + switch (i) + { + case 0: + return _reference_output_data_1; + case 1: + return _reference_output_data_2; + default: + assert(false && "Wrong input index"); + } + } + +protected: + std::vector _input_data; + std::vector _reference_output_data_1; + std::vector _reference_output_data_2; + const unsigned char *_test_kernel_model_circle; +}; + +} // namespace test_model +} // namespace onert_micro + +#endif // ONERT_MICRO_TEST_MODELS_UNPACK_KERNEL_BASE_H diff --git a/onert-micro/onert-micro/src/execute/kernels/Unpack.cpp b/onert-micro/onert-micro/src/execute/kernels/Unpack.cpp new file mode 100644 index 00000000000..cfa61f4b537 --- /dev/null +++ b/onert-micro/onert-micro/src/execute/kernels/Unpack.cpp @@ -0,0 +1,104 @@ +/* + * 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/OMKernelData.h" + +#include "execute/OMKernelExecutionBuilder.h" +#include "execute/OMUtils.h" +#include "execute/OMRuntimeKernel.h" + +#include "PALUnpack.h" + +using namespace onert_micro; +using namespace onert_micro::core; +using namespace onert_micro::execute; + +namespace +{ + +constexpr uint32_t inputTensorIdx = 0; +constexpr uint32_t outputTensorIdx = 0; + +} // namespace + +OMStatus onert_micro::execute::execute_kernel_CircleUnpack(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 *input; + const circle::Tensor *output; + + uint8_t *input_data; + + // Read kernel + const circle::UnpackOptions *options; + + core::SplitParams params{}; + { + execute::OMRuntimeKernel runtime_kernel; + OMStatus status = runtime_kernel.readKernel(op_index, runtime_context); + if (status != Ok) + return status; + + input = runtime_kernel.inputs[inputTensorIdx]; + output = runtime_kernel.outputs[outputTensorIdx]; + assert(input != nullptr); + assert(output != nullptr); + + status = runtime_kernel.getDataFromStorage(op_index, runtime_storage, runtime_context); + if (status != Ok) + return status; + + input_data = runtime_kernel.inputs_data[inputTensorIdx]; + assert(input_data != nullptr); + options = runtime_kernel.first_operator->builtin_options_as_UnpackOptions(); + + params.num_outputs = options->num(); + + for (uint32_t i = 0; i < params.num_outputs; ++i) + { + params.output_data[i] = runtime_kernel.outputs_data[i]; + } + } + OMStatus status; + OMRuntimeShape input_shape(input); + OMRuntimeShape output_shape(output); + + int32_t axis_value = options->axis(); + + switch (input->type()) + { +#ifndef DIS_FLOAT + case circle::TensorType_FLOAT32: + status = + pal::Unpack(params, input_shape, core::utils::castInputData(input_data), + output_shape, axis_value); + break; +#endif // DIS_FLOAT + default: + { + status = UnsupportedActivation; + assert(false && "Unsupported type."); + } + } + + return status; +} diff --git a/onert-micro/onert-micro/src/execute/kernels/tests/Unpack.test.cpp b/onert-micro/onert-micro/src/execute/kernels/tests/Unpack.test.cpp new file mode 100644 index 00000000000..9c5738842a5 --- /dev/null +++ b/onert-micro/onert-micro/src/execute/kernels/tests/Unpack.test.cpp @@ -0,0 +1,52 @@ +/* + * 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/unpack/FloatUnpackKernel.h" +#include "test_models/unpack/NegUnpackKernel.h" + +namespace onert_micro +{ +namespace execute +{ +namespace testing +{ + +using namespace testing; + +class UnpackTest : public ::testing::Test +{ + // Do nothing +}; + +TEST_F(UnpackTest, Float_P) +{ + onert_micro::test_model::TestDataFloatUnpack test_data_kernel; + std::vector output_data_vector = + onert_micro::execute::testing::checkKernel(1, &test_data_kernel); + EXPECT_THAT(output_data_vector, test_data_kernel.get_output_data_by_index(0)); +} + +TEST_F(UnpackTest, Input_output_type_mismatch_NEG) +{ + onert_micro::test_model::NegTestDataInputOutputTypeMismatchUnpackKernel 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/Unpack.cpp b/onert-micro/onert-micro/src/import/kernels/Unpack.cpp new file mode 100644 index 00000000000..c7536cb2b40 --- /dev/null +++ b/onert-micro/onert-micro/src/import/kernels/Unpack.cpp @@ -0,0 +1,100 @@ +/* + * 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 "import/OMKernelConfigureBuilder.h" +#include "execute/OMRuntimeKernel.h" + +using namespace onert_micro; +using namespace onert_micro::core; + +namespace +{ + +constexpr uint32_t inputTensorIdx = 0; +constexpr uint32_t outputTensorIdx = 0; + +} // namespace + +OMStatus onert_micro::import::configure_kernel_CircleUnpack(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 *input = runtime_kernel.inputs[inputTensorIdx]; + const circle::Tensor *output = runtime_kernel.outputs[outputTensorIdx]; + + assert(input != nullptr); + assert(output != nullptr); + + status = utils::checkCondition(output->type() == input->type()); + if (status != Ok) + return status; + + auto options = runtime_kernel.first_operator->builtin_options_as_UnpackOptions(); + status = utils::checkCondition(options != nullptr); + if (status != Ok) + return status; + + status = utils::checkCondition(runtime_kernel.outputs_num == options->num()); + if (status != Ok) + return status; + + // Check all outputs have the same type and shapes + OMRuntimeShape output_shape(output); + for (uint32_t i = 1; i < options->num(); ++i) + { + const circle::Tensor *cur_output = runtime_kernel.outputs[i]; + status = utils::checkCondition(output->type() == cur_output->type()); + if (status != Ok) + return status; + + OMRuntimeShape cur_output_shape(cur_output); + status = utils::checkCondition(output_shape == cur_output_shape); + if (status != Ok) + return status; + } + + // Check shapes input and output + OMRuntimeShape input_shape(input); + for (int i = 0; i < input_shape.dimensionsCount(); ++i) + { + if (i == options->axis()) + continue; + + if (i < options->axis()) + { + status = utils::checkCondition(input_shape.dims(i) == output_shape.dims(i)); + } + else + { + status = utils::checkCondition(input_shape.dims(i) == output_shape.dims(i - 1)); + } + if (status != Ok) + return status; + } + + return status; +}