From 1090a4ce53f416a32439417194a7af3146f535a2 Mon Sep 17 00:00:00 2001 From: Vyacheslav Bazhenov Date: Thu, 21 Sep 2023 15:50:02 +0300 Subject: [PATCH] [onert-micro] Introduce Floor kernel This commit introduces Floor kernel. ONE-DCO-1.0-Signed-off-by: Vyacheslav Bazhenov --- .../test_models/floor/FloatFloorKernel.h | 85 +++++++++++ .../test_models/floor/NegFloorKernel.h | 143 ++++++++++++++++++ .../test_models/floor/TestDataFloorBase.h | 60 ++++++++ .../pal/common/PALFloorCommon.h | 47 ++++++ .../pal/mcu/KernelsToBuild.lst | 1 + .../luci-interpreter/pal/mcu/PALFloor.h | 27 ++++ .../luci-interpreter/src/kernels/Floor.cpp | 69 ++++++--- .../luci-interpreter/src/kernels/Floor.h | 45 ------ .../src/kernels/Floor.test.cpp | 102 ++++++++----- 9 files changed, 473 insertions(+), 106 deletions(-) create mode 100644 onert-micro/luci-interpreter/include/luci_interpreter/test_models/floor/FloatFloorKernel.h create mode 100644 onert-micro/luci-interpreter/include/luci_interpreter/test_models/floor/NegFloorKernel.h create mode 100644 onert-micro/luci-interpreter/include/luci_interpreter/test_models/floor/TestDataFloorBase.h create mode 100644 onert-micro/luci-interpreter/pal/common/PALFloorCommon.h create mode 100644 onert-micro/luci-interpreter/pal/mcu/PALFloor.h delete mode 100644 onert-micro/luci-interpreter/src/kernels/Floor.h diff --git a/onert-micro/luci-interpreter/include/luci_interpreter/test_models/floor/FloatFloorKernel.h b/onert-micro/luci-interpreter/include/luci_interpreter/test_models/floor/FloatFloorKernel.h new file mode 100644 index 00000000000..4d88b7772ff --- /dev/null +++ b/onert-micro/luci-interpreter/include/luci_interpreter/test_models/floor/FloatFloorKernel.h @@ -0,0 +1,85 @@ +/* + * 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_FLOOR_KERNEL_H +#define LUCI_INTERPRETER_TEST_MODELS_FLOAT_FLOOR_KERNEL_H + +#include "TestDataFloorBase.h" + +namespace luci_interpreter +{ +namespace test_kernel +{ +namespace floor_float +{ +/* + * Floor Kernel: + * + * Input(2, 3) + * | + * Floor + * | + * Output(2, 3) + */ +unsigned char test_kernel_model_circle[] = { + 0x1c, 0x00, 0x00, 0x00, 0x43, 0x49, 0x52, 0x30, 0x00, 0x00, 0x12, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, + 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x70, 0x61, + 0x63, 0x6b, 0x61, 0x67, 0x65, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x14, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xd8, 0xff, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x6f, 0x66, 0x6d, 0x00, 0xbc, 0xff, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x66, 0x6d, 0x00, 0xf0, 0xff, 0xff, 0xff, + 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x00, 0x00}; + +const std::vector input_data = {7.297842, 30.999863, 15.692827, + -18.824865, 22.614136, 5.7466774}; + +const std::vector reference_output_data = {7, 30, 15, -19, 22, 5}; + +} // namespace floor_float + +class TestDataFloatFloor : public TestDataFloorBase +{ +public: + TestDataFloatFloor() + { + _input_data = floor_float::input_data; + _reference_output_data = floor_float::reference_output_data; + _test_kernel_model_circle = floor_float::test_kernel_model_circle; + } + + ~TestDataFloatFloor() override = default; +}; + +} // namespace test_kernel +} // namespace luci_interpreter + +#endif // LUCI_INTERPRETER_TEST_MODELS_FLOAT_FLOOR_KERNEL_H diff --git a/onert-micro/luci-interpreter/include/luci_interpreter/test_models/floor/NegFloorKernel.h b/onert-micro/luci-interpreter/include/luci_interpreter/test_models/floor/NegFloorKernel.h new file mode 100644 index 00000000000..37b023ffd86 --- /dev/null +++ b/onert-micro/luci-interpreter/include/luci_interpreter/test_models/floor/NegFloorKernel.h @@ -0,0 +1,143 @@ +/* + * 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_FLOOR_KERNEL_H +#define LUCI_INTERPRETER_TEST_MODELS_NEG_FLOOR_KERNEL_H + +#include "TestDataFloorBase.h" + +namespace luci_interpreter +{ +namespace test_kernel +{ +namespace neg_input_output_type_mismatch_floor_kernel +{ +/* + * Floor Kernel with input output type mismatch (should be equal): + * + * Input(2, 3) - Uint8 + * | + * Floor + * | + * Output(2, 3) - 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, + 0x2c, 0x00, 0x00, 0x00, 0x64, 0x01, 0x00, 0x00, 0x80, 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, + 0x48, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x0c, 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, 0x48, 0x00, 0x00, 0x00, + 0x10, 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, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x14, 0x00, 0x13, 0x00, 0x0c, 0x00, + 0x08, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x54, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x14, 0x00, + 0x04, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x81, 0x80, 0x00, 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xbf, 0x03, 0x00, 0x00, 0x00, 0x69, 0x66, 0x6d, 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, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 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_floor_kernel + +namespace neg_invalid_input_output_shape_floor_kernel +{ +/* + * Floor Kernel with different input output shapes: + * + * Input(1, 2, 3) + * | + * Floor + * | + * 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, + 0x2c, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x24, 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, + 0x48, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x0c, 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, 0x38, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0xdc, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x02, 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, 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, 0x03, 0x00, 0x00, 0x00, + 0x01, 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, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 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_invalid_input_output_shape_floor_kernel + +class NegTestDataInputOutputTypeMismatchFloorKernel : public NegTestDataBase +{ +public: + NegTestDataInputOutputTypeMismatchFloorKernel() + { + _test_kernel_model_circle = + neg_input_output_type_mismatch_floor_kernel::test_kernel_model_circle; + } + + ~NegTestDataInputOutputTypeMismatchFloorKernel() override = default; + + const unsigned char *get_model_ptr() override final { return _test_kernel_model_circle; } + +protected: + const unsigned char *_test_kernel_model_circle; +}; + +class NegTestDataInvalidInputOutputShapeFloorKernel : public NegTestDataBase +{ +public: + NegTestDataInvalidInputOutputShapeFloorKernel() + { + _test_kernel_model_circle = + neg_invalid_input_output_shape_floor_kernel::test_kernel_model_circle; + } + + ~NegTestDataInvalidInputOutputShapeFloorKernel() 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_FLOOR_KERNEL_H diff --git a/onert-micro/luci-interpreter/include/luci_interpreter/test_models/floor/TestDataFloorBase.h b/onert-micro/luci-interpreter/include/luci_interpreter/test_models/floor/TestDataFloorBase.h new file mode 100644 index 00000000000..c0a32f9cd0f --- /dev/null +++ b/onert-micro/luci-interpreter/include/luci_interpreter/test_models/floor/TestDataFloorBase.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_FLOOR_KERNEL_BASE_H +#define LUCI_INTERPRETER_TEST_MODELS_FLOOR_KERNEL_BASE_H + +#include "luci_interpreter/test_models/TestDataBase.h" + +namespace luci_interpreter +{ +namespace test_kernel +{ + +template class TestDataFloorBase : public TestDataBase +{ +public: + TestDataFloorBase() = 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_FLOOR_KERNEL_BASE_H diff --git a/onert-micro/luci-interpreter/pal/common/PALFloorCommon.h b/onert-micro/luci-interpreter/pal/common/PALFloorCommon.h new file mode 100644 index 00000000000..e8334782674 --- /dev/null +++ b/onert-micro/luci-interpreter/pal/common/PALFloorCommon.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023 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. + */ + +#ifndef LUCI_INTERPRETER_PAL_FLOOR_COMMON_H +#define LUCI_INTERPRETER_PAL_FLOOR_COMMON_H + +#include + +namespace luci_interpreter_pal +{ +inline void Floor(const luci_interpreter::RuntimeShape &input_shape, const float *input_data, + const luci_interpreter::RuntimeShape &output_shape, float *output_data) +{ + // check that input and output dimensions are equal + int N = input_shape.dimensionsCount(); + assert(N == output_shape.dimensionsCount()); + + // check that sizes of all dimensions are equal + for (int i = 0; i < N; ++i) + { + assert(input_shape.dims(i) == output_shape.dims(i)); + } + + const int flat_size = input_shape.flatSize(); + for (int i = 0; i < flat_size; i++) + { + int offset = i; + output_data[offset] = std::floor(input_data[offset]); + } +} +} // namespace luci_interpreter_pal + +#endif // LUCI_INTERPRETER_PAL_FLOOR_COMMON_H diff --git a/onert-micro/luci-interpreter/pal/mcu/KernelsToBuild.lst b/onert-micro/luci-interpreter/pal/mcu/KernelsToBuild.lst index c8179dea19e..b6fbcba8d0c 100644 --- a/onert-micro/luci-interpreter/pal/mcu/KernelsToBuild.lst +++ b/onert-micro/luci-interpreter/pal/mcu/KernelsToBuild.lst @@ -17,6 +17,7 @@ REGISTER_KERNEL(EXPAND_DIMS, ExpandDims) REGISTER_KERNEL(ELU, Elu) REGISTER_KERNEL(EQUAL, Equal) REGISTER_KERNEL(FILL, Fill) +REGISTER_KERNEL(FLOOR, Floor) REGISTER_KERNEL(PACK, Pack) REGISTER_KERNEL(PAD, Pad) REGISTER_KERNEL(PADV2, PadV2) diff --git a/onert-micro/luci-interpreter/pal/mcu/PALFloor.h b/onert-micro/luci-interpreter/pal/mcu/PALFloor.h new file mode 100644 index 00000000000..1f8aca21456 --- /dev/null +++ b/onert-micro/luci-interpreter/pal/mcu/PALFloor.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 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. + */ + +#ifndef LUCI_INTERPRETER_PAL_FLOOR_H +#define LUCI_INTERPRETER_PAL_FLOOR_H + +#include "PALFloorCommon.h" + +namespace luci_interpreter_pal +{ +} // namespace luci_interpreter_pal + +#endif // LUCI_INTERPRETER_PAL_FLOOR_H diff --git a/onert-micro/luci-interpreter/src/kernels/Floor.cpp b/onert-micro/luci-interpreter/src/kernels/Floor.cpp index f7871b5c8c6..6a45deb5c04 100644 --- a/onert-micro/luci-interpreter/src/kernels/Floor.cpp +++ b/onert-micro/luci-interpreter/src/kernels/Floor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved + * Copyright (c) 2023 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"); @@ -15,44 +15,69 @@ * limitations under the License. */ -#include "kernels/Floor.h" +#include "Builders.h" #include "kernels/Utils.h" -#include +#include "PALFloor.h" namespace luci_interpreter { - -namespace kernels +void configure_kernel_CircleFloor(const circle::Operator *cur_op, BaseRuntimeGraph *runtime_graph) { + const auto input_index = cur_op->inputs()->operator[](0); + const auto output_index = cur_op->outputs()->operator[](0); -Floor::Floor(const Tensor *input, Tensor *output) : Kernel({input}, {output}) {} + assert(input_index != -1); + assert(output_index != -1); -void Floor::configure() -{ - LUCI_INTERPRETER_CHECK(input()->element_type() == output()->element_type()); - // TODO: enable it only if kernel with dynamic shapes - output()->resize(input()->shape()); + const auto input = runtime_graph->getCircleTensorByIndex(input_index); + const auto output = runtime_graph->getCircleTensorByIndex(output_index); + + LUCI_INTERPRETER_CHECK(Tensor::element_type(input) == Tensor::element_type(output)); + // check that input and output dimensions are equal + int N = kernels::getTensorShape(input).dimensionsCount(); + LUCI_INTERPRETER_CHECK(N == kernels::getTensorShape(output).dimensionsCount()); + + // check that sizes of all dimensions are equal + for (int i = 0; i < N; ++i) + { + LUCI_INTERPRETER_CHECK(kernels::getTensorShape(input).dims(i) == + kernels::getTensorShape(output).dims(i)); + } } -void Floor::execute() const +void execute_kernel_CircleFloor(const circle::Operator *cur_op, BaseRuntimeGraph *runtime_graph) { - switch (input()->element_type()) + + const auto input_index = cur_op->inputs()->operator[](0); + const auto output_index = cur_op->outputs()->operator[](0); + + assert(input_index != -1); + assert(output_index != -1); + + const auto input = runtime_graph->getCircleTensorByIndex(input_index); + const auto output = runtime_graph->getCircleTensorByIndex(output_index); + + const uint8_t *input_data = runtime_graph->getDataByTensor(input); + uint8_t *output_data = runtime_graph->getDataByTensor(output); + + assert(input_data != nullptr); + assert(output_data != nullptr); + + switch (Tensor::element_type(input)) { +#ifndef DIS_FLOAT case DataType::FLOAT32: - evalFloat(); - break; + luci_interpreter_pal::Floor( + kernels::getTensorShape(input), kernels::getTensorData(input_data), + kernels::getTensorShape(output), kernels::getTensorData(output_data)); + + break; +#endif // DIS_FLOAT default: assert(false && "Unsupported type."); } } -void Floor::evalFloat() const -{ - tflite::reference_ops::Floor(getTensorShape(input()), getTensorData(input()), - getTensorShape(output()), getTensorData(output())); -} - -} // namespace kernels } // namespace luci_interpreter diff --git a/onert-micro/luci-interpreter/src/kernels/Floor.h b/onert-micro/luci-interpreter/src/kernels/Floor.h deleted file mode 100644 index ca3ad5997c9..00000000000 --- a/onert-micro/luci-interpreter/src/kernels/Floor.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_FLOOR_H -#define LUCI_INTERPRETER_KERNELS_FLOOR_H - -#include "core/Kernel.h" - -namespace luci_interpreter -{ -namespace kernels -{ - -class Floor : public Kernel -{ -public: - Floor(const Tensor *input, Tensor *output); - - const Tensor *input() const { return _inputs[0]; } - Tensor *output() const { return _outputs[0]; } - - void configure() override; - void execute() const override; - -private: - void evalFloat() const; -}; - -} // namespace kernels -} // namespace luci_interpreter - -#endif // LUCI_INTERPRETER_KERNELS_FLOOR_H diff --git a/onert-micro/luci-interpreter/src/kernels/Floor.test.cpp b/onert-micro/luci-interpreter/src/kernels/Floor.test.cpp index 30076fb54b1..42765c7b798 100644 --- a/onert-micro/luci-interpreter/src/kernels/Floor.test.cpp +++ b/onert-micro/luci-interpreter/src/kernels/Floor.test.cpp @@ -1,5 +1,6 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved + * Copyright (c) 2021 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. @@ -14,14 +15,14 @@ * limitations under the License. */ -#include "kernels/Floor.h" #include "kernels/TestUtils.h" -#include "luci_interpreter/TestMemoryManager.h" +#include "luci_interpreter/test_models/floor/FloatFloorKernel.h" +#include "luci_interpreter/test_models/floor/NegFloorKernel.h" + +#include "loader/ModuleLoader.h" namespace luci_interpreter { -namespace kernels -{ namespace { @@ -29,48 +30,71 @@ using namespace testing; class FloorTest : public ::testing::Test { -protected: - void SetUp() override { _memory_manager = std::make_unique(); } - - std::unique_ptr _memory_manager; + // Do nothing }; -TEST_F(FloorTest, SimpleFloat) +template std::vector checkFloorKernel(test_kernel::TestDataBase *test_data_base) +{ + MemoryManager memory_manager{}; + RuntimeModule runtime_module{}; + bool dealloc_input = true; + + // 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); + + auto *main_runtime_graph = runtime_module.getMainGraph(); + assert(main_runtime_graph->getNumOfInputTensors() == 1); + + // 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); + } + + runtime_module.execute(); + + assert(main_runtime_graph->getNumOfOutputTensors() == 1); + + 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_F(FloorTest, Float_P) { - std::initializer_list input_shape{1, 2, 4, 1}; - std::vector input_data{ - 0.2, 8.6, 2.4, 4.3, // Row 1 - 3, 7.1, 10.5, -0.9, // Row 2 - }; - - std::initializer_list ref_output_shape{1, 2, 4, 1}; - std::vector ref_output_data{ - 0, 8, 2, 4, // Row 1 - 3, 7, 10, -1, // Row 2 - }; - - Tensor input_tensor = - makeInputTensor(input_shape, input_data, _memory_manager.get()); - Tensor output_tensor = makeOutputTensor(DataType::FLOAT32); - - Floor kernel(&input_tensor, &output_tensor); - kernel.configure(); - _memory_manager->allocate_memory(output_tensor); - kernel.execute(); - - EXPECT_THAT(extractTensorData(output_tensor), FloatArrayNear(ref_output_data)); - EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape)); + test_kernel::TestDataFloatFloor test_data_kernel; + std::vector output_data_vector = checkFloorKernel(&test_data_kernel); + EXPECT_THAT(output_data_vector, test_data_kernel.get_output_data_by_index(0)); +} + +TEST_F(FloorTest, Input_output_type_mismatch_NEG) +{ + test_kernel::NegTestDataInputOutputTypeMismatchFloorKernel 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), + ""); } -TEST_F(FloorTest, Input_Output_Type_NEG) +TEST_F(FloorTest, Invalid_input_output_shape_NEG) { - Tensor input_tensor = makeInputTensor({1}, {1.f}, _memory_manager.get()); - Tensor output_tensor = makeOutputTensor(DataType::S32); + test_kernel::NegTestDataInvalidInputOutputShapeFloorKernel test_data_kernel; - Floor kernel(&input_tensor, &output_tensor); - EXPECT_ANY_THROW(kernel.configure()); + 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