From c690b3d91cf26e802b5e38604ebe4fd16997c94b Mon Sep 17 00:00:00 2001 From: SlavikMIPT Date: Wed, 4 Oct 2023 17:38:21 +0300 Subject: [PATCH] [onert-micro] Introduce LogicalNot kernel (#11662) This commit introduces LogicalNot kernel ONE-DCO-1.0-Signed-off-by: Vyacheslav Bazhenov Co-authored-by: Vyacheslav Bazhenov --- .../logical_not/BoolLogicalNotKernel.h | 89 +++++++++++ .../logical_not/NegLogicalNotKernel.h | 141 ++++++++++++++++++ .../logical_not/TestDataLogicalNotBase.h | 60 ++++++++ .../pal/common/PALLogicalNotCommon.h | 34 +++++ .../pal/mcu/KernelsToBuild.lst | 1 + .../luci-interpreter/pal/mcu/PALLogicalNot.h | 27 ++++ .../src/kernels/LogicalNot.cpp | 60 ++++---- .../src/kernels/LogicalNot.test.cpp | 96 +++++++----- 8 files changed, 441 insertions(+), 67 deletions(-) create mode 100644 onert-micro/luci-interpreter/include/luci_interpreter/test_models/logical_not/BoolLogicalNotKernel.h create mode 100644 onert-micro/luci-interpreter/include/luci_interpreter/test_models/logical_not/NegLogicalNotKernel.h create mode 100644 onert-micro/luci-interpreter/include/luci_interpreter/test_models/logical_not/TestDataLogicalNotBase.h create mode 100644 onert-micro/luci-interpreter/pal/common/PALLogicalNotCommon.h create mode 100644 onert-micro/luci-interpreter/pal/mcu/PALLogicalNot.h diff --git a/onert-micro/luci-interpreter/include/luci_interpreter/test_models/logical_not/BoolLogicalNotKernel.h b/onert-micro/luci-interpreter/include/luci_interpreter/test_models/logical_not/BoolLogicalNotKernel.h new file mode 100644 index 00000000000..d39ee5c42f1 --- /dev/null +++ b/onert-micro/luci-interpreter/include/luci_interpreter/test_models/logical_not/BoolLogicalNotKernel.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_BOOL_LOGICAL_NOT_KERNEL_H +#define LUCI_INTERPRETER_TEST_MODELS_BOOL_LOGICAL_NOT_KERNEL_H + +#include "TestDataLogicalNotBase.h" + +namespace luci_interpreter +{ +namespace test_kernel +{ +namespace logical_not_bool +{ +/* + * LogicalNot Kernel: + * + * Input(1, 3, 3, 2) + * | + * LogicalNot + * | + * 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, + 0x28, 0x00, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, 0x48, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 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, 0x5c, 0x00, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x64, 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, 0x3f, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x04, 0x00, 0x04, 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, 0x44, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0xd0, 0xff, 0xff, 0xff, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x6f, 0x66, 0x6d, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 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, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 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, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, + 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 = {false, true, false, false, true, true, false, false, false, + false, false, true, false, true, true, true, true, true}; + +const std::vector reference_output_data = {true, false, true, true, false, false, + true, true, true, true, true, false, + true, false, false, false, false, false}; + +} // namespace logical_not_bool + +class TestDataBoolLogicalNot : public TestDataLogicalNotBase +{ +public: + TestDataBoolLogicalNot() + { + _input_data = logical_not_bool::input_data; + _reference_output_data = logical_not_bool::reference_output_data; + _test_kernel_model_circle = logical_not_bool::test_kernel_model_circle; + } + + ~TestDataBoolLogicalNot() override = default; +}; + +} // namespace test_kernel +} // namespace luci_interpreter + +#endif // LUCI_INTERPRETER_TEST_MODELS_BOOL_LOGICAL_NOT_KERNEL_H diff --git a/onert-micro/luci-interpreter/include/luci_interpreter/test_models/logical_not/NegLogicalNotKernel.h b/onert-micro/luci-interpreter/include/luci_interpreter/test_models/logical_not/NegLogicalNotKernel.h new file mode 100644 index 00000000000..14fb43438a7 --- /dev/null +++ b/onert-micro/luci-interpreter/include/luci_interpreter/test_models/logical_not/NegLogicalNotKernel.h @@ -0,0 +1,141 @@ +/* + * 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_LOGICAL_NOT_KERNEL_H +#define LUCI_INTERPRETER_TEST_MODELS_NEG_LOGICAL_NOT_KERNEL_H + +#include "TestDataLogicalNotBase.h" + +namespace luci_interpreter +{ +namespace test_kernel +{ +namespace neg_wrong_output_type_logical_not_kernel +{ +/* + * LogicalNot Kernel with wrong output type (should be bool): + * + * Input(1, 3, 3, 2) - Bool + * | + * LogicalNot + * | + * 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, + 0x28, 0x00, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, 0x48, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 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, 0x5c, 0x00, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x64, 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, 0x3f, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x04, 0x00, 0x04, 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, 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, 0x03, 0x00, 0x00, 0x00, 0x03, 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, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 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, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, + 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_wrong_output_type_logical_not_kernel + +namespace neg_input_output_shape_mismatch_logical_not_kernel +{ +/* + * LogicalNot Kernel with input output shapes mismatch (should be equal): + * + * Input(1, 3, 3, 2) - Bool + * | + * LogicalNot + * | + * Output(1, 3, 3) - Bool + */ +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, + 0x28, 0x00, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, 0x48, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 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, 0x5c, 0x00, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x64, 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, 0x3f, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x04, 0x00, 0x04, 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, 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, 0x03, 0x00, 0x00, 0x00, 0x03, 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, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 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, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, + 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_shape_mismatch_logical_not_kernel + +class NegTestDataInputOutputTypeMismatchLogicalNotKernel : public NegTestDataBase +{ +public: + NegTestDataInputOutputTypeMismatchLogicalNotKernel() + { + _test_kernel_model_circle = neg_wrong_output_type_logical_not_kernel::test_kernel_model_circle; + } + + ~NegTestDataInputOutputTypeMismatchLogicalNotKernel() override = default; + + const unsigned char *get_model_ptr() override final { return _test_kernel_model_circle; } + +protected: + const unsigned char *_test_kernel_model_circle; +}; + +class NegTestDataInputOutputShapeMismatchLogicalNotKernel : public NegTestDataBase +{ +public: + NegTestDataInputOutputShapeMismatchLogicalNotKernel() + { + _test_kernel_model_circle = + neg_input_output_shape_mismatch_logical_not_kernel::test_kernel_model_circle; + } + + ~NegTestDataInputOutputShapeMismatchLogicalNotKernel() 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_LOGICAL_NOT_KERNEL_H diff --git a/onert-micro/luci-interpreter/include/luci_interpreter/test_models/logical_not/TestDataLogicalNotBase.h b/onert-micro/luci-interpreter/include/luci_interpreter/test_models/logical_not/TestDataLogicalNotBase.h new file mode 100644 index 00000000000..d57fadb1a04 --- /dev/null +++ b/onert-micro/luci-interpreter/include/luci_interpreter/test_models/logical_not/TestDataLogicalNotBase.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_LOGICAL_NOT_KERNEL_BASE_H +#define LUCI_INTERPRETER_TEST_MODELS_LOGICAL_NOT_KERNEL_BASE_H + +#include "luci_interpreter/test_models/TestDataBase.h" + +namespace luci_interpreter +{ +namespace test_kernel +{ + +template class TestDataLogicalNotBase : public TestDataBase +{ +public: + TestDataLogicalNotBase() = 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_LOGICAL_NOT_KERNEL_BASE_H diff --git a/onert-micro/luci-interpreter/pal/common/PALLogicalNotCommon.h b/onert-micro/luci-interpreter/pal/common/PALLogicalNotCommon.h new file mode 100644 index 00000000000..446c59f7377 --- /dev/null +++ b/onert-micro/luci-interpreter/pal/common/PALLogicalNotCommon.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023 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 LUCI_INTERPRETER_PAL_LOGICAL_NOT_COMMON_H +#define LUCI_INTERPRETER_PAL_LOGICAL_NOT_COMMON_H + +namespace luci_interpreter_pal +{ + +inline void LogicalNot(const int flat_size, const bool *input_data, bool *output_data) +{ + for (int i = 0; i < flat_size; ++i) + { + output_data[i] = !input_data[i]; + } +} + +} // namespace luci_interpreter_pal + +#endif // LUCI_INTERPRETER_PAL_LOGICAL_NOT_COMMON_H diff --git a/onert-micro/luci-interpreter/pal/mcu/KernelsToBuild.lst b/onert-micro/luci-interpreter/pal/mcu/KernelsToBuild.lst index 21770f2fbc3..9ea7711191a 100644 --- a/onert-micro/luci-interpreter/pal/mcu/KernelsToBuild.lst +++ b/onert-micro/luci-interpreter/pal/mcu/KernelsToBuild.lst @@ -43,6 +43,7 @@ REGISTER_KERNEL(L2_NORMALIZATION, L2Normalize) REGISTER_KERNEL(L2_POOL_2D, L2Pool2D) REGISTER_KERNEL(LESS_EQUAL, LessEqual) REGISTER_KERNEL(LOGICAL_AND, LogicalAnd) +REGISTER_KERNEL(LOGICAL_NOT, LogicalNot) REGISTER_KERNEL(LOGICAL_OR, LogicalOr) REGISTER_KERNEL(LEAKY_RELU, LeakyRelu) REGISTER_KERNEL(LOG_SOFTMAX, LogSoftmax) diff --git a/onert-micro/luci-interpreter/pal/mcu/PALLogicalNot.h b/onert-micro/luci-interpreter/pal/mcu/PALLogicalNot.h new file mode 100644 index 00000000000..3ec69600721 --- /dev/null +++ b/onert-micro/luci-interpreter/pal/mcu/PALLogicalNot.h @@ -0,0 +1,27 @@ +/* + * 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_LOGICAL_NOT_H +#define LUCI_INTERPRETER_PAL_LOGICAL_NOT_H + +#include "PALLogicalNotCommon.h" + +namespace luci_interpreter_pal +{ + +} // namespace luci_interpreter_pal + +#endif // LUCI_INTERPRETER_PAL_LOGICAL_NOT_H diff --git a/onert-micro/luci-interpreter/src/kernels/LogicalNot.cpp b/onert-micro/luci-interpreter/src/kernels/LogicalNot.cpp index 4ba4499e917..1ed6e1a2953 100644 --- a/onert-micro/luci-interpreter/src/kernels/LogicalNot.cpp +++ b/onert-micro/luci-interpreter/src/kernels/LogicalNot.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 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,49 +13,49 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#include "kernels/LogicalNot.h" - +#include "Builders.h" #include "kernels/Utils.h" +#include "SISOKernel.h" -#include "kernels/BinaryOpCommon.h" +#include "PALLogicalNot.h" namespace luci_interpreter { -namespace kernels +void configure_kernel_CircleLogicalNot(const circle::Operator *cur_op, + BaseRuntimeGraph *runtime_graph) { + kernels::SISOKernel kernel(cur_op, runtime_graph); -LogicalNot::LogicalNot(const Tensor *input, Tensor *output) : Kernel({input}, {output}) {} + LUCI_INTERPRETER_CHECK(Tensor::element_type(kernel.input()) == DataType::BOOL); + LUCI_INTERPRETER_CHECK(Tensor::element_type(kernel.output()) == DataType::BOOL); -void LogicalNot::configure() -{ - LUCI_INTERPRETER_CHECK(input()->element_type() == output()->element_type()); - // TODO: enable it only if kernel with dynamic shapes - output()->resize(input()->shape()); -} + // check that input and output dimensions are equal + int N = Tensor::num_dims(kernel.input()); + LUCI_INTERPRETER_CHECK(N == Tensor::num_dims(kernel.output())); -void LogicalNot::execute() const -{ - switch (input()->element_type()) + // check that sizes of all dimensions are equal + for (int i = 0; i < N; ++i) { - case DataType::BOOL: - evalLogicalNot(); - break; - default: - assert(false && "Unsupported type."); + LUCI_INTERPRETER_CHECK(kernels::getTensorShape(kernel.input()).dims(i) == + kernels::getTensorShape(kernel.output()).dims(i)); } } -inline void LogicalNot::evalLogicalNot() const +void execute_kernel_CircleLogicalNot(const circle::Operator *cur_op, + BaseRuntimeGraph *runtime_graph) { - const int size = tflite::MatchingFlatSize(getTensorShape(input()), getTensorShape(output())); - bool *output_data = getTensorData(output()); - const bool *input_data = getTensorData(input()); - for (int i = 0; i < size; ++i) - { - output_data[i] = !input_data[i]; - } + kernels::SISOKernel kernel(cur_op, runtime_graph); + + auto data = kernels::getTensorData(runtime_graph->getDataByTensor(kernel.input())); + if (data == nullptr) + data = kernels::getTensorData(runtime_graph->getConstDataByTensor(kernel.input())); + + assert(data != nullptr); + + auto output_data = kernels::getTensorData(runtime_graph->getDataByTensor(kernel.output())); + + const int64_t flat_size = kernels::getTensorShape(kernel.input()).flatSize(); + luci_interpreter_pal::LogicalNot(flat_size, data, output_data); } -} // namespace kernels } // namespace luci_interpreter diff --git a/onert-micro/luci-interpreter/src/kernels/LogicalNot.test.cpp b/onert-micro/luci-interpreter/src/kernels/LogicalNot.test.cpp index 3cbf27f6b11..6a9e0fa6e3a 100644 --- a/onert-micro/luci-interpreter/src/kernels/LogicalNot.test.cpp +++ b/onert-micro/luci-interpreter/src/kernels/LogicalNot.test.cpp @@ -1,6 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved - * Copyright 2017 The TensorFlow Authors. All Rights Reserved. + * 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. @@ -15,14 +14,14 @@ * limitations under the License. */ -#include "kernels/LogicalNot.h" #include "kernels/TestUtils.h" -#include "luci_interpreter/TestMemoryManager.h" +#include "luci_interpreter/test_models/logical_not/BoolLogicalNotKernel.h" +#include "luci_interpreter/test_models/logical_not/NegLogicalNotKernel.h" + +#include "loader/ModuleLoader.h" namespace luci_interpreter { -namespace kernels -{ namespace { @@ -30,49 +29,72 @@ using namespace testing; class LogicalNotTest : public ::testing::Test { -protected: - void SetUp() override { _memory_manager = std::make_unique(); } - - std::unique_ptr _memory_manager; + // Do nothing }; -TEST_F(LogicalNotTest, Basic) +template +std::vector checkLogicalNotKernel(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(LogicalNotTest, Bool_P) { - Shape input_shape{1, 1, 1, 4}; - Tensor input_tensor = - makeInputTensor(input_shape, {true, false, false, true}, _memory_manager.get()); - Tensor output_tensor = makeOutputTensor(DataType::BOOL); - - LogicalNot kernel(&input_tensor, &output_tensor); - kernel.configure(); - _memory_manager->allocate_memory(output_tensor); - kernel.execute(); - - EXPECT_THAT(extractTensorData(output_tensor), - ::testing::ElementsAre(false, true, true, false)); - EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAre(1, 1, 1, 4)); + test_kernel::TestDataBoolLogicalNot test_data_kernel; + std::vector output_data_vector = checkLogicalNotKernel(&test_data_kernel); + EXPECT_THAT(output_data_vector, test_data_kernel.get_output_data_by_index(0)); } -TEST_F(LogicalNotTest, OutputTypeInvalid_NEG) +TEST_F(LogicalNotTest, Input_output_type_mismatch_NEG) { - Tensor input_tensor = makeInputTensor({1, 1, 1, 4}, {true, false, false, true}, - _memory_manager.get()); - Tensor output_tensor = makeOutputTensor(DataType::S32); + test_kernel::NegTestDataInputOutputTypeMismatchLogicalNotKernel test_data_kernel; - LogicalNot 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), + ""); } -TEST_F(LogicalNotTest, InputTypeInvalid_NEG) +TEST_F(LogicalNotTest, Invalid_input_output_shape_NEG) { - Tensor input_tensor = - makeInputTensor({1, 1, 1, 4}, {1, 0, 0, 1}, _memory_manager.get()); - Tensor output_tensor = makeOutputTensor(DataType::BOOL); + test_kernel::NegTestDataInputOutputShapeMismatchLogicalNotKernel test_data_kernel; - LogicalNot 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