diff --git a/onert-micro/onert-micro/include/pal/mcu/KernelsToBuild.lst b/onert-micro/onert-micro/include/pal/mcu/KernelsToBuild.lst index 695195f5882..65ce01af9a5 100644 --- a/onert-micro/onert-micro/include/pal/mcu/KernelsToBuild.lst +++ b/onert-micro/onert-micro/include/pal/mcu/KernelsToBuild.lst @@ -36,7 +36,7 @@ REGISTER_KERNEL(FLOOR_MOD, FloorMod) #/*REGISTER_KERNEL(PRELU, PRelu)*/ #/*REGISTER_KERNEL(RESHAPE, Reshape)*/ REGISTER_KERNEL(RELU, Relu) -#/*REGISTER_KERNEL(RELU6, Relu6)*/ +REGISTER_KERNEL(RELU6, Relu6) #/*REGISTER_KERNEL(REDUCE_PROD, ReduceCommon)*/ #/*REGISTER_KERNEL(REDUCE_MAX, ReduceMax)*/ #/*REGISTER_KERNEL(ROUND, Round)*/ diff --git a/onert-micro/onert-micro/include/test_models/relu6/FloatReLU6Kernel.h b/onert-micro/onert-micro/include/test_models/relu6/FloatReLU6Kernel.h new file mode 100644 index 00000000000..ef007ffd54f --- /dev/null +++ b/onert-micro/onert-micro/include/test_models/relu6/FloatReLU6Kernel.h @@ -0,0 +1,88 @@ +/* + * 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_RELU6_KERNEL_H +#define ONERT_MICRO_TEST_MODELS_FLOAT_RELU6_KERNEL_H + +#include "TestDataReLU6Base.h" + +namespace onert_micro +{ +namespace test_model +{ +namespace relu6_float +{ +/* + * ReLU6 Kernel: + * + * Input(1, 3, 3, 2) + * | + * ReLU6 + * | + * 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, + 0x2c, 0x00, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0x30, 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, 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, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x69, 0x66, 0x6d, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x0c, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 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 = {4.2436867, 11.136094, -10.418385, 9.319618, -4.471156, + -20.418179, 18.783192, 7.1997013, -9.659637, 6.2115526, + -4.2794833, 10.500693, 8.646875, 3.8725555, -21.104343, + -7.6522045, 1.0404004, 7.109288}; +const std::vector reference_output_data = {4.2436867, 6.0, 0.0, 6.0, 0.0, 0.0, + 6.0, 6.0, 0.0, 6.0, 0.0, 6.0, + 6.0, 3.8725555, 0.0, 0.0, 1.0404004, 6.0}; + +} // namespace relu6_float + +class TestDataFloatReLU6 : public TestDataReLU6Base +{ +public: + TestDataFloatReLU6() + { + _input_data = relu6_float::input_data; + _reference_output_data = relu6_float::reference_output_data; + _test_kernel_model_circle = relu6_float::test_kernel_model_circle; + } + + ~TestDataFloatReLU6() override = default; +}; + +} // namespace test_model +} // namespace onert_micro + +#endif // ONERT_MICRO_TEST_MODELS_FLOAT_RELU6_KERNEL_H diff --git a/onert-micro/onert-micro/include/test_models/relu6/NegReLU6Kernel.h b/onert-micro/onert-micro/include/test_models/relu6/NegReLU6Kernel.h new file mode 100644 index 00000000000..d048e247cb5 --- /dev/null +++ b/onert-micro/onert-micro/include/test_models/relu6/NegReLU6Kernel.h @@ -0,0 +1,83 @@ +/* + * 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_RELU6_KERNEL_H +#define ONERT_MICRO_TEST_MODELS_NEG_RELU6_KERNEL_H + +#include "test_models/TestDataBase.h" + +namespace onert_micro +{ +namespace test_model +{ +namespace neg_input_output_type_mismatch_kernel +{ +/* + * ReLU6 Kernel with input output type mismatch: + * + * Input(1, 3, 3, 2) - Float32 + * | + * ReLU6 + * | + * Output(1, 3, 3, 2) - 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, 0x24, 0x01, 0x00, 0x00, 0x40, 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, 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, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x69, 0x66, 0x6d, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x0c, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 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_kernel + +class NegTestDataInputOutputTypeMismatchReLU6Kernel : public NegTestDataBase +{ +public: + NegTestDataInputOutputTypeMismatchReLU6Kernel() + { + _test_kernel_model_circle = neg_input_output_type_mismatch_kernel::test_kernel_model_circle; + } + + ~NegTestDataInputOutputTypeMismatchReLU6Kernel() 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_RELU6_KERNEL_H diff --git a/onert-micro/onert-micro/include/test_models/relu6/TestDataReLU6Base.h b/onert-micro/onert-micro/include/test_models/relu6/TestDataReLU6Base.h new file mode 100644 index 00000000000..f509e5380a8 --- /dev/null +++ b/onert-micro/onert-micro/include/test_models/relu6/TestDataReLU6Base.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ONERT_MICRO_TEST_MODELS_RELU6_KERNEL_BASE_H +#define ONERT_MICRO_TEST_MODELS_RELU6_KERNEL_BASE_H + +#include "test_models/TestDataBase.h" + +namespace onert_micro +{ +namespace test_model +{ + +template class TestDataReLU6Base : public TestDataBase +{ +public: + TestDataReLU6Base() = default; + + const unsigned char *get_model_ptr() override final { return _test_kernel_model_circle; } + + const std::vector &get_input_data_by_index(int i) override final + { + switch (i) + { + case 0: + return _input_data; + default: + assert(false && "Wrong input index"); + } + } + + const std::vector &get_output_data_by_index(int i) override final + { + assert(i == 0); + return _reference_output_data; + } + +protected: + std::vector _input_data; + std::vector _reference_output_data; + const unsigned char *_test_kernel_model_circle; +}; + +} // namespace test_model +} // namespace onert_micro + +#endif // ONERT_MICRO_TEST_MODELS_RELU6_KERNEL_BASE_H diff --git a/onert-micro/onert-micro/src/execute/kernels/Relu6.cpp b/onert-micro/onert-micro/src/execute/kernels/Relu6.cpp new file mode 100644 index 00000000000..7dddfe51762 --- /dev/null +++ b/onert-micro/onert-micro/src/execute/kernels/Relu6.cpp @@ -0,0 +1,98 @@ +/* + * 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 "execute/OMKernelExecutionBuilder.h" +#include "execute/OMRuntimeKernel.h" + +#include "PALReluCommon.h" + +using namespace onert_micro; +using namespace onert_micro::execute; + +namespace +{ + +constexpr uint32_t inputTensorIdx = 0; +constexpr uint32_t outputTensorIdx = 0; + +} // namespace + +// NOTE: doesnt currently support dynamic shapes +OMStatus onert_micro::execute::execute_kernel_CircleRelu6(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 = nullptr; + const circle::Tensor *output = nullptr; + + uint8_t *input_data = nullptr; + uint8_t *output_data = nullptr; + + OMStatus status = Ok; + + OMRuntimeKernel runtime_kernel; + runtime_kernel.readKernel(op_index, runtime_context); + + 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]; + output_data = runtime_kernel.outputs_data[outputTensorIdx]; + + assert(input_data != nullptr); + assert(output_data != nullptr); + + switch (input->type()) + { +#ifndef DIS_FLOAT + case circle::TensorType_FLOAT32: + { + + core::OMRuntimeShape input_shape(input); + core::OMRuntimeShape output_shape(output); + + const float *input_data_float = core::utils::castInputData(input_data); + float *output_data_float = core::utils::castOutputData(output_data); + + assert(output_data_float); + const int flat_size = input_shape.flatSize(); + + status = pal::ReLUCommon(flat_size, input_data_float, output_data_float, 0.0f, true); + } + break; +#endif // DIS_FLOAT + default: + { + status = UnsupportedType; + assert(false && "Unsupported type."); + } + } + + return status; +} diff --git a/onert-micro/onert-micro/src/execute/kernels/tests/Relu6.test.cpp b/onert-micro/onert-micro/src/execute/kernels/tests/Relu6.test.cpp new file mode 100644 index 00000000000..0279c0d2728 --- /dev/null +++ b/onert-micro/onert-micro/src/execute/kernels/tests/Relu6.test.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "execute/OMTestUtils.h" +#include "test_models/relu6/FloatReLU6Kernel.h" +#include "test_models/relu6/NegReLU6Kernel.h" + +namespace onert_micro +{ +namespace execute +{ +namespace testing +{ + +using namespace testing; + +class ReLU6Test : public ::testing::Test +{ + // Do nothing +}; + +TEST_F(ReLU6Test, Float_P) +{ + onert_micro::test_model::TestDataFloatReLU6 test_data_kernel; + std::vector output_data_vector = + onert_micro::execute::testing::checkKernel(1, &test_data_kernel); + EXPECT_THAT(output_data_vector, + FloatArrayNear(test_data_kernel.get_output_data_by_index(0), 0.0001f)); +} + +TEST_F(ReLU6Test, Input_output_type_mismatch_NEG) +{ + onert_micro::test_model::NegTestDataInputOutputTypeMismatchReLU6Kernel 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/Relu6.cpp b/onert-micro/onert-micro/src/import/kernels/Relu6.cpp new file mode 100644 index 00000000000..a752a1fefd5 --- /dev/null +++ b/onert-micro/onert-micro/src/import/kernels/Relu6.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "import/helpers/OMConfigureSISOKernel.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_CircleRelu6(const OMConfigureArgs &config_args) +{ + + return onert_micro::import::helpers::configure_SISO_kernel(config_args); +}