Skip to content

Commit

Permalink
[onert-micro] Reducing code duplication for FloorDiv, FloorMod, Min, …
Browse files Browse the repository at this point in the history
…Max, GatherND

Refactoring kernels: FloorDiv, FloorMod, Min, Max, GatherND for [issue](#13272)

ONE-DCO-1.0-Signed-off-by:  Evgenii Maltsev [email protected]
  • Loading branch information
Torrero committed Jun 25, 2024
1 parent 2ceb27c commit 723a16c
Show file tree
Hide file tree
Showing 8 changed files with 185 additions and 237 deletions.
41 changes: 41 additions & 0 deletions onert-micro/onert-micro/include/execute/kernels/ReadDataCommon.h
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions onert-micro/onert-micro/src/execute/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ set(SOURCES
OMUtils.cpp
kernels/ConvolutionCommon.cpp
kernels/PoolingCommon.cpp
kernels/ReadDataCommon.cpp
)

# Add configure kernels
Expand Down
73 changes: 21 additions & 52 deletions onert-micro/onert-micro/src/execute/kernels/FloorDiv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,89 +17,58 @@
#include "execute/OMKernelExecutionBuilder.h"
#include "OMStatus.h"
#include "execute/OMRuntimeKernel.h"
#include "execute/kernels/ReadDataCommon.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<float>(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<float>(input_data1),
core::utils::castInputData<float>(input_data2),
core::utils::castOutputData<float>(output_data));
}
else
{
pal::BroadcastFloorDiv4DSlow(input1_shape, core::utils::castInputData<float>(input_data1),
input2_shape, core::utils::castInputData<float>(input_data2),
pal::BroadcastFloorDiv4DSlow(input_shape1, core::utils::castInputData<float>(input_data1),
input_shape2, core::utils::castInputData<float>(input_data2),
output_shape, core::utils::castOutputData<float>(output_data));
}
}
Expand Down
71 changes: 17 additions & 54 deletions onert-micro/onert-micro/src/execute/kernels/FloorMod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,89 +17,52 @@
#include "execute/OMKernelExecutionBuilder.h"
#include "OMStatus.h"
#include "execute/OMRuntimeKernel.h"
#include "execute/kernels/ReadDataCommon.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<float>(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<float>(input_data1),
core::utils::castInputData<float>(input_data2),
core::utils::castOutputData<float>(output_data));
}
else
{
pal::BroadcastFloorMod4DSlow(input1_shape, core::utils::castInputData<float>(input_data1),
input2_shape, core::utils::castInputData<float>(input_data2),
pal::BroadcastFloorMod4DSlow(input_shape1, core::utils::castInputData<float>(input_data1),
input_shape2, core::utils::castInputData<float>(input_data2),
output_shape, core::utils::castOutputData<float>(output_data));
}
}
Expand Down
54 changes: 9 additions & 45 deletions onert-micro/onert-micro/src/execute/kernels/GatherND.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,68 +23,32 @@
#include "execute/OMKernelExecutionBuilder.h"
#include "execute/OMUtils.h"
#include "execute/OMRuntimeKernel.h"
#include "execute/kernels/ReadDataCommon.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:
Expand Down
Loading

0 comments on commit 723a16c

Please sign in to comment.