From 92d1dde2cf985c8ba38902351043313e2f0bf968 Mon Sep 17 00:00:00 2001 From: Balyshev Artem <43214667+BalyshevArtem@users.noreply.github.com> Date: Mon, 2 Oct 2023 13:29:03 +0300 Subject: [PATCH] [onert-micro] Add float DepthToSpace kernels (#11622) This commit adds float DepthToSpace kernels for onert-micro. ONE-DCO-1.0-Signed-off-by: Artem Balyshev Co-authored-by: Artem Balyshev --- .../depth_to_space/FloatDepthToSpaceKernel.h | 89 ++++++++++++++ .../depth_to_space/NegDepthToSpaceKernel.h | 87 ++++++++++++++ .../depth_to_space/TestDataDepthToSpaceBase.h | 60 ++++++++++ .../pal/cmsisnn/KernelsToBuild.lst | 1 + .../pal/common/PALDepthToSpace.h | 70 +++++++++++ .../pal/mcu/KernelsToBuild.lst | 1 + .../src/kernels/DepthToSpace.cpp | 87 +++++++------- .../src/kernels/DepthToSpace.h | 45 ------- .../src/kernels/DepthToSpace.test.cpp | 112 +++++++----------- 9 files changed, 393 insertions(+), 159 deletions(-) create mode 100644 onert-micro/luci-interpreter/include/luci_interpreter/test_models/depth_to_space/FloatDepthToSpaceKernel.h create mode 100644 onert-micro/luci-interpreter/include/luci_interpreter/test_models/depth_to_space/NegDepthToSpaceKernel.h create mode 100644 onert-micro/luci-interpreter/include/luci_interpreter/test_models/depth_to_space/TestDataDepthToSpaceBase.h create mode 100644 onert-micro/luci-interpreter/pal/common/PALDepthToSpace.h delete mode 100644 onert-micro/luci-interpreter/src/kernels/DepthToSpace.h diff --git a/onert-micro/luci-interpreter/include/luci_interpreter/test_models/depth_to_space/FloatDepthToSpaceKernel.h b/onert-micro/luci-interpreter/include/luci_interpreter/test_models/depth_to_space/FloatDepthToSpaceKernel.h new file mode 100644 index 00000000000..44e43c092ed --- /dev/null +++ b/onert-micro/luci-interpreter/include/luci_interpreter/test_models/depth_to_space/FloatDepthToSpaceKernel.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2023 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 LUCI_INTERPRETER_TEST_MODELS_FLOAT_DEPTH_TO_SPACE_KERNEL_H +#define LUCI_INTERPRETER_TEST_MODELS_FLOAT_DEPTH_TO_SPACE_KERNEL_H + +#include "TestDataDepthToSpaceBase.h" + +namespace luci_interpreter +{ +namespace test_kernel +{ +namespace depth_to_space_float +{ +/* + * DepthToSpace Kernel: + * + * Input(1, 2, 2, 4) + * | + * DepthToSpace + * | + * Output(1, 4, 4, 1) + */ +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, + 0x2c, 0x00, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00, 0x4c, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 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, + 0x64, 0x00, 0x00, 0x00, 0x68, 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, 0x16, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x08, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x14, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xd4, 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, + 0x04, 0x00, 0x00, 0x00, 0x04, 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, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x66, 0x6d, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 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, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 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 = { + -88.77164, 8.495978, -2.749088, 73.70849, -68.09995, 67.459724, -14.851314, 25.076237, + -31.075678, 50.127613, 72.91088, 18.95467, 39.1749, -40.51118, 20.050987, -9.049585}; +const std::vector reference_output_data = { + -88.77164, 8.495978, -68.09995, 67.459724, -2.749088, 73.70849, -14.851314, 25.076237, + -31.075678, 50.127613, 39.1749, -40.51118, 72.91088, 18.95467, 20.050987, -9.049585}; + +} // namespace depth_to_space_float + +class TestDataFloatDepthToSpace : public TestDataDepthToSpaceBase +{ +public: + TestDataFloatDepthToSpace() + { + _input_data = depth_to_space_float::input_data; + _reference_output_data = depth_to_space_float::reference_output_data; + _test_kernel_model_circle = depth_to_space_float::test_kernel_model_circle; + } + + ~TestDataFloatDepthToSpace() override = default; +}; + +} // namespace test_kernel +} // namespace luci_interpreter + +#endif // LUCI_INTERPRETER_TEST_MODELS_FLOAT_DEPTH_TO_SPACE_KERNEL_H diff --git a/onert-micro/luci-interpreter/include/luci_interpreter/test_models/depth_to_space/NegDepthToSpaceKernel.h b/onert-micro/luci-interpreter/include/luci_interpreter/test_models/depth_to_space/NegDepthToSpaceKernel.h new file mode 100644 index 00000000000..c418ceaff63 --- /dev/null +++ b/onert-micro/luci-interpreter/include/luci_interpreter/test_models/depth_to_space/NegDepthToSpaceKernel.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2023 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 LUCI_INTERPRETER_TEST_MODELS_NEG_DEPTH_TO_SPACE_KERNEL_H +#define LUCI_INTERPRETER_TEST_MODELS_NEG_DEPTH_TO_SPACE_KERNEL_H + +#include "luci_interpreter/test_models/TestDataBase.h" + +namespace luci_interpreter +{ +namespace test_kernel +{ +namespace neg_input_output_type_mismatch_depth_to_space_kernel +{ +/* + * DepthToSpace kernel with input output type mismatch: + * + * Input(1, 2, 2, 4) - Float32 + * | + * DepthToSpace + * | + * Output(1, 4, 4, 1) - Int32 + */ +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, + 0x2c, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 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, + 0x64, 0x00, 0x00, 0x00, 0x68, 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, 0x16, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x08, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x14, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x10, 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, 0x0c, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x6f, 0x66, 0x6d, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x04, 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, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x66, 0x6d, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 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, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 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_depth_to_space_kernel + +class NegTestDataInputOutputTypeMismatchDepthToSpaceKernel : public NegTestDataBase +{ +public: + NegTestDataInputOutputTypeMismatchDepthToSpaceKernel() + { + _test_kernel_model_circle = + neg_input_output_type_mismatch_depth_to_space_kernel::test_kernel_model_circle; + } + + ~NegTestDataInputOutputTypeMismatchDepthToSpaceKernel() 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_kernel +} // namespace luci_interpreter + +#endif // LUCI_INTERPRETER_TEST_MODELS_NEG_DEPTH_TO_SPACE_KERNEL_H diff --git a/onert-micro/luci-interpreter/include/luci_interpreter/test_models/depth_to_space/TestDataDepthToSpaceBase.h b/onert-micro/luci-interpreter/include/luci_interpreter/test_models/depth_to_space/TestDataDepthToSpaceBase.h new file mode 100644 index 00000000000..e8c48a1f506 --- /dev/null +++ b/onert-micro/luci-interpreter/include/luci_interpreter/test_models/depth_to_space/TestDataDepthToSpaceBase.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023 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 LUCI_INTERPRETER_TEST_MODELS_DEPTH_TO_SPACE_KERNEL_BASE_H +#define LUCI_INTERPRETER_TEST_MODELS_DEPTH_TO_SPACE_KERNEL_BASE_H + +#include "luci_interpreter/test_models/TestDataBase.h" + +namespace luci_interpreter +{ +namespace test_kernel +{ + +template class TestDataDepthToSpaceBase : public TestDataBase +{ +public: + TestDataDepthToSpaceBase() = 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_kernel +} // namespace luci_interpreter + +#endif // LUCI_INTERPRETER_TEST_MODELS_DEPTH_TO_SPACE_KERNEL_BASE_H diff --git a/onert-micro/luci-interpreter/pal/cmsisnn/KernelsToBuild.lst b/onert-micro/luci-interpreter/pal/cmsisnn/KernelsToBuild.lst index 6e8ec181d56..a2249f99d54 100644 --- a/onert-micro/luci-interpreter/pal/cmsisnn/KernelsToBuild.lst +++ b/onert-micro/luci-interpreter/pal/cmsisnn/KernelsToBuild.lst @@ -5,6 +5,7 @@ REGISTER_KERNEL(ARG_MAX, ArgMax) REGISTER_KERNEL(ARG_MIN, ArgMin) REGISTER_KERNEL(BATCH_TO_SPACE_ND, BatchToSpaceND) REGISTER_KERNEL(DIV, Div) +REGISTER_KERNEL(DEPTH_TO_SPACE, DepthToSpace) REGISTER_KERNEL(DEQUANTIZE, Dequantize) REGISTER_KERNEL(ADD_N, AddN) REGISTER_KERNEL(CONV_2D, Conv2D) diff --git a/onert-micro/luci-interpreter/pal/common/PALDepthToSpace.h b/onert-micro/luci-interpreter/pal/common/PALDepthToSpace.h new file mode 100644 index 00000000000..5f98c8820c3 --- /dev/null +++ b/onert-micro/luci-interpreter/pal/common/PALDepthToSpace.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2023 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 LUCI_INTERPRETER_PAL_DEPTH_TO_SPACE_COMMON_H +#define LUCI_INTERPRETER_PAL_DEPTH_TO_SPACE_COMMON_H + +#include "PALUtils.h" + +#include + +namespace luci_interpreter_pal +{ + +template +inline void +DepthToSpace(const int32_t block_size, const luci_interpreter::RuntimeShape &unextended_input_shape, + const T *input_data, const luci_interpreter::RuntimeShape &unextended_output_shape, + T *output_data) +{ + const luci_interpreter::RuntimeShape input_shape = + luci_interpreter::RuntimeShape::extendedShape(4, unextended_input_shape); + const luci_interpreter::RuntimeShape output_shape = + luci_interpreter::RuntimeShape::extendedShape(4, unextended_output_shape); + + const int output_depth = output_shape.dims(3); + const int output_width = output_shape.dims(2); + const int output_height = output_shape.dims(1); + const int output_batch = output_shape.dims(0); + + for (int out_b = 0; out_b < output_batch; ++out_b) + { + 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) + { + const int in_d = + out_d + ((out_h % block_size) * block_size + out_w % block_size) * output_depth; + + const int in_w = out_w / block_size; + const int in_h = out_h / block_size; + const int in_b = out_b; + + const int input_index = offset(input_shape.dimsData(), in_b, in_h, in_w, in_d); + const int output_index = offset(output_shape.dimsData(), out_b, out_h, out_w, out_d); + + output_data[output_index] = input_data[input_index]; + } + } + } + } +} + +} // namespace luci_interpreter_pal + +#endif // LUCI_INTERPRETER_PAL_DEPTH_TO_SPACE_COMMON_H diff --git a/onert-micro/luci-interpreter/pal/mcu/KernelsToBuild.lst b/onert-micro/luci-interpreter/pal/mcu/KernelsToBuild.lst index 76846830fa8..63a55fa2025 100644 --- a/onert-micro/luci-interpreter/pal/mcu/KernelsToBuild.lst +++ b/onert-micro/luci-interpreter/pal/mcu/KernelsToBuild.lst @@ -6,6 +6,7 @@ REGISTER_KERNEL(ARG_MIN, ArgMin) REGISTER_KERNEL(BATCH_TO_SPACE_ND, BatchToSpaceND) REGISTER_KERNEL(DIV, Div) REGISTER_KERNEL(DEPTHWISE_CONV_2D, DepthwiseConv2D) +REGISTER_KERNEL(DEPTH_TO_SPACE, DepthToSpace) REGISTER_KERNEL(DEQUANTIZE, Dequantize) REGISTER_KERNEL(ADD_N, AddN) REGISTER_KERNEL(FULLY_CONNECTED, FullyConnected) diff --git a/onert-micro/luci-interpreter/src/kernels/DepthToSpace.cpp b/onert-micro/luci-interpreter/src/kernels/DepthToSpace.cpp index 937958ba84a..c8ab72d2933 100644 --- a/onert-micro/luci-interpreter/src/kernels/DepthToSpace.cpp +++ b/onert-micro/luci-interpreter/src/kernels/DepthToSpace.cpp @@ -14,68 +14,67 @@ * limitations under the License. */ -#include "DepthToSpace.h" -#include "Utils.h" +#include "Builders.h" +#include "kernels/Utils.h" +#include "SISOKernel.h" + #include "PALDepthToSpace.h" namespace luci_interpreter { -namespace kernels -{ -DepthToSpace::DepthToSpace(const Tensor *input, Tensor *output, const DepthToSpaceParams ¶ms) - : KernelWithParams({input}, {output}, params) +void configure_kernel_CircleDepthToSpace(const circle::Operator *cur_op, + BaseRuntimeGraph *runtime_graph) { -} + kernels::SISOKernel kernel(cur_op, runtime_graph); -void DepthToSpace::configure() -{ - LUCI_INTERPRETER_CHECK(input()->shape().num_dims() == 4); - LUCI_INTERPRETER_CHECK(output()->element_type() == DataType::FLOAT32 || - output()->element_type() == DataType::U8) - LUCI_INTERPRETER_CHECK(input()->element_type() == output()->element_type()) - const int block_size = params().block_size; - const int32_t input_height = input()->shape().dim(1); - const int32_t input_width = input()->shape().dim(2); - const int32_t input_channels = input()->shape().dim(3); - int32_t output_height = input_height * block_size; - int32_t output_width = input_width * block_size; - int32_t output_channels = input_channels / block_size / block_size; + LUCI_INTERPRETER_CHECK(Tensor::element_type(kernel.input()) == + Tensor::element_type(kernel.output())); + + const auto *options = cur_op->builtin_options_as_DepthToSpaceOptions(); + + const int32_t block_size = options->block_size(); + LUCI_INTERPRETER_CHECK(block_size > 0); + + constexpr int kHeightRank = 1; + constexpr int kWidthRank = 2; + constexpr int kDepthRank = 3; + + const int input_height = Tensor::dim(kernel.input(), kHeightRank); + const int input_width = Tensor::dim(kernel.input(), kWidthRank); + const int input_channels = Tensor::dim(kernel.input(), kDepthRank); + int output_height = input_height * block_size; + int output_width = input_width * block_size; + int output_channels = input_channels / block_size / block_size; LUCI_INTERPRETER_CHECK(input_height == output_height / block_size); LUCI_INTERPRETER_CHECK(input_width == output_width / block_size); LUCI_INTERPRETER_CHECK(input_channels == output_channels * block_size * block_size); - - Shape output_shape(4); - output_shape.dim(0) = input()->shape().dim(0); - output_shape.dim(1) = output_height; - output_shape.dim(2) = output_width; - output_shape.dim(3) = output_channels; - - // TODO: enable it only if kernel with dynamic shapes - output()->resize(output_shape); } -void DepthToSpace::execute() const +void execute_kernel_CircleDepthToSpace(const circle::Operator *cur_op, + BaseRuntimeGraph *runtime_graph) { - tflite::DepthToSpaceParams op_params; - op_params.block_size = params().block_size; - switch (input()->element_type()) + kernels::SISOKernel kernel(cur_op, runtime_graph); + + const auto *options = cur_op->builtin_options_as_DepthToSpaceOptions(); + const int32_t block_size = options->block_size(); + + switch (Tensor::element_type(kernel.input())) { +#ifndef DIS_FLOAT case DataType::FLOAT32: - luci_interpreter_pal::DepthToSpace(op_params, getTensorShape(input()), - getTensorData(input()), getTensorShape(output()), - getTensorData(output())); - break; - case DataType::U8: - luci_interpreter_pal::DepthToSpace(op_params, getTensorShape(input()), - getTensorData(input()), getTensorShape(output()), - getTensorData(output())); + { + luci_interpreter_pal::DepthToSpace( + block_size, kernels::getTensorRuntimeShape(kernel.input(), runtime_graph), + kernels::getTensorData(runtime_graph->getDataByTensor(kernel.input())), + kernels::getTensorRuntimeShape(kernel.output(), runtime_graph), + kernels::getTensorData(runtime_graph->getDataByTensor(kernel.output()))); break; + } +#endif // DIS_FLOAT default: - assert(false && "Unsupported Type."); + assert(false && "Unsupported type"); } } - -} // namespace kernels } // namespace luci_interpreter diff --git a/onert-micro/luci-interpreter/src/kernels/DepthToSpace.h b/onert-micro/luci-interpreter/src/kernels/DepthToSpace.h deleted file mode 100644 index 63ce3761077..00000000000 --- a/onert-micro/luci-interpreter/src/kernels/DepthToSpace.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2020 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 LUCI_INTERPRETER_KERNELS_DEPTHTOSPACE_H -#define LUCI_INTERPRETER_KERNELS_DEPTHTOSPACE_H - -#include "core/Kernel.h" -#include "core/KernelParams.h" - -#include - -namespace luci_interpreter -{ -namespace kernels -{ - -class DepthToSpace : public KernelWithParams -{ -public: - DepthToSpace(const Tensor *input, Tensor *output, const DepthToSpaceParams ¶ms); - - const Tensor *input() const { return _inputs[0]; } - Tensor *output() const { return _outputs[0]; } - - void configure() override; - void execute() const override; -}; - -} // namespace kernels -} // namespace luci_interpreter - -#endif // LUCI_INTERPRETER_KERNELS_DEPTHTOSPACE_H diff --git a/onert-micro/luci-interpreter/src/kernels/DepthToSpace.test.cpp b/onert-micro/luci-interpreter/src/kernels/DepthToSpace.test.cpp index 88e6e07f1d9..f0dc2ce0059 100644 --- a/onert-micro/luci-interpreter/src/kernels/DepthToSpace.test.cpp +++ b/onert-micro/luci-interpreter/src/kernels/DepthToSpace.test.cpp @@ -14,102 +14,74 @@ * limitations under the License. */ -#include "kernels/DepthToSpace.h" #include "kernels/TestUtils.h" -#include "luci_interpreter/TestMemoryManager.h" +#include "luci_interpreter/test_models/depth_to_space/FloatDepthToSpaceKernel.h" +#include "luci_interpreter/test_models/depth_to_space/NegDepthToSpaceKernel.h" + +#include "loader/ModuleLoader.h" namespace luci_interpreter { -namespace kernels -{ namespace { using namespace testing; -template class DepthToSpaceTest : public ::testing::Test +class DepthToSpaceTest : public ::testing::Test { + // Do nothing }; -using DataTypes = ::testing::Types; -TYPED_TEST_SUITE(DepthToSpaceTest, DataTypes); - -TYPED_TEST(DepthToSpaceTest, SimpleCase) +template +std::vector checkDepthToSpaceKernel(test_kernel::TestDataBase *test_data_base) { - std::unique_ptr memory_manager = std::make_unique(); - std::vector input_data{1, 2, 3, 4, 5, 6, 7, 8}; - Shape input_shape{1, 1, 2, 4}; - std::vector output_data{1, 2, 5, 6, 3, 4, 7, 8}; - std::vector output_shape{1, 2, 4, 1}; - - Tensor input_tensor = - makeInputTensor()>(input_shape, input_data, memory_manager.get()); - Tensor output_tensor = makeOutputTensor(getElementType()); + MemoryManager memory_manager{}; + RuntimeModule runtime_module{}; + bool dealloc_input = true; - DepthToSpaceParams params{}; - params.block_size = 2; + // Load model with single op + auto *model_data_raw = reinterpret_cast(test_data_base->get_model_ptr()); + ModuleLoader::load(&runtime_module, &memory_manager, model_data_raw, dealloc_input); - DepthToSpace kernel = DepthToSpace(&input_tensor, &output_tensor, params); - kernel.configure(); - memory_manager->allocate_memory(output_tensor); - kernel.execute(); + auto *main_runtime_graph = runtime_module.getMainGraph(); + assert(main_runtime_graph->getNumOfInputTensors() == 1); - EXPECT_THAT(extractTensorData(output_tensor), - ::testing::ElementsAreArray(output_data)); - EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape)); -} - -TEST(DepthToSpaceTest, InvalidInputShape_NEG) -{ - std::unique_ptr memory_manager = std::make_unique(); - std::vector input_data{1, 2, 3, 4, 5, 6, 7, 8}; - Shape input_shape{1, 2, 4}; + // Set input data + { + auto *input_tensor_data = reinterpret_cast(main_runtime_graph->configureGraphInput(0)); + std::copy(test_data_base->get_input_data_by_index(0).begin(), + test_data_base->get_input_data_by_index(0).end(), input_tensor_data); + } - Tensor input_tensor = - makeInputTensor(input_shape, input_data, memory_manager.get()); - Tensor output_tensor = makeOutputTensor(DataType::FLOAT32); + runtime_module.execute(); - DepthToSpaceParams params{}; - params.block_size = 2; + assert(main_runtime_graph->getNumOfOutputTensors() == 1); - DepthToSpace kernel = DepthToSpace(&input_tensor, &output_tensor, params); - EXPECT_ANY_THROW(kernel.configure()); + T *output_data = reinterpret_cast(main_runtime_graph->getOutputDataByIndex(0)); + const size_t num_elements = (main_runtime_graph->getOutputDataSizeByIndex(0) / sizeof(T)); + std::vector output_data_vector(output_data, output_data + num_elements); + return output_data_vector; } -TEST(DepthToSpaceTest, InOutTypeMismatch_NEG) +TEST_F(DepthToSpaceTest, Float_P) { - std::unique_ptr memory_manager = std::make_unique(); - std::vector input_data{1, 2, 3, 4, 5, 6, 7, 8}; - Shape input_shape{1, 1, 2, 4}; - - Tensor input_tensor = - makeInputTensor(input_shape, input_data, memory_manager.get()); - Tensor output_tensor = makeOutputTensor(DataType::U8); - - DepthToSpaceParams params{}; - params.block_size = 2; - - DepthToSpace kernel = DepthToSpace(&input_tensor, &output_tensor, params); - EXPECT_ANY_THROW(kernel.configure()); + test_kernel::TestDataFloatDepthToSpace test_data_kernel; + std::vector output_data_vector = checkDepthToSpaceKernel(&test_data_kernel); + EXPECT_THAT(output_data_vector, kernels::testing::FloatArrayNear( + test_data_kernel.get_output_data_by_index(0), 0.0001f)); } -TEST(DepthToSpaceTest, InvalidBlockSize_NEG) +TEST_F(DepthToSpaceTest, Input_output_type_mismatch_NEG) { - std::unique_ptr memory_manager = std::make_unique(); - std::vector input_data{1, 2, 3, 4, 5, 6, 7, 8}; - Shape input_shape{1, 1, 2, 4}; - - Tensor input_tensor = - makeInputTensor(input_shape, input_data, memory_manager.get()); - Tensor output_tensor = makeOutputTensor(DataType::FLOAT32); - - DepthToSpaceParams params{}; - params.block_size = 3; - - DepthToSpace kernel = DepthToSpace(&input_tensor, &output_tensor, params); - EXPECT_ANY_THROW(kernel.configure()); + test_kernel::NegTestDataInputOutputTypeMismatchDepthToSpaceKernel test_data_kernel; + MemoryManager memory_manager{}; + RuntimeModule runtime_module{}; + bool dealloc_input = true; + // Load model with single op + auto *model_data_raw = reinterpret_cast(test_data_kernel.get_model_ptr()); + EXPECT_DEATH(ModuleLoader::load(&runtime_module, &memory_manager, model_data_raw, dealloc_input), + ""); } } // namespace -} // namespace kernels } // namespace luci_interpreter