From 0a7eea94b81c44eedb65d4de83c7c474ebb017ca Mon Sep 17 00:00:00 2001 From: Evgenii Maltsev Date: Wed, 26 Jun 2024 13:38:38 +0400 Subject: [PATCH 1/8] [onert-micro] Reducing code duplication for FloorDiv, FloorMod, Min, Max, GatherND (#13293) Refactoring kernels: FloorDiv, FloorMod, Min, Max, GatherND for [issue](https://github.com/Samsung/ONE/issues/13272) ONE-DCO-1.0-Signed-off-by: Evgenii Maltsev e.maltsev@samsung.com --- .../execute/kernels/ReadKernelDataCommon.h | 41 ++++++++++ .../onert-micro/src/execute/CMakeLists.txt | 1 + .../src/execute/kernels/FloorDiv.cpp | 73 +++++------------ .../src/execute/kernels/FloorMod.cpp | 71 ++++------------- .../src/execute/kernels/GatherND.cpp | 54 +++---------- .../src/execute/kernels/Maximum.cpp | 52 +++---------- .../src/execute/kernels/Minimum.cpp | 52 +++---------- .../execute/kernels/ReadKernelDataCommon.cpp | 78 +++++++++++++++++++ 8 files changed, 185 insertions(+), 237 deletions(-) create mode 100644 onert-micro/onert-micro/include/execute/kernels/ReadKernelDataCommon.h create mode 100644 onert-micro/onert-micro/src/execute/kernels/ReadKernelDataCommon.cpp diff --git a/onert-micro/onert-micro/include/execute/kernels/ReadKernelDataCommon.h b/onert-micro/onert-micro/include/execute/kernels/ReadKernelDataCommon.h new file mode 100644 index 00000000000..754250a64fd --- /dev/null +++ b/onert-micro/onert-micro/include/execute/kernels/ReadKernelDataCommon.h @@ -0,0 +1,41 @@ +/* + * 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_EXECUTE_KERNELS_READDATACOMMON_H +#define ONERT_MICRO_EXECUTE_KERNELS_READDATACOMMON_H + +#include "OMStatus.h" +#include "core/OMKernelData.h" +#include "core/OMRuntimeShape.h" +#include "execute/OMRuntimeKernel.h" +#include "execute/OMKernelExecutionBuilder.h" + +namespace onert_micro +{ +namespace execute +{ + +OMStatus readKernelDataTISO(const OMExecuteArgs &execute_args, uint8_t *&input_data1, + uint8_t *&input_data2, uint8_t *&output_data, + core::OMRuntimeShape &input1_shape_ref, + core::OMRuntimeShape &input2_shape_ref, + core::OMRuntimeShape &output_shape_ref, + circle::TensorType &tensor_type); + +} // namespace execute +} // namespace onert_micro + +#endif // ONERT_MICRO_EXECUTE_KERNELS_READDATACOMMON_H diff --git a/onert-micro/onert-micro/src/execute/CMakeLists.txt b/onert-micro/onert-micro/src/execute/CMakeLists.txt index 912af3bd885..015ceb7105c 100644 --- a/onert-micro/onert-micro/src/execute/CMakeLists.txt +++ b/onert-micro/onert-micro/src/execute/CMakeLists.txt @@ -16,6 +16,7 @@ set(SOURCES OMUtils.cpp kernels/ConvolutionCommon.cpp kernels/PoolingCommon.cpp + kernels/ReadKernelDataCommon.cpp kernels/ReshapeCommon.cpp ) diff --git a/onert-micro/onert-micro/src/execute/kernels/FloorDiv.cpp b/onert-micro/onert-micro/src/execute/kernels/FloorDiv.cpp index 9e11dcfe19b..cf9ae03e368 100644 --- a/onert-micro/onert-micro/src/execute/kernels/FloorDiv.cpp +++ b/onert-micro/onert-micro/src/execute/kernels/FloorDiv.cpp @@ -17,89 +17,58 @@ #include "execute/OMKernelExecutionBuilder.h" #include "OMStatus.h" #include "execute/OMRuntimeKernel.h" +#include "execute/kernels/ReadKernelDataCommon.h" +#include "PALComparisons.h" #include "core/OMUtils.h" #include "PALFloorDiv.h" using namespace onert_micro; using namespace onert_micro::core; -namespace -{ - -constexpr uint32_t input1TensorIdx = 0; -constexpr uint32_t input2TensorIdx = 1; -constexpr uint32_t outputTensorIdx = 0; - -} // namespace - // NOTE: doesnt currently support dynamic shapes OMStatus onert_micro::execute::execute_kernel_CircleFloorDiv(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 *input1 = nullptr; - const circle::Tensor *input2 = nullptr; - const circle::Tensor *output = nullptr; - uint8_t *input_data1 = nullptr; - uint8_t *input_data2 = nullptr; - uint8_t *output_data = nullptr; + const float *cast_input_data1 = nullptr; + const float *cast_input_data2 = nullptr; + float *cast_output_data = nullptr; - OMStatus status = Ok; + uint8_t *input_data1; + uint8_t *input_data2; + uint8_t *output_data; - { - OMRuntimeKernel runtime_kernel; - runtime_kernel.readKernel(op_index, runtime_context); - - input1 = runtime_kernel.inputs[input1TensorIdx]; - input2 = runtime_kernel.inputs[input2TensorIdx]; - output = runtime_kernel.outputs[outputTensorIdx]; - - assert(input1 != nullptr); - assert(input2 != nullptr); - assert(output != nullptr); - - status = runtime_kernel.getDataFromStorage(op_index, runtime_storage, runtime_context); - if (status != Ok) - return status; - - input_data1 = runtime_kernel.inputs_data[input1TensorIdx]; - input_data2 = runtime_kernel.inputs_data[input2TensorIdx]; - output_data = runtime_kernel.outputs_data[outputTensorIdx]; - } + core::OMRuntimeShape input_shape1; + core::OMRuntimeShape input_shape2; + core::OMRuntimeShape output_shape; - assert(input_data1 != nullptr); - assert(input_data2 != nullptr); - assert(output_data != nullptr); + circle::TensorType input1_type; - core::OMRuntimeShape input1_shape(input1); - core::OMRuntimeShape input2_shape(input2); - core::OMRuntimeShape output_shape(output); + OMStatus status = + execute::readKernelDataTISO(execute_args, input_data1, input_data2, output_data, input_shape1, + input_shape2, output_shape, input1_type); - switch (input1->type()) + switch (input1_type) { #ifndef DIS_FLOAT case circle::TensorType_FLOAT32: { // Check the denominator - for (int i = 0; i < input2_shape.flatSize(); ++i) + for (int i = 0; i < input_shape2.flatSize(); ++i) { utils::checkCondition(core::utils::castInputData(input_data2)[i] != 0); } // check that input and output dimensions are equal - if (input1_shape == input2_shape) + if (input_shape1 == input_shape2) { - const int flat_size = input1_shape.flatSize(); + const int flat_size = input_shape1.flatSize(); pal::FloorDiv(flat_size, core::utils::castInputData(input_data1), core::utils::castInputData(input_data2), core::utils::castOutputData(output_data)); } else { - pal::BroadcastFloorDiv4DSlow(input1_shape, core::utils::castInputData(input_data1), - input2_shape, core::utils::castInputData(input_data2), + pal::BroadcastFloorDiv4DSlow(input_shape1, core::utils::castInputData(input_data1), + input_shape2, core::utils::castInputData(input_data2), output_shape, core::utils::castOutputData(output_data)); } } diff --git a/onert-micro/onert-micro/src/execute/kernels/FloorMod.cpp b/onert-micro/onert-micro/src/execute/kernels/FloorMod.cpp index cfd397b4518..73b3c8b95e8 100644 --- a/onert-micro/onert-micro/src/execute/kernels/FloorMod.cpp +++ b/onert-micro/onert-micro/src/execute/kernels/FloorMod.cpp @@ -17,89 +17,52 @@ #include "execute/OMKernelExecutionBuilder.h" #include "OMStatus.h" #include "execute/OMRuntimeKernel.h" +#include "execute/kernels/ReadKernelDataCommon.h" #include "core/OMUtils.h" #include "PALFloorMod.h" using namespace onert_micro; using namespace onert_micro::core; -namespace -{ - -constexpr uint32_t input1TensorIdx = 0; -constexpr uint32_t input2TensorIdx = 1; -constexpr uint32_t outputTensorIdx = 0; - -} // namespace - // NOTE: doesnt currently support dynamic shapes OMStatus onert_micro::execute::execute_kernel_CircleFloorMod(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 *input1 = nullptr; - const circle::Tensor *input2 = nullptr; - const circle::Tensor *output = nullptr; - - uint8_t *input_data1 = nullptr; - uint8_t *input_data2 = nullptr; - uint8_t *output_data = nullptr; - - OMStatus status = Ok; + uint8_t *input_data1; + uint8_t *input_data2; + uint8_t *output_data; - { - OMRuntimeKernel runtime_kernel; - runtime_kernel.readKernel(op_index, runtime_context); - - input1 = runtime_kernel.inputs[input1TensorIdx]; - input2 = runtime_kernel.inputs[input2TensorIdx]; - output = runtime_kernel.outputs[outputTensorIdx]; - - assert(input1 != nullptr); - assert(input2 != nullptr); - assert(output != nullptr); - - status = runtime_kernel.getDataFromStorage(op_index, runtime_storage, runtime_context); - if (status != Ok) - return status; - - input_data1 = runtime_kernel.inputs_data[input1TensorIdx]; - input_data2 = runtime_kernel.inputs_data[input2TensorIdx]; - output_data = runtime_kernel.outputs_data[outputTensorIdx]; - } + core::OMRuntimeShape input_shape1; + core::OMRuntimeShape input_shape2; + core::OMRuntimeShape output_shape; - assert(input_data1 != nullptr); - assert(input_data2 != nullptr); - assert(output_data != nullptr); + circle::TensorType input1_type; - core::OMRuntimeShape input1_shape(input1); - core::OMRuntimeShape input2_shape(input2); - core::OMRuntimeShape output_shape(output); + OMStatus status = + execute::readKernelDataTISO(execute_args, input_data1, input_data2, output_data, input_shape1, + input_shape2, output_shape, input1_type); - switch (input1->type()) + switch (input1_type) { #ifndef DIS_FLOAT case circle::TensorType_FLOAT32: { // Check the denominator - for (int i = 0; i < input2_shape.flatSize(); ++i) + for (int i = 0; i < input_shape2.flatSize(); ++i) { utils::checkCondition(core::utils::castInputData(input_data2)[i] != 0); } // check that input and output dimensions are equal - if (input1_shape == input2_shape) + if (input_shape1 == input_shape2) { - const int flat_size = input1_shape.flatSize(); + const int flat_size = input_shape1.flatSize(); pal::FloorMod(flat_size, core::utils::castInputData(input_data1), core::utils::castInputData(input_data2), core::utils::castOutputData(output_data)); } else { - pal::BroadcastFloorMod4DSlow(input1_shape, core::utils::castInputData(input_data1), - input2_shape, core::utils::castInputData(input_data2), + pal::BroadcastFloorMod4DSlow(input_shape1, core::utils::castInputData(input_data1), + input_shape2, core::utils::castInputData(input_data2), output_shape, core::utils::castOutputData(output_data)); } } diff --git a/onert-micro/onert-micro/src/execute/kernels/GatherND.cpp b/onert-micro/onert-micro/src/execute/kernels/GatherND.cpp index d32ccfe8b0f..e5f3571c828 100644 --- a/onert-micro/onert-micro/src/execute/kernels/GatherND.cpp +++ b/onert-micro/onert-micro/src/execute/kernels/GatherND.cpp @@ -23,68 +23,32 @@ #include "execute/OMKernelExecutionBuilder.h" #include "execute/OMUtils.h" #include "execute/OMRuntimeKernel.h" +#include "execute/kernels/ReadKernelDataCommon.h" #include "PALGatherND.h" using namespace onert_micro; using namespace onert_micro::core; using namespace onert_micro::execute; -namespace -{ - -constexpr uint32_t inputTensorIdx = 0; -constexpr uint32_t positionsTensorIdx = 1; -constexpr uint32_t outputTensorIdx = 0; - -} // namespace - // NOTE: doesn't currently support dynamic shapes OMStatus onert_micro::execute::execute_kernel_CircleGatherND(const OMExecuteArgs &execute_args) { - core::OMRuntimeContext &runtime_context = execute_args.runtime_context; - core::OMRuntimeStorage &runtime_storage = execute_args.runtime_storage; - uint16_t op_index = execute_args.kernel_index; - - const circle::Tensor *input; - const circle::Tensor *position; - const circle::Tensor *output; uint8_t *input_data; uint8_t *position_data; uint8_t *output_data; - // Read kernel - { - execute::OMRuntimeKernel runtime_kernel; - OMStatus status = runtime_kernel.readKernel(op_index, runtime_context); - if (status != Ok) - return status; - - input = runtime_kernel.inputs[inputTensorIdx]; - position = runtime_kernel.inputs[positionsTensorIdx]; - output = runtime_kernel.outputs[outputTensorIdx]; - assert(input != nullptr); - assert(position != 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]; - position_data = runtime_kernel.inputs_data[positionsTensorIdx]; - output_data = runtime_kernel.outputs_data[outputTensorIdx]; - assert(input_data != nullptr); - assert(position_data != nullptr); - assert(output_data != nullptr); - } + core::OMRuntimeShape input_shape; + core::OMRuntimeShape position_shape; + core::OMRuntimeShape output_shape; - OMStatus status = Ok; + circle::TensorType inputType; - OMRuntimeShape input_shape(input); - OMRuntimeShape position_shape(position); + OMStatus status = + execute::readKernelDataTISO(execute_args, input_data, position_data, output_data, input_shape, + position_shape, output_shape, inputType); - switch (input->type()) + switch (inputType) { #ifndef DIS_FLOAT case circle::TensorType_FLOAT32: diff --git a/onert-micro/onert-micro/src/execute/kernels/Maximum.cpp b/onert-micro/onert-micro/src/execute/kernels/Maximum.cpp index 347aa2402ff..73a10b6091f 100644 --- a/onert-micro/onert-micro/src/execute/kernels/Maximum.cpp +++ b/onert-micro/onert-micro/src/execute/kernels/Maximum.cpp @@ -17,6 +17,7 @@ #include "execute/OMKernelExecutionBuilder.h" #include "OMStatus.h" #include "execute/OMRuntimeKernel.h" +#include "execute/kernels/ReadKernelDataCommon.h" #include "core/OMUtils.h" #include "PALMaximum.h" @@ -24,59 +25,24 @@ using namespace onert_micro; using namespace onert_micro::core; using namespace onert_micro::execute; -namespace -{ - -constexpr uint32_t input1TensorIdx = 0; -constexpr uint32_t input2TensorIdx = 1; -constexpr uint32_t outputTensorIdx = 0; - -} // namespace - OMStatus onert_micro::execute::execute_kernel_CircleMaximum(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; - - OMStatus status = Ok; - - const circle::Tensor *input1 = nullptr; - const circle::Tensor *input2 = nullptr; - const circle::Tensor *output = nullptr; uint8_t *input_data1; uint8_t *input_data2; uint8_t *output_data; - OMRuntimeKernel runtime_kernel; - runtime_kernel.readKernel(op_index, runtime_context); - - status = runtime_kernel.getDataFromStorage(op_index, runtime_storage, runtime_context); - if (status != Ok) - return status; - - input1 = runtime_kernel.inputs[input1TensorIdx]; - input2 = runtime_kernel.inputs[input2TensorIdx]; - output = runtime_kernel.outputs[outputTensorIdx]; - - assert(input1 != nullptr); - assert(input2 != nullptr); - assert(output != nullptr); - - input_data1 = runtime_kernel.inputs_data[input1TensorIdx]; - input_data2 = runtime_kernel.inputs_data[input2TensorIdx]; - output_data = runtime_kernel.outputs_data[outputTensorIdx]; + core::OMRuntimeShape input_shape1; + core::OMRuntimeShape input_shape2; + core::OMRuntimeShape output_shape; - assert(input_data1 != nullptr); - assert(input_data2 != nullptr); - assert(output_data != nullptr); + circle::TensorType input1_type; - OMRuntimeShape input_shape1(input1); - OMRuntimeShape input_shape2(input2); - OMRuntimeShape output_shape(output); + OMStatus status = + execute::readKernelDataTISO(execute_args, input_data1, input_data2, output_data, input_shape1, + input_shape2, output_shape, input1_type); - switch (input1->type()) + switch (input1_type) { #ifndef DIS_FLOAT case circle::TensorType_FLOAT32: diff --git a/onert-micro/onert-micro/src/execute/kernels/Minimum.cpp b/onert-micro/onert-micro/src/execute/kernels/Minimum.cpp index 8974f5a12b0..e5c4e7ce471 100644 --- a/onert-micro/onert-micro/src/execute/kernels/Minimum.cpp +++ b/onert-micro/onert-micro/src/execute/kernels/Minimum.cpp @@ -17,6 +17,7 @@ #include "execute/OMKernelExecutionBuilder.h" #include "OMStatus.h" #include "execute/OMRuntimeKernel.h" +#include "execute/kernels/ReadKernelDataCommon.h" #include "core/OMUtils.h" #include "PALMinimum.h" @@ -24,59 +25,24 @@ using namespace onert_micro; using namespace onert_micro::core; using namespace onert_micro::execute; -namespace -{ - -constexpr uint32_t input1TensorIdx = 0; -constexpr uint32_t input2TensorIdx = 1; -constexpr uint32_t outputTensorIdx = 0; - -} // namespace - OMStatus onert_micro::execute::execute_kernel_CircleMinimum(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; - - OMStatus status = Ok; - - const circle::Tensor *input1 = nullptr; - const circle::Tensor *input2 = nullptr; - const circle::Tensor *output = nullptr; uint8_t *input_data1; uint8_t *input_data2; uint8_t *output_data; - OMRuntimeKernel runtime_kernel; - runtime_kernel.readKernel(op_index, runtime_context); - - status = runtime_kernel.getDataFromStorage(op_index, runtime_storage, runtime_context); - if (status != Ok) - return status; - - input1 = runtime_kernel.inputs[input1TensorIdx]; - input2 = runtime_kernel.inputs[input2TensorIdx]; - output = runtime_kernel.outputs[outputTensorIdx]; - - assert(input1 != nullptr); - assert(input2 != nullptr); - assert(output != nullptr); - - input_data1 = runtime_kernel.inputs_data[input1TensorIdx]; - input_data2 = runtime_kernel.inputs_data[input2TensorIdx]; - output_data = runtime_kernel.outputs_data[outputTensorIdx]; + core::OMRuntimeShape input_shape1; + core::OMRuntimeShape input_shape2; + core::OMRuntimeShape output_shape; - assert(input_data1 != nullptr); - assert(input_data2 != nullptr); - assert(output_data != nullptr); + circle::TensorType input1_type; - OMRuntimeShape input_shape1(input1); - OMRuntimeShape input_shape2(input2); - OMRuntimeShape output_shape(output); + OMStatus status = + execute::readKernelDataTISO(execute_args, input_data1, input_data2, output_data, input_shape1, + input_shape2, output_shape, input1_type); - switch (input1->type()) + switch (input1_type) { #ifndef DIS_FLOAT case circle::TensorType_FLOAT32: diff --git a/onert-micro/onert-micro/src/execute/kernels/ReadKernelDataCommon.cpp b/onert-micro/onert-micro/src/execute/kernels/ReadKernelDataCommon.cpp new file mode 100644 index 00000000000..791fc97f16a --- /dev/null +++ b/onert-micro/onert-micro/src/execute/kernels/ReadKernelDataCommon.cpp @@ -0,0 +1,78 @@ +/* + * 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/kernels/ReadKernelDataCommon.h" +#include "execute/OMUtils.h" + +using namespace onert_micro; +using namespace onert_micro::core; + +namespace TensorIndexTISO +{ + +constexpr uint32_t input1TensorIdx = 0; +constexpr uint32_t input2TensorIdx = 1; +constexpr uint32_t outputTensorIdx = 0; + +} // namespace TensorIndexTISO + +OMStatus onert_micro::execute::readKernelDataTISO(const OMExecuteArgs &execute_args, + uint8_t *&input_data1, uint8_t *&input_data2, + uint8_t *&output_data, + core::OMRuntimeShape &input1_shape_ref, + core::OMRuntimeShape &input2_shape_ref, + core::OMRuntimeShape &output_shape_ref, + circle::TensorType &tensor_type) + +{ + + core::OMRuntimeContext &runtime_context = execute_args.runtime_context; + core::OMRuntimeStorage &runtime_storage = execute_args.runtime_storage; + uint16_t op_index = execute_args.kernel_index; + + OMStatus status = Ok; + + OMRuntimeKernel runtime_kernel; + runtime_kernel.readKernel(op_index, runtime_context); + + status = runtime_kernel.getDataFromStorage(op_index, runtime_storage, runtime_context); + if (status != Ok) + return status; + + const circle::Tensor *input1 = nullptr; + const circle::Tensor *input2 = nullptr; + const circle::Tensor *output = nullptr; + + input1 = runtime_kernel.inputs[TensorIndexTISO::input1TensorIdx]; + input2 = runtime_kernel.inputs[TensorIndexTISO::input2TensorIdx]; + output = runtime_kernel.outputs[TensorIndexTISO::outputTensorIdx]; + + assert(input1 != nullptr); + assert(input2 != nullptr); + assert(output != nullptr); + + input_data1 = runtime_kernel.inputs_data[TensorIndexTISO::input1TensorIdx]; + input_data2 = runtime_kernel.inputs_data[TensorIndexTISO::input2TensorIdx]; + output_data = runtime_kernel.outputs_data[TensorIndexTISO::outputTensorIdx]; + + input1_shape_ref = std::move(core::OMRuntimeShape(input1)); + input2_shape_ref = std::move(core::OMRuntimeShape(input2)); + output_shape_ref = std::move(core::OMRuntimeShape(output)); + + tensor_type = input1->type(); + + return status; +} From 5d5f2cb402f3398b51cb18bcdc167ec9dc95808c Mon Sep 17 00:00:00 2001 From: Hyeongseok Oh Date: Wed, 26 Jun 2024 20:04:12 +0900 Subject: [PATCH 2/8] [onert/test] Add SUCCEED to unittest (#13303) This commit adds SUCCEED() macro to unittest for TC checker workaround. ONE-DCO-1.0-Signed-off-by: Hyeongseok Oh --- compute/cker/src/train/Conv.test.cc | 2 ++ .../src/GenModelTests/nontrainable_op_trains/Add.test.cc | 4 ++++ .../GenModelTests/nontrainable_op_trains/MaxPool2D.test.cc | 4 ++++ .../src/GenModelTests/nontrainable_op_trains/Mean.test.cc | 4 ++++ .../src/GenModelTests/nontrainable_op_trains/Mul.test.cc | 4 ++++ .../src/GenModelTests/nontrainable_op_trains/Pad.test.cc | 4 ++++ .../src/GenModelTests/nontrainable_op_trains/Relu.test.cc | 4 ++++ .../src/GenModelTests/nontrainable_op_trains/Relu6.test.cc | 4 ++++ .../src/GenModelTests/nontrainable_op_trains/Reshape.test.cc | 4 ++++ .../src/GenModelTests/nontrainable_op_trains/Softmax.test.cc | 4 ++++ .../src/GenModelTests/nontrainable_op_trains/Sub.test.cc | 4 ++++ 11 files changed, 42 insertions(+) diff --git a/compute/cker/src/train/Conv.test.cc b/compute/cker/src/train/Conv.test.cc index e3ddac8a59e..c7bf34eb3a5 100644 --- a/compute/cker/src/train/Conv.test.cc +++ b/compute/cker/src/train/Conv.test.cc @@ -384,6 +384,8 @@ TEST(CKer_Operation, ConvGrad) ConvVerifier::verifyInputGradExpected(params, incoming_shape, incoming.data(), filter_shape, filter.data(), padding_bottom, padding_right, input_shape); + + SUCCEED(); } } diff --git a/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Add.test.cc b/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Add.test.cc index 89e87eed5b1..472fb375e7e 100644 --- a/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Add.test.cc +++ b/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Add.test.cc @@ -37,6 +37,8 @@ TEST_F(GenModelTrain, neg_NonTrainableOps_Add_InvalidShape) _context = std::make_unique(cgen.finish()); _context->setBackends({"train"}); _context->expectFailCompile(); + + SUCCEED(); } TEST_F(GenModelTrain, neg_NonTrainableOps_Add_InvalidType) @@ -58,4 +60,6 @@ TEST_F(GenModelTrain, neg_NonTrainableOps_Add_InvalidType) _context = std::make_unique(cgen.finish()); _context->setBackends({"train"}); _context->expectFailModelLoad(); + + SUCCEED(); } diff --git a/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/MaxPool2D.test.cc b/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/MaxPool2D.test.cc index 5038c7aa4b8..6883dbf40c6 100644 --- a/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/MaxPool2D.test.cc +++ b/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/MaxPool2D.test.cc @@ -238,6 +238,8 @@ TEST_F(GenModelTrain, neg_NonTrainableOps_MaxPool2D_InvalidShape) _context = std::make_unique(cgen.finish()); _context->setBackends({"train"}); _context->expectFailCompile(); + + SUCCEED(); } TEST_F(GenModelTrain, neg_NonTrainableOps_MaxPool2D_InvalidType) @@ -259,4 +261,6 @@ TEST_F(GenModelTrain, neg_NonTrainableOps_MaxPool2D_InvalidType) _context = std::make_unique(cgen.finish()); _context->setBackends({"train"}); _context->expectFailCompile(); + + SUCCEED(); } diff --git a/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Mean.test.cc b/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Mean.test.cc index 242c3ff2d4a..2a4f75e03ec 100644 --- a/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Mean.test.cc +++ b/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Mean.test.cc @@ -78,6 +78,8 @@ TEST_F(GenModelTrain, neg_NonTrainableOps_Mean_InvalidShape) _context = std::make_unique(cgen.finish()); _context->setBackends({"train"}); _context->expectFailCompile(); + + SUCCEED(); } TEST_F(GenModelTrain, neg_NonTrainableOps_Mean_InvalidType) @@ -101,4 +103,6 @@ TEST_F(GenModelTrain, neg_NonTrainableOps_Mean_InvalidType) _context = std::make_unique(cgen.finish()); _context->setBackends({"train"}); _context->expectFailCompile(); + + SUCCEED(); } diff --git a/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Mul.test.cc b/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Mul.test.cc index b120994b257..25d4438c17c 100644 --- a/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Mul.test.cc +++ b/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Mul.test.cc @@ -37,6 +37,8 @@ TEST_F(GenModelTrain, neg_NonTrainableOps_Mul_InvalidShape) _context = std::make_unique(cgen.finish()); _context->setBackends({"train"}); _context->expectFailCompile(); + + SUCCEED(); } TEST_F(GenModelTrain, neg_NonTrainableOps_Mul_InvalidType) @@ -58,4 +60,6 @@ TEST_F(GenModelTrain, neg_NonTrainableOps_Mul_InvalidType) _context = std::make_unique(cgen.finish()); _context->setBackends({"train"}); _context->expectFailModelLoad(); + + SUCCEED(); } diff --git a/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Pad.test.cc b/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Pad.test.cc index 1a86f40619e..e6899cb1999 100644 --- a/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Pad.test.cc +++ b/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Pad.test.cc @@ -77,6 +77,8 @@ TEST_F(GenModelTrain, neg_NonTrainableOps_Pad_InvalidShape) _context = std::make_unique(cgen.finish()); _context->setBackends({"train"}); _context->expectFailCompile(); + + SUCCEED(); } TEST_F(GenModelTrain, neg_NonTrainableOps_Pad_InvalidType) @@ -101,4 +103,6 @@ TEST_F(GenModelTrain, neg_NonTrainableOps_Pad_InvalidType) _context = std::make_unique(cgen.finish()); _context->setBackends({"train"}); _context->expectFailModelLoad(); + + SUCCEED(); } diff --git a/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Relu.test.cc b/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Relu.test.cc index ece21ad8b71..5a0102a394f 100644 --- a/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Relu.test.cc +++ b/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Relu.test.cc @@ -80,6 +80,8 @@ TEST_F(GenModelTrain, neg_NonTrainableOps_Relu_InvalidShape) _context = std::make_unique(cgen.finish()); _context->setBackends({"train"}); _context->expectFailCompile(); + + SUCCEED(); } TEST_F(GenModelTrain, neg_NonTrainableOps_Relu_InvalidType) @@ -102,4 +104,6 @@ TEST_F(GenModelTrain, neg_NonTrainableOps_Relu_InvalidType) _context = std::make_unique(cgen.finish()); _context->setBackends({"train"}); _context->expectFailModelLoad(); + + SUCCEED(); } diff --git a/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Relu6.test.cc b/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Relu6.test.cc index b52f304d90a..7feb4e1c465 100644 --- a/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Relu6.test.cc +++ b/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Relu6.test.cc @@ -80,6 +80,8 @@ TEST_F(GenModelTrain, neg_NonTrainableOps_Relu6_InvalidShape) _context = std::make_unique(cgen.finish()); _context->setBackends({"train"}); _context->expectFailCompile(); + + SUCCEED(); } TEST_F(GenModelTrain, neg_NonTrainableOps_Relu6_InvalidType) @@ -102,4 +104,6 @@ TEST_F(GenModelTrain, neg_NonTrainableOps_Relu6_InvalidType) _context = std::make_unique(cgen.finish()); _context->setBackends({"train"}); _context->expectFailModelLoad(); + + SUCCEED(); } diff --git a/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Reshape.test.cc b/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Reshape.test.cc index eda2b75955b..ab036f44bef 100644 --- a/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Reshape.test.cc +++ b/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Reshape.test.cc @@ -82,6 +82,8 @@ TEST_F(GenModelTrain, neg_NonTrainableOps_Reshape_InvalidShape) _context = std::make_unique(cgen.finish()); _context->setBackends({"train"}); _context->expectFailCompile(); + + SUCCEED(); } TEST_F(GenModelTrain, neg_NonTrainableOps_Reshape_InvalidType) @@ -106,4 +108,6 @@ TEST_F(GenModelTrain, neg_NonTrainableOps_Reshape_InvalidType) _context = std::make_unique(cgen.finish()); _context->setBackends({"train"}); _context->expectFailCompile(); + + SUCCEED(); } diff --git a/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Softmax.test.cc b/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Softmax.test.cc index a244ede941d..11d0759be1f 100644 --- a/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Softmax.test.cc +++ b/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Softmax.test.cc @@ -76,6 +76,8 @@ TEST_F(GenModelTrain, neg_NonTrainableOps_Softmax_InvalidShape) _context = std::make_unique(cgen.finish()); _context->setBackends({"train"}); _context->expectFailCompile(); + + SUCCEED(); } TEST_F(GenModelTrain, neg_NonTrainableOps_Softmax_InvalidType) @@ -99,4 +101,6 @@ TEST_F(GenModelTrain, neg_NonTrainableOps_Softmax_InvalidType) _context = std::make_unique(cgen.finish()); _context->setBackends({"train"}); _context->expectFailModelLoad(); + + SUCCEED(); } diff --git a/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Sub.test.cc b/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Sub.test.cc index 5f903bcd94b..cb2b1b1e199 100644 --- a/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Sub.test.cc +++ b/tests/nnfw_api/src/GenModelTests/nontrainable_op_trains/Sub.test.cc @@ -38,6 +38,8 @@ TEST_F(GenModelTrain, neg_NonTrainableOps_Sub_InvalidShape) _context = std::make_unique(cgen.finish()); _context->setBackends({"train"}); _context->expectFailCompile(); + + SUCCEED(); } TEST_F(GenModelTrain, neg_NonTrainableOps_Sub_InvalidType) @@ -59,4 +61,6 @@ TEST_F(GenModelTrain, neg_NonTrainableOps_Sub_InvalidType) _context = std::make_unique(cgen.finish()); _context->setBackends({"train"}); _context->expectFailModelLoad(); + + SUCCEED(); } From 66d257e7be846255a7ec5816410fdef89960ee54 Mon Sep 17 00:00:00 2001 From: seongwoo chae Date: Thu, 27 Jun 2024 11:20:31 +0900 Subject: [PATCH 3/8] Release note 1.27.0 (#13310) This commit is a release note for 1.27.0. ONE-DCO-1.0-Signed-off-by: seongwoo --- docs/release/1.27/index.rst | 13 +++++++++++++ docs/release/1.27/release-note-1.27.0.md | 12 ++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 docs/release/1.27/index.rst create mode 100644 docs/release/1.27/release-note-1.27.0.md diff --git a/docs/release/1.27/index.rst b/docs/release/1.27/index.rst new file mode 100644 index 00000000000..522094867a1 --- /dev/null +++ b/docs/release/1.27/index.rst @@ -0,0 +1,13 @@ +.. ONE documentation master file, created by + sphinx-quickstart on Thu Jun 19 09:10:15 2024. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +1.27 +==== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + ./release-note-1.27.0.md diff --git a/docs/release/1.27/release-note-1.27.0.md b/docs/release/1.27/release-note-1.27.0.md new file mode 100644 index 00000000000..9377e0b5c51 --- /dev/null +++ b/docs/release/1.27/release-note-1.27.0.md @@ -0,0 +1,12 @@ +# Release Note 1.27.0 + +## ONE Compiler + +- Support more Op(s): CircleGRU, CircleRelu0To1 +- Support more optimization option(s): `resolve_former_customop`, `--forward_transpose_op`, + `fold_shape`, `remove_gather_guard`, `fuse_add_with_conv`, `fold_squeeze`, `fuse_rsqrt` +- Support INT4, UINT4 data types +- Support 4bit quantization of ONNX fake quantize model +- Introduce global configuration target feature +- Introduce command schema feature +- Use C++17 From a74a468f3cc560ac5eba35b6c882e60927f7650a Mon Sep 17 00:00:00 2001 From: seongwoo chae Date: Thu, 27 Jun 2024 11:21:00 +0900 Subject: [PATCH 4/8] [debian] Update changelog for version 1.27.0 (#13311) This commit updates changelog for release 1.27.0. ONE-DCO-1.0-Signed-off-by: seongwoo --- infra/debian/compiler/changelog | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/infra/debian/compiler/changelog b/infra/debian/compiler/changelog index 3e9de6b3d34..4565fbf33da 100644 --- a/infra/debian/compiler/changelog +++ b/infra/debian/compiler/changelog @@ -1,3 +1,16 @@ +one (1.27.0) bionic focal; urgency=medium + + * Support more Op(s): CircleGRU, CircleRelu0To1 + * Support more optimization option(s): `resolve_former_customop`, `--forward_transpose_op`, + `fold_shape`, `remove_gather_guard`, `fuse_add_with_conv`, `fold_squeeze`, `fuse_rsqrt` + * Support INT4, UINT4 data types + * Support 4bit quantization of ONNX fake quantize model + * Introduce global configuration target feature + * Introduce command schema feature + * Use C++17 + + -- seongwoo Thu, 27 Jun 2024 10:44:00 +0900 + one (1.26.0) bionic; urgency=medium * Support more Op(s): HardSwish, CumSum, BroadcastTo From eb96f5565d54b38854dfddd6aca1f89424063358 Mon Sep 17 00:00:00 2001 From: Hyeongseok Oh Date: Thu, 27 Jun 2024 11:44:18 +0900 Subject: [PATCH 5/8] [onert] Change ODC input file setting (#13300) This commit changes CodegenManager and QuantizeManager input file setting. Because input file can be changed by API, CodegenManager and QuantizeManager get input file from running method parameter, not constructor. ONE-DCO-1.0-Signed-off-by: Hyeongseok Oh --- .../onert/api/nnfw/src/nnfw_api_internal.cc | 23 ++++++------------- .../onert/core/include/odc/CodegenManager.h | 22 +++++++++--------- .../onert/core/include/odc/QuantizeManager.h | 12 ++++------ runtime/onert/core/src/odc/CodegenManager.cc | 7 +++--- runtime/onert/core/src/odc/QuantizeManager.cc | 6 ++--- .../core/src/odc/QuantizeManager.test.cc | 8 +++---- 6 files changed, 34 insertions(+), 44 deletions(-) diff --git a/runtime/onert/api/nnfw/src/nnfw_api_internal.cc b/runtime/onert/api/nnfw/src/nnfw_api_internal.cc index aa11e339fc6..989f2638eea 100644 --- a/runtime/onert/api/nnfw/src/nnfw_api_internal.cc +++ b/runtime/onert/api/nnfw/src/nnfw_api_internal.cc @@ -244,7 +244,8 @@ uint64_t getBufSize(const nnfw_tensorinfo *info) nnfw_session::nnfw_session() : _nnpkg{nullptr}, _coptions{onert::compiler::CompilerOptions::fromGlobalConfig()}, _compiler_artifact{nullptr}, _execution{nullptr}, _kernel_registry{nullptr}, - _train_info{nullptr}, _quant_manager{nullptr}, _codegen_manager{nullptr}, _model_path{""} + _train_info{nullptr}, _quant_manager{std::make_unique()}, + _codegen_manager{std::make_unique()}, _model_path{""} { // DO NOTHING } @@ -314,11 +315,6 @@ NNFW_STATUS nnfw_session::load_model_from_modelfile(const char *model_file_path) return NNFW_STATUS_UNEXPECTED_NULL; } - // Create quantize manager - _quant_manager = std::make_unique(std::string(model_file_path)); - // Create codegen manager - _codegen_manager = std::make_unique(std::string{model_file_path}); - std::string filename{model_file_path}; // TODO: Use std::filesystem::path when we can use c++17. auto dotidx = filename.find_last_of('.'); @@ -412,13 +408,6 @@ NNFW_STATUS nnfw_session::load_model_from_nnpackage(const char *package_dir) return NNFW_STATUS_ERROR; } - // Create quantize manager - // TODO Support multiple models - auto const model_filename = package_path + std::string("/") + models[0].asString(); - _quant_manager = std::make_unique(model_filename); - // Create codegen manager - _codegen_manager = std::make_unique(model_filename); - for (uint16_t i = 0; i < num_models; ++i) { auto model_file_path = package_path + std::string("/") + models[i].asString(); @@ -426,7 +415,7 @@ NNFW_STATUS nnfw_session::load_model_from_nnpackage(const char *package_dir) auto model = loadModel(model_file_path, model_type); if (model == nullptr) return NNFW_STATUS_ERROR; - _model_path = std::string(model_file_path); + _model_path = std::string(model_file_path); // TODO Support multiple models model->bindKernelBuilder(_kernel_registry->getBuilder()); _nnpkg->push(onert::ir::ModelIndex{i}, std::move(model)); } @@ -1746,7 +1735,7 @@ NNFW_STATUS nnfw_session::quantize() return NNFW_STATUS_INVALID_STATE; } - auto result = _quant_manager->quantize(); + auto result = _quant_manager->quantize(_model_path); if (!result) return NNFW_STATUS_INVALID_STATE; @@ -1844,7 +1833,7 @@ NNFW_STATUS nnfw_session::codegen(const char *target, NNFW_CODEGEN_PREF pref) _codegen_manager->exportModelPath(export_model_path); } - _codegen_manager->codegen(target, codegen_pref); + _codegen_manager->codegen(_model_path, target, codegen_pref); // Replace model // TODO Support buffer replace, not file reload @@ -1866,6 +1855,8 @@ NNFW_STATUS nnfw_session::codegen(const char *target, NNFW_CODEGEN_PREF pref) _nnpkg->replaceModel(std::move(model)); _state = State::MODEL_LOADED; _model_path = export_model_path; + _compiler_artifact.reset(); + _execution.reset(); } catch (const std::exception &e) { diff --git a/runtime/onert/core/include/odc/CodegenManager.h b/runtime/onert/core/include/odc/CodegenManager.h index 1d17f201d02..947750becf6 100644 --- a/runtime/onert/core/include/odc/CodegenManager.h +++ b/runtime/onert/core/include/odc/CodegenManager.h @@ -37,7 +37,7 @@ class CodegenManager { public: // Non-copyable - CodegenManager(const std::string &model_path) : _model_path(model_path) {} + CodegenManager() = default; CodegenManager(CodegenManager const &) = delete; CodegenManager &operator=(CodegenManager const &) = delete; @@ -59,19 +59,19 @@ class CodegenManager /** * @brief Execute code generator * - * @param target Target backend name - * This target string will be used to find a backend library. - * The name of target backend library should follow the following rules: - * 'lib' + {backend extension} + '-gen' + {lib extension} - * And the target string should be a name except 'lib' and {lib extension}. - * For example, if the backend extension is 'aaa', the backend library name - * should be 'libaaa-gen.so', and the target string should be 'aaa-gen'. - * @param pref @c CodegenPreference Codegen preference + * @param model[in] Model to be compiled + * @param target[in] Target backend name + * This target string will be used to find a backend library. + * The name of target backend library should follow the following rules: + * 'lib' + {backend extension} + '-gen' + {lib extension} + * And the target string should be a name except 'lib' and {lib extension}. + * For example, if the backend extension is 'aaa', the backend library name + * should be 'libaaa-gen.so', and the target string should be 'aaa-gen'. + * @param pref @c CodegenPreference Codegen preference */ - bool codegen(const char *target, CodegenPreference pref); + bool codegen(const std::string &model_path, const char *target, CodegenPreference pref); private: - std::string _model_path = ""; std::string _export_model_path = ""; }; diff --git a/runtime/onert/core/include/odc/QuantizeManager.h b/runtime/onert/core/include/odc/QuantizeManager.h index 883b487f939..257b86b0cc3 100644 --- a/runtime/onert/core/include/odc/QuantizeManager.h +++ b/runtime/onert/core/include/odc/QuantizeManager.h @@ -34,8 +34,7 @@ class QuantizeManager { public: // Non-copyable - QuantizeManager() = delete; - QuantizeManager(const std::string &model_path) : _model_path(model_path) {} + QuantizeManager() = default; QuantizeManager(QuantizeManager const &) = delete; QuantizeManager &operator=(QuantizeManager const &) = delete; @@ -64,14 +63,13 @@ class QuantizeManager void quantizeType(QuantizeType qtype) { _qtype = qtype; } /** - * @brief Quantize model - * - * @return true if success, otherwise false + * @brief Quantize model + * @param[in] model_path Model path to quantize + * @return @c true if success, otherwise @c false */ - bool quantize(); + bool quantize(const std::string &model_path); private: - std::string _model_path = ""; std::string _export_model_path = ""; QuantizeType _qtype = ODC_QTYPE_NOT_SET; }; diff --git a/runtime/onert/core/src/odc/CodegenManager.cc b/runtime/onert/core/src/odc/CodegenManager.cc index 645104eef74..45f10a69d61 100644 --- a/runtime/onert/core/src/odc/CodegenManager.cc +++ b/runtime/onert/core/src/odc/CodegenManager.cc @@ -25,7 +25,8 @@ namespace onert namespace odc { -bool CodegenManager::codegen(const char *target, CodegenPreference pref) +bool CodegenManager::codegen(const std::string &model_path, const char *target, + CodegenPreference pref) { if (target == nullptr) throw std::runtime_error("Target string is not set"); @@ -33,7 +34,7 @@ bool CodegenManager::codegen(const char *target, CodegenPreference pref) if (_export_model_path.empty()) throw std::runtime_error("Export model path is not set"); - if (_model_path.empty()) + if (model_path.empty()) throw std::runtime_error("Model path does not exist"); // codegen function is thread-unsafe @@ -45,7 +46,7 @@ bool CodegenManager::codegen(const char *target, CodegenPreference pref) const auto code_generator = codegen_loader.get(); // TODO Use compile preference UNUSED_RELEASE(pref); - const auto result = code_generator->codegen(_model_path.c_str(), _export_model_path.c_str()); + const auto result = code_generator->codegen(model_path.c_str(), _export_model_path.c_str()); codegen_loader.unloadLibrary(); return (result == 0); diff --git a/runtime/onert/core/src/odc/QuantizeManager.cc b/runtime/onert/core/src/odc/QuantizeManager.cc index 8039728a67b..fc5725b911c 100644 --- a/runtime/onert/core/src/odc/QuantizeManager.cc +++ b/runtime/onert/core/src/odc/QuantizeManager.cc @@ -25,9 +25,9 @@ namespace onert namespace odc { -bool QuantizeManager::quantize() +bool QuantizeManager::quantize(const std::string &model_path) { - if (_model_path.empty() || _export_model_path.empty()) + if (model_path.empty() || _export_model_path.empty()) return false; // Compile function is thread-unsafe @@ -39,7 +39,7 @@ bool QuantizeManager::quantize() return false; auto quantizer = quantize_loader.get(); - auto result = quantizer->quantize(_model_path.c_str(), _export_model_path.c_str(), _qtype); + auto result = quantizer->quantize(model_path.c_str(), _export_model_path.c_str(), _qtype); // TODO Unload quantize library to reduce memory usage diff --git a/runtime/onert/core/src/odc/QuantizeManager.test.cc b/runtime/onert/core/src/odc/QuantizeManager.test.cc index 6e3ee0275b7..3c9f45c6e87 100644 --- a/runtime/onert/core/src/odc/QuantizeManager.test.cc +++ b/runtime/onert/core/src/odc/QuantizeManager.test.cc @@ -23,16 +23,16 @@ using namespace onert::odc; // Test export model path is not set TEST(odc_QuantizeManager, neg_export_model_path_not_set) { - QuantizeManager manager("model_path"); + QuantizeManager manager; manager.quantizeType(ODC_QTYPE_WO_I8_SYM); - ASSERT_EQ(manager.quantize(), false); + ASSERT_EQ(manager.quantize("model_path"), false); } // Test invalid model path TEST(odc_QuantizeManager, neg_invalid_model_path) { - QuantizeManager manager("invalid_model_path.circle"); + QuantizeManager manager; manager.exportModelPath("export_model_path.circle"); manager.quantizeType(ODC_QTYPE_WO_I8_SYM); - ASSERT_EQ(manager.quantize(), false); + ASSERT_EQ(manager.quantize("invalid_model_path.circle"), false); } From 81d2b6dca76e7912bc6620990901ec9e78739917 Mon Sep 17 00:00:00 2001 From: Balyshev Artem <43214667+BalyshevArtem@users.noreply.github.com> Date: Thu, 27 Jun 2024 07:56:02 +0300 Subject: [PATCH 6/8] [onert-micro] Reduce Relu code duplication (#13307) * [onert-micro] Reduce Relu code duplication This pr reduces code duplication for Relu. ONE-DCO-1.0-Signed-off-by: Artem Balyshev * add leaky relu --------- Co-authored-by: Artem Balyshev --- .../include/execute/kernels/ReluCommon.h | 36 +++++++ .../onert-micro/src/execute/CMakeLists.txt | 1 + .../src/execute/kernels/LeakyRelu.cpp | 83 +--------------- .../onert-micro/src/execute/kernels/Relu.cpp | 76 +------------- .../onert-micro/src/execute/kernels/Relu6.cpp | 77 +-------------- .../src/execute/kernels/ReluCommon.cpp | 98 +++++++++++++++++++ .../onert-micro/src/import/kernels/Relu6.cpp | 8 -- 7 files changed, 144 insertions(+), 235 deletions(-) create mode 100644 onert-micro/onert-micro/include/execute/kernels/ReluCommon.h create mode 100644 onert-micro/onert-micro/src/execute/kernels/ReluCommon.cpp diff --git a/onert-micro/onert-micro/include/execute/kernels/ReluCommon.h b/onert-micro/onert-micro/include/execute/kernels/ReluCommon.h new file mode 100644 index 00000000000..17edf389c4e --- /dev/null +++ b/onert-micro/onert-micro/include/execute/kernels/ReluCommon.h @@ -0,0 +1,36 @@ +/* + * 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_EXECUTE_KERNELS_RESHAPE_COMMON_H +#define ONERT_MICRO_EXECUTE_KERNELS_RESHAPE_COMMON_H + +#include "OMStatus.h" +#include "core/OMUtils.h" + +#include "execute/OMKernelExecutionBuilder.h" +#include "execute/OMRuntimeKernel.h" + +namespace onert_micro +{ +namespace execute +{ + +OMStatus execute_relu_common(const OMExecuteArgs &execute_args, bool is_relu_6); + +} // namespace execute +} // namespace onert_micro + +#endif // ONERT_MICRO_EXECUTE_KERNELS_RESHAPE_COMMON_H diff --git a/onert-micro/onert-micro/src/execute/CMakeLists.txt b/onert-micro/onert-micro/src/execute/CMakeLists.txt index 015ceb7105c..d255ca04979 100644 --- a/onert-micro/onert-micro/src/execute/CMakeLists.txt +++ b/onert-micro/onert-micro/src/execute/CMakeLists.txt @@ -14,6 +14,7 @@ set(SOURCES OMKernelExecutionBuilder.cpp OMRuntimeKernel.cpp OMUtils.cpp + kernels/ReluCommon.cpp kernels/ConvolutionCommon.cpp kernels/PoolingCommon.cpp kernels/ReadKernelDataCommon.cpp diff --git a/onert-micro/onert-micro/src/execute/kernels/LeakyRelu.cpp b/onert-micro/onert-micro/src/execute/kernels/LeakyRelu.cpp index 9d483266af2..d2b6467ca52 100644 --- a/onert-micro/onert-micro/src/execute/kernels/LeakyRelu.cpp +++ b/onert-micro/onert-micro/src/execute/kernels/LeakyRelu.cpp @@ -14,91 +14,14 @@ * limitations under the License. */ -#include "OMStatus.h" - -#include "core/OMUtils.h" - -#include "execute/OMKernelExecutionBuilder.h" -#include "execute/OMRuntimeKernel.h" - -#include "PALReluCommon.h" +#include "execute/kernels/ReluCommon.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_CircleLeakyRelu(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]; - - const auto *options = runtime_kernel.first_operator->builtin_options_as_LeakyReluOptions(); - - if (options == nullptr) - return UnknownError; - - 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, options->alpha(), false); - } - break; -#endif // DIS_FLOAT - default: - { - status = UnsupportedType; - assert(false && "Unsupported type."); - } - } - - return status; + bool is_relu_6 = false; + return execute_relu_common(execute_args, is_relu_6); } diff --git a/onert-micro/onert-micro/src/execute/kernels/Relu.cpp b/onert-micro/onert-micro/src/execute/kernels/Relu.cpp index 2e74066d360..2c8fbb923c4 100644 --- a/onert-micro/onert-micro/src/execute/kernels/Relu.cpp +++ b/onert-micro/onert-micro/src/execute/kernels/Relu.cpp @@ -14,84 +14,14 @@ * limitations under the License. */ -#include "OMStatus.h" - -#include "core/OMUtils.h" - -#include "execute/OMKernelExecutionBuilder.h" -#include "execute/OMRuntimeKernel.h" - -#include "PALReluCommon.h" +#include "execute/kernels/ReluCommon.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_CircleRelu(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, false); - } - break; -#endif // DIS_FLOAT - default: - { - status = UnsupportedType; - assert(false && "Unsupported type."); - } - } - - return status; + bool is_relu_6 = false; + return execute_relu_common(execute_args, is_relu_6); } diff --git a/onert-micro/onert-micro/src/execute/kernels/Relu6.cpp b/onert-micro/onert-micro/src/execute/kernels/Relu6.cpp index 7dddfe51762..f501ad348bb 100644 --- a/onert-micro/onert-micro/src/execute/kernels/Relu6.cpp +++ b/onert-micro/onert-micro/src/execute/kernels/Relu6.cpp @@ -14,85 +14,14 @@ * limitations under the License. */ -#include "OMStatus.h" - -#include "core/OMUtils.h" - -#include "execute/OMKernelExecutionBuilder.h" -#include "execute/OMRuntimeKernel.h" - -#include "PALReluCommon.h" +#include "execute/kernels/ReluCommon.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; + bool is_relu_6 = true; + return execute_relu_common(execute_args, is_relu_6); } diff --git a/onert-micro/onert-micro/src/execute/kernels/ReluCommon.cpp b/onert-micro/onert-micro/src/execute/kernels/ReluCommon.cpp new file mode 100644 index 00000000000..ae464bffef9 --- /dev/null +++ b/onert-micro/onert-micro/src/execute/kernels/ReluCommon.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 "execute/kernels/ReluCommon.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_relu_common(const OMExecuteArgs &execute_args, + bool is_relu_6) +{ + 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); + + float alpha = 0.f; + auto options = runtime_kernel.first_operator->builtin_options_as_LeakyReluOptions(); + if (options != nullptr) + alpha = options->alpha(); + + switch (input->type()) + { +#ifndef DIS_FLOAT + case circle::TensorType_FLOAT32: + { + core::OMRuntimeShape input_shape(input); + core::OMRuntimeShape output_shape(output); + + const auto *input_data_float = core::utils::castInputData(input_data); + auto *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, alpha, is_relu_6); + } + break; +#endif // DIS_FLOAT + default: + { + status = UnsupportedType; + assert(false && "Unsupported type."); + break; + } + } + + return status; +} diff --git a/onert-micro/onert-micro/src/import/kernels/Relu6.cpp b/onert-micro/onert-micro/src/import/kernels/Relu6.cpp index a752a1fefd5..aff10a3353e 100644 --- a/onert-micro/onert-micro/src/import/kernels/Relu6.cpp +++ b/onert-micro/onert-micro/src/import/kernels/Relu6.cpp @@ -19,14 +19,6 @@ 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) { From b061b26b8d5d16c685f402b03b092eb259db3525 Mon Sep 17 00:00:00 2001 From: seongwoo chae Date: Thu, 27 Jun 2024 15:47:49 +0900 Subject: [PATCH 7/8] [vconone] Bump up to 1.28.0 (#13312) This commit bumps up to 1.28.0. ONE-DCO-1.0-Signed-off-by: seongwoo --- compiler/vconone/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/vconone/CMakeLists.txt b/compiler/vconone/CMakeLists.txt index 7fd69d434c6..0c1263dfd15 100644 --- a/compiler/vconone/CMakeLists.txt +++ b/compiler/vconone/CMakeLists.txt @@ -1,5 +1,5 @@ if (NOT VCONONE_VERSION) - set(VCONONE_VERSION 0x00000000001b0001) + set(VCONONE_VERSION 0x00000000001c0001) # NOTE order is [build patch minor major] # if VCONONE_VERSION is set with -D option, it will be cached # you may have to remove cache file if you remove -D option From 6131e61602d66732d7f8b2f4e715537e20ef1a8c Mon Sep 17 00:00:00 2001 From: Balyshev Artem <43214667+BalyshevArtem@users.noreply.github.com> Date: Thu, 27 Jun 2024 09:49:54 +0300 Subject: [PATCH 8/8] [onert-micro] Reduce SpaceToBatchND code duplication (#13290) This pr reduces code duplication for SpacesBatchesND and BatchToSpaceND. ONE-DCO-1.0-Signed-off-by: Artem Balyshev Co-authored-by: Artem Balyshev --- .../execute/kernels/SpacesBatchesNDCommon.h | 46 ++++++++ .../import/helpers/OMSpacesBatchesNDCommon.h | 38 ++++++ .../pal/common/PALSpaceToBatchNDCommon.h | 11 +- .../onert-micro/src/execute/CMakeLists.txt | 1 + .../src/execute/kernels/BatchToSpaceND.cpp | 94 ++------------- .../src/execute/kernels/SpaceToBatchND.cpp | 96 ++------------- .../execute/kernels/SpacesBatchesNDCommon.cpp | 109 ++++++++++++++++++ .../onert-micro/src/import/CMakeLists.txt | 1 + .../helpers/OMSpacesBatchesNDCommon.cpp | 86 ++++++++++++++ .../src/import/kernels/BatchToSpaceND.cpp | 66 +---------- .../src/import/kernels/SpaceToBatchND.cpp | 66 +---------- 11 files changed, 313 insertions(+), 301 deletions(-) create mode 100644 onert-micro/onert-micro/include/execute/kernels/SpacesBatchesNDCommon.h create mode 100644 onert-micro/onert-micro/include/import/helpers/OMSpacesBatchesNDCommon.h create mode 100644 onert-micro/onert-micro/src/execute/kernels/SpacesBatchesNDCommon.cpp create mode 100644 onert-micro/onert-micro/src/import/helpers/OMSpacesBatchesNDCommon.cpp diff --git a/onert-micro/onert-micro/include/execute/kernels/SpacesBatchesNDCommon.h b/onert-micro/onert-micro/include/execute/kernels/SpacesBatchesNDCommon.h new file mode 100644 index 00000000000..482f0d9832b --- /dev/null +++ b/onert-micro/onert-micro/include/execute/kernels/SpacesBatchesNDCommon.h @@ -0,0 +1,46 @@ +/* + * 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_EXECUTE_KERNELS_SPACES_BATCHES_ND_COMMON_H +#define ONERT_MICRO_EXECUTE_KERNELS_SPACES_BATCHES_ND_COMMON_H + +#include "OMStatus.h" + +#include "core/OMUtils.h" +#include "core/OMKernelData.h" + +#include "execute/OMKernelExecutionBuilder.h" +#include "execute/OMUtils.h" +#include "execute/OMRuntimeKernel.h" +#include + +namespace onert_micro +{ +namespace execute +{ + +OMStatus execute_spaces_batches_nd_common( + const OMExecuteArgs &execute_args, + const std::function< + OMStatus(const core::OMRuntimeShape &unextended_input1_shape, const float *input1_data, + const core::OMRuntimeShape &unextended_input2_shape, const int32_t *block_shape_data, + const core::OMRuntimeShape &unextended_input3_shape, const int32_t *crops_data, + const core::OMRuntimeShape &unextended_output_shape, float *output_data)> &f); + +} // namespace execute +} // namespace onert_micro + +#endif // ONERT_MICRO_EXECUTE_KERNELS_SPACES_BATCHES_ND_COMMON_H diff --git a/onert-micro/onert-micro/include/import/helpers/OMSpacesBatchesNDCommon.h b/onert-micro/onert-micro/include/import/helpers/OMSpacesBatchesNDCommon.h new file mode 100644 index 00000000000..b7db4f94405 --- /dev/null +++ b/onert-micro/onert-micro/include/import/helpers/OMSpacesBatchesNDCommon.h @@ -0,0 +1,38 @@ +/* + * 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_IMPORT_HELPERS_CONFIGURE_SPACES_BATCHES_ND_COMMON_H +#define ONERT_MICRO_IMPORT_HELPERS_CONFIGURE_SPACES_BATCHES_ND_COMMON_H + +#include "import/OMKernelConfigureBuilder.h" +#include "core/OMUtils.h" +#include "OMStatus.h" +#include "execute/OMRuntimeKernel.h" + +namespace onert_micro +{ +namespace import +{ +namespace helpers +{ + +OMStatus configure_spaces_batches_nd_kernel_common(const OMConfigureArgs &config_args); + +} // namespace helpers +} // namespace import +} // namespace onert_micro + +#endif // ONERT_MICRO_IMPORT_HELPERS_CONFIGURE_SPACES_BATCHES_ND_COMMON_H diff --git a/onert-micro/onert-micro/include/pal/common/PALSpaceToBatchNDCommon.h b/onert-micro/onert-micro/include/pal/common/PALSpaceToBatchNDCommon.h index 01648d03c67..1fcf0e2aa67 100644 --- a/onert-micro/onert-micro/include/pal/common/PALSpaceToBatchNDCommon.h +++ b/onert-micro/onert-micro/include/pal/common/PALSpaceToBatchNDCommon.h @@ -48,11 +48,10 @@ inline core::OMRuntimeShape extendShapeSpaceToBatch(const core::OMRuntimeShape & template inline OMStatus -SpaceToBatchND(const int32_t pad_value, const core::OMRuntimeShape &unextended_input1_shape, - const T *input1_data, const core::OMRuntimeShape &unextended_input2_shape, - const int32_t *block_shape_data, const core::OMRuntimeShape &unextended_input3_shape, - const int32_t *paddings_data, const core::OMRuntimeShape &unextended_output_shape, - T *output_data) +SpaceToBatchND(const core::OMRuntimeShape &unextended_input1_shape, const T *input1_data, + const core::OMRuntimeShape &unextended_input2_shape, const int32_t *block_shape_data, + const core::OMRuntimeShape &unextended_input3_shape, const int32_t *paddings_data, + const core::OMRuntimeShape &unextended_output_shape, T *output_data) { // Extends the input/output shape from 3D to 4D if needed, NHC -> NH1C. const core::OMRuntimeShape input1_shape = extendShapeSpaceToBatch(unextended_input1_shape); @@ -73,6 +72,8 @@ SpaceToBatchND(const int32_t pad_value, const core::OMRuntimeShape &unextended_i const int padding_top = paddings_data[0]; const int padding_left = unextended_input1_shape.dimensionsCount() == 4 ? paddings_data[2] : 0; + const int32_t pad_value = 0; + for (int out_b = 0; out_b < output_batch_size; ++out_b) { int input_batch = out_b % input_batch_size; diff --git a/onert-micro/onert-micro/src/execute/CMakeLists.txt b/onert-micro/onert-micro/src/execute/CMakeLists.txt index d255ca04979..4ec56ed4e1e 100644 --- a/onert-micro/onert-micro/src/execute/CMakeLists.txt +++ b/onert-micro/onert-micro/src/execute/CMakeLists.txt @@ -19,6 +19,7 @@ set(SOURCES kernels/PoolingCommon.cpp kernels/ReadKernelDataCommon.cpp kernels/ReshapeCommon.cpp + kernels/SpacesBatchesNDCommon.cpp ) # Add configure kernels diff --git a/onert-micro/onert-micro/src/execute/kernels/BatchToSpaceND.cpp b/onert-micro/onert-micro/src/execute/kernels/BatchToSpaceND.cpp index 1d1840dafcb..c54a547f668 100644 --- a/onert-micro/onert-micro/src/execute/kernels/BatchToSpaceND.cpp +++ b/onert-micro/onert-micro/src/execute/kernels/BatchToSpaceND.cpp @@ -14,95 +14,23 @@ * limitations under the License. */ -#include "execute/OMUtils.h" -#include "execute/OMKernelExecutionBuilder.h" -#include "OMStatus.h" -#include "execute/OMRuntimeKernel.h" -#include "core/OMUtils.h" - -#include "core/OMRuntimeShape.h" +#include "execute/kernels/SpacesBatchesNDCommon.h" #include "PALBatchToSpaceND.h" using namespace onert_micro; using namespace onert_micro::execute; -namespace -{ -constexpr uint32_t input1TensorIdx = 0; -constexpr uint32_t input2TensorIdx = 1; -constexpr uint32_t input3TensorIdx = 2; -constexpr uint32_t outputTensorIdx = 0; - -} // namespace OMStatus onert_micro::execute::execute_kernel_CircleBatchToSpaceND( const onert_micro::execute::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 *input1; - const circle::Tensor *input2; - const circle::Tensor *input3; - const circle::Tensor *output; - - uint8_t *input1_data; - uint8_t *input2_data; - uint8_t *input3_data; - uint8_t *output_data; - - uint16_t input1_index = 0; - uint16_t input2_index = 0; - - // Read kernel - - execute::OMRuntimeKernel runtime_kernel; - OMStatus status = runtime_kernel.readKernel(op_index, runtime_context); - if (status != Ok) - return status; - - input1 = runtime_kernel.inputs[input1TensorIdx]; - input2 = runtime_kernel.inputs[input2TensorIdx]; - input3 = runtime_kernel.inputs[input3TensorIdx]; - output = runtime_kernel.outputs[outputTensorIdx]; - - core::OMRuntimeShape input1_shape(input1); - core::OMRuntimeShape input2_shape(input1); - core::OMRuntimeShape input3_shape(input1); - core::OMRuntimeShape output_shape(output); - - assert(input1 != nullptr); - assert(input2 != nullptr); - assert(input3 != nullptr); - assert(output != nullptr); - - status = runtime_kernel.getDataFromStorage(op_index, runtime_storage, runtime_context); - if (status != Ok) - return status; - - input1_data = runtime_kernel.inputs_data[input1TensorIdx]; - input2_data = runtime_kernel.inputs_data[input2TensorIdx]; - input3_data = runtime_kernel.inputs_data[input3TensorIdx]; - output_data = runtime_kernel.outputs_data[outputTensorIdx]; - - switch (input1->type()) - { -#ifndef DIS_FLOAT - case circle::TensorType_FLOAT32: - { - status = pal::BatchToSpaceND(input1_shape, reinterpret_cast(input1_data), - input2_shape, reinterpret_cast(input2_data), - input3_shape, reinterpret_cast(input3_data), - output_shape, reinterpret_cast(output_data)); - } - break; -#endif // DIS_FLOAT - default: - { - status = UnsupportedType; - assert(false && "Unsupported type."); - } - } - - return status; + auto batch_to_space_float_lambda = + [](const core::OMRuntimeShape &input1_shape, const float *input1_data, + const core::OMRuntimeShape &input2_shape, const int32_t *block_shape_data, + const core::OMRuntimeShape &input3_shape, const int32_t *crops_data, + const core::OMRuntimeShape &output_shape, float *output_data) { + return pal::BatchToSpaceND(input1_shape, input1_data, input2_shape, block_shape_data, + input3_shape, crops_data, output_shape, output_data); + }; + + return execute_spaces_batches_nd_common(execute_args, batch_to_space_float_lambda); } diff --git a/onert-micro/onert-micro/src/execute/kernels/SpaceToBatchND.cpp b/onert-micro/onert-micro/src/execute/kernels/SpaceToBatchND.cpp index f4876510a64..dfa1934e56a 100644 --- a/onert-micro/onert-micro/src/execute/kernels/SpaceToBatchND.cpp +++ b/onert-micro/onert-micro/src/execute/kernels/SpaceToBatchND.cpp @@ -14,97 +14,23 @@ * limitations under the License. */ -#include "execute/OMUtils.h" -#include "execute/OMKernelExecutionBuilder.h" -#include "OMStatus.h" -#include "execute/OMRuntimeKernel.h" -#include "core/OMUtils.h" - -#include "core/OMRuntimeShape.h" +#include "execute/kernels/SpacesBatchesNDCommon.h" #include "PALSpaceToBatchND.h" using namespace onert_micro; using namespace onert_micro::execute; -namespace -{ -constexpr uint32_t input1TensorIdx = 0; -constexpr uint32_t input2TensorIdx = 1; -constexpr uint32_t input3TensorIdx = 2; -constexpr uint32_t outputTensorIdx = 0; - -} // namespace OMStatus onert_micro::execute::execute_kernel_CircleSpaceToBatchND( const onert_micro::execute::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 *input1; - const circle::Tensor *input2; - const circle::Tensor *input3; - const circle::Tensor *output; - - uint8_t *input1_data; - uint8_t *input2_data; - uint8_t *input3_data; - uint8_t *output_data; - - uint16_t input1_index = 0; - uint16_t input2_index = 0; - - // Read kernel - - execute::OMRuntimeKernel runtime_kernel; - OMStatus status = runtime_kernel.readKernel(op_index, runtime_context); - if (status != Ok) - return status; - - input1 = runtime_kernel.inputs[input1TensorIdx]; - input2 = runtime_kernel.inputs[input2TensorIdx]; - input3 = runtime_kernel.inputs[input3TensorIdx]; - output = runtime_kernel.outputs[outputTensorIdx]; - - core::OMRuntimeShape input1_shape(input1); - core::OMRuntimeShape input2_shape(input1); - core::OMRuntimeShape input3_shape(input1); - core::OMRuntimeShape output_shape(output); - - assert(input1 != nullptr); - assert(input2 != nullptr); - assert(input3 != nullptr); - assert(output != nullptr); - - status = runtime_kernel.getDataFromStorage(op_index, runtime_storage, runtime_context); - if (status != Ok) - return status; - - input1_data = runtime_kernel.inputs_data[input1TensorIdx]; - input2_data = runtime_kernel.inputs_data[input2TensorIdx]; - input3_data = runtime_kernel.inputs_data[input3TensorIdx]; - output_data = runtime_kernel.outputs_data[outputTensorIdx]; - const int32_t pad_value = 0; - - switch (input1->type()) - { -#ifndef DIS_FLOAT - case circle::TensorType_FLOAT32: - { - status = - pal::SpaceToBatchND(pad_value, input1_shape, reinterpret_cast(input1_data), - input2_shape, reinterpret_cast(input2_data), - input3_shape, reinterpret_cast(input3_data), - output_shape, reinterpret_cast(output_data)); - } - break; -#endif // DIS_FLOAT - default: - { - status = UnsupportedType; - assert(false && "Unsupported type."); - } - } - - return status; + auto batch_to_space_float_lambda = + [](const core::OMRuntimeShape &input1_shape, const float *input1_data, + const core::OMRuntimeShape &input2_shape, const int32_t *block_shape_data, + const core::OMRuntimeShape &input3_shape, const int32_t *crops_data, + const core::OMRuntimeShape &output_shape, float *output_data) { + return pal::SpaceToBatchND(input1_shape, input1_data, input2_shape, block_shape_data, + input3_shape, crops_data, output_shape, output_data); + }; + + return execute_spaces_batches_nd_common(execute_args, batch_to_space_float_lambda); } diff --git a/onert-micro/onert-micro/src/execute/kernels/SpacesBatchesNDCommon.cpp b/onert-micro/onert-micro/src/execute/kernels/SpacesBatchesNDCommon.cpp new file mode 100644 index 00000000000..d93c4d06c21 --- /dev/null +++ b/onert-micro/onert-micro/src/execute/kernels/SpacesBatchesNDCommon.cpp @@ -0,0 +1,109 @@ +/* + * 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/kernels/SpacesBatchesNDCommon.h" +#include "execute/OMUtils.h" + +using namespace onert_micro; +using namespace onert_micro::core; + +namespace +{ + +constexpr uint32_t input1TensorIdx = 0; +constexpr uint32_t input2TensorIdx = 1; +constexpr uint32_t input3TensorIdx = 2; +constexpr uint32_t outputTensorIdx = 0; + +} // namespace + +OMStatus onert_micro::execute::execute_spaces_batches_nd_common( + const OMExecuteArgs &execute_args, + const std::function< + OMStatus(const core::OMRuntimeShape &unextended_input1_shape, const float *input1_data, + const core::OMRuntimeShape &unextended_input2_shape, const int32_t *block_shape_data, + const core::OMRuntimeShape &unextended_input3_shape, const int32_t *crops_data, + const core::OMRuntimeShape &unextended_output_shape, float *output_data)> &func) +{ + 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 *input1; + const circle::Tensor *input2; + const circle::Tensor *input3; + const circle::Tensor *output; + + uint8_t *input1_data; + uint8_t *input2_data; + uint8_t *input3_data; + uint8_t *output_data; + + uint16_t input1_index = 0; + uint16_t input2_index = 0; + + // Read kernel + + execute::OMRuntimeKernel runtime_kernel; + OMStatus status = runtime_kernel.readKernel(op_index, runtime_context); + if (status != Ok) + return status; + + input1 = runtime_kernel.inputs[input1TensorIdx]; + input2 = runtime_kernel.inputs[input2TensorIdx]; + input3 = runtime_kernel.inputs[input3TensorIdx]; + output = runtime_kernel.outputs[outputTensorIdx]; + + core::OMRuntimeShape input1_shape(input1); + core::OMRuntimeShape input2_shape(input1); + core::OMRuntimeShape input3_shape(input1); + core::OMRuntimeShape output_shape(output); + + assert(input1 != nullptr); + assert(input2 != nullptr); + assert(input3 != nullptr); + assert(output != nullptr); + + status = runtime_kernel.getDataFromStorage(op_index, runtime_storage, runtime_context); + if (status != Ok) + return status; + + input1_data = runtime_kernel.inputs_data[input1TensorIdx]; + input2_data = runtime_kernel.inputs_data[input2TensorIdx]; + input3_data = runtime_kernel.inputs_data[input3TensorIdx]; + output_data = runtime_kernel.outputs_data[outputTensorIdx]; + + switch (input1->type()) + { +#ifndef DIS_FLOAT + case circle::TensorType_FLOAT32: + { + status = func(input1_shape, reinterpret_cast(input1_data), input2_shape, + reinterpret_cast(input2_data), input3_shape, + reinterpret_cast(input3_data), output_shape, + reinterpret_cast(output_data)); + } + break; +#endif // DIS_FLOAT + default: + { + status = UnsupportedType; + assert(false && "Unsupported type."); + } + } + + return status; +} diff --git a/onert-micro/onert-micro/src/import/CMakeLists.txt b/onert-micro/onert-micro/src/import/CMakeLists.txt index 6297f8feed1..e06fdc3894b 100644 --- a/onert-micro/onert-micro/src/import/CMakeLists.txt +++ b/onert-micro/onert-micro/src/import/CMakeLists.txt @@ -7,6 +7,7 @@ set(SOURCES helpers/OMConfigureSISOKernel.cpp helpers/OMPadCommon.cpp helpers/OMConfigureTISOKernel.cpp + helpers/OMSpacesBatchesNDCommon.cpp helpers/OMPoolingCommon.cpp ) diff --git a/onert-micro/onert-micro/src/import/helpers/OMSpacesBatchesNDCommon.cpp b/onert-micro/onert-micro/src/import/helpers/OMSpacesBatchesNDCommon.cpp new file mode 100644 index 00000000000..b8592a14dfa --- /dev/null +++ b/onert-micro/onert-micro/src/import/helpers/OMSpacesBatchesNDCommon.cpp @@ -0,0 +1,86 @@ +/* + * 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/OMSpacesBatchesNDCommon.h" + +using namespace onert_micro; +using namespace onert_micro::core; + +namespace +{ + +constexpr uint32_t input1TensorIdx = 0; +constexpr uint32_t input2TensorIdx = 1; +constexpr uint32_t input3TensorIdx = 2; +constexpr uint32_t outputTensorIdx = 0; + +} // namespace + +OMStatus onert_micro::import::helpers::configure_spaces_batches_nd_kernel_common( + const OMConfigureArgs &config_args) +{ + OMRuntimeContext &runtime_context = config_args.runtime_context; + uint16_t op_index = config_args.kernel_index; + + onert_micro::execute::OMRuntimeKernel runtime_kernel; + + OMStatus status = runtime_kernel.readKernel(op_index, runtime_context); + if (status != Ok) + return status; + + const circle::Tensor *input1 = runtime_kernel.inputs[input1TensorIdx]; + const circle::Tensor *input2 = runtime_kernel.inputs[input2TensorIdx]; + const circle::Tensor *input3 = runtime_kernel.inputs[input3TensorIdx]; + const circle::Tensor *output = runtime_kernel.outputs[outputTensorIdx]; + + core::OMRuntimeShape input1_shape(input1); + core::OMRuntimeShape output_shape(output); + + assert(input1 != nullptr); + assert(input2 != nullptr); + assert(input3 != nullptr); + assert(output != nullptr); + + status = utils::checkCondition(input1->type() == output->type()); + if (status != Ok) + return status; + + status = utils::checkCondition(input2->type() == circle::TensorType_INT32); + if (status != Ok) + return status; + + status = utils::checkCondition(input3->type() == circle::TensorType_INT32); + if (status != Ok) + return status; + + status = utils::checkCondition(output_shape.dimensionsCount() >= 3); + if (status != Ok) + return status; + + status = utils::checkCondition(input1_shape.dimensionsCount() >= 3); + if (status != Ok) + return status; + + status = utils::checkCondition(output_shape.dimensionsCount() <= 4); + if (status != Ok) + return status; + + status = utils::checkCondition(input1_shape.dimensionsCount() <= 4); + if (status != Ok) + return status; + + return status; +} diff --git a/onert-micro/onert-micro/src/import/kernels/BatchToSpaceND.cpp b/onert-micro/onert-micro/src/import/kernels/BatchToSpaceND.cpp index 62fb0e75aec..64791713508 100644 --- a/onert-micro/onert-micro/src/import/kernels/BatchToSpaceND.cpp +++ b/onert-micro/onert-micro/src/import/kernels/BatchToSpaceND.cpp @@ -14,75 +14,13 @@ * limitations under the License. */ -#include "import/OMKernelConfigureBuilder.h" -#include "core/OMUtils.h" -#include "OMStatus.h" -#include "execute/OMRuntimeKernel.h" +#include "import/helpers/OMSpacesBatchesNDCommon.h" using namespace onert_micro; using namespace onert_micro::core; -namespace -{ - -constexpr uint32_t input1TensorIdx = 0; -constexpr uint32_t input2TensorIdx = 1; -constexpr uint32_t input3TensorIdx = 2; -constexpr uint32_t outputTensorIdx = 0; - -} // namespace OMStatus onert_micro::import::configure_kernel_CircleBatchToSpaceND( const onert_micro::import::OMConfigureArgs &config_args) { - OMRuntimeContext &runtime_context = config_args.runtime_context; - uint16_t op_index = config_args.kernel_index; - - onert_micro::execute::OMRuntimeKernel runtime_kernel; - - OMStatus status = runtime_kernel.readKernel(op_index, runtime_context); - if (status != Ok) - return status; - - const circle::Tensor *input1 = runtime_kernel.inputs[input1TensorIdx]; - const circle::Tensor *input2 = runtime_kernel.inputs[input2TensorIdx]; - const circle::Tensor *input3 = runtime_kernel.inputs[input3TensorIdx]; - const circle::Tensor *output = runtime_kernel.outputs[outputTensorIdx]; - - core::OMRuntimeShape input1_shape(input1); - core::OMRuntimeShape output_shape(output); - - assert(input1 != nullptr); - assert(input2 != nullptr); - assert(input3 != nullptr); - assert(output != nullptr); - - status = utils::checkCondition(input1->type() == output->type()); - if (status != Ok) - return status; - - status = utils::checkCondition(input2->type() == circle::TensorType_INT32); - if (status != Ok) - return status; - - status = utils::checkCondition(input3->type() == circle::TensorType_INT32); - if (status != Ok) - return status; - - status = utils::checkCondition(output_shape.dimensionsCount() >= 3); - if (status != Ok) - return status; - - status = utils::checkCondition(input1_shape.dimensionsCount() >= 3); - if (status != Ok) - return status; - - status = utils::checkCondition(output_shape.dimensionsCount() <= 4); - if (status != Ok) - return status; - - status = utils::checkCondition(input1_shape.dimensionsCount() <= 4); - if (status != Ok) - return status; - - return status; + return helpers::configure_spaces_batches_nd_kernel_common(config_args); } diff --git a/onert-micro/onert-micro/src/import/kernels/SpaceToBatchND.cpp b/onert-micro/onert-micro/src/import/kernels/SpaceToBatchND.cpp index c9959c5ac2e..f3db592fccf 100644 --- a/onert-micro/onert-micro/src/import/kernels/SpaceToBatchND.cpp +++ b/onert-micro/onert-micro/src/import/kernels/SpaceToBatchND.cpp @@ -14,75 +14,13 @@ * limitations under the License. */ -#include "import/OMKernelConfigureBuilder.h" -#include "core/OMUtils.h" -#include "OMStatus.h" -#include "execute/OMRuntimeKernel.h" +#include "import/helpers/OMSpacesBatchesNDCommon.h" using namespace onert_micro; using namespace onert_micro::core; -namespace -{ - -constexpr uint32_t input1TensorIdx = 0; -constexpr uint32_t input2TensorIdx = 1; -constexpr uint32_t input3TensorIdx = 2; -constexpr uint32_t outputTensorIdx = 0; - -} // namespace OMStatus onert_micro::import::configure_kernel_CircleSpaceToBatchND( const onert_micro::import::OMConfigureArgs &config_args) { - OMRuntimeContext &runtime_context = config_args.runtime_context; - uint16_t op_index = config_args.kernel_index; - - onert_micro::execute::OMRuntimeKernel runtime_kernel; - - OMStatus status = runtime_kernel.readKernel(op_index, runtime_context); - if (status != Ok) - return status; - - const circle::Tensor *input1 = runtime_kernel.inputs[input1TensorIdx]; - const circle::Tensor *input2 = runtime_kernel.inputs[input2TensorIdx]; - const circle::Tensor *input3 = runtime_kernel.inputs[input3TensorIdx]; - const circle::Tensor *output = runtime_kernel.outputs[outputTensorIdx]; - - core::OMRuntimeShape input1_shape(input1); - core::OMRuntimeShape output_shape(output); - - assert(input1 != nullptr); - assert(input2 != nullptr); - assert(input3 != nullptr); - assert(output != nullptr); - - status = utils::checkCondition(input1->type() == output->type()); - if (status != Ok) - return status; - - status = utils::checkCondition(input2->type() == circle::TensorType_INT32); - if (status != Ok) - return status; - - status = utils::checkCondition(input3->type() == circle::TensorType_INT32); - if (status != Ok) - return status; - - status = utils::checkCondition(output_shape.dimensionsCount() >= 3); - if (status != Ok) - return status; - - status = utils::checkCondition(input1_shape.dimensionsCount() >= 3); - if (status != Ok) - return status; - - status = utils::checkCondition(output_shape.dimensionsCount() <= 4); - if (status != Ok) - return status; - - status = utils::checkCondition(input1_shape.dimensionsCount() <= 4); - if (status != Ok) - return status; - - return status; + return helpers::configure_spaces_batches_nd_kernel_common(config_args); }