diff options
Diffstat (limited to 'runtime/onert/core/src/interp/operations')
-rw-r--r-- | runtime/onert/core/src/interp/operations/BinaryArithmeticOps.cc | 205 | ||||
-rw-r--r-- | runtime/onert/core/src/interp/operations/Concat.cc | 147 | ||||
-rw-r--r-- | runtime/onert/core/src/interp/operations/Conv2D.cc | 151 | ||||
-rw-r--r-- | runtime/onert/core/src/interp/operations/DepthwiseConv2D.cc | 156 | ||||
-rw-r--r-- | runtime/onert/core/src/interp/operations/ElementwiseActivations.cc | 161 | ||||
-rw-r--r-- | runtime/onert/core/src/interp/operations/FullyConnected.cc | 136 | ||||
-rw-r--r-- | runtime/onert/core/src/interp/operations/Gather.cc | 138 | ||||
-rw-r--r-- | runtime/onert/core/src/interp/operations/InstanceNorm.cc | 121 | ||||
-rw-r--r-- | runtime/onert/core/src/interp/operations/OperationUtil.h | 203 | ||||
-rw-r--r-- | runtime/onert/core/src/interp/operations/Pad.cc | 106 | ||||
-rw-r--r-- | runtime/onert/core/src/interp/operations/Pool2D.cc | 140 | ||||
-rw-r--r-- | runtime/onert/core/src/interp/operations/Reshape.cc | 63 | ||||
-rw-r--r-- | runtime/onert/core/src/interp/operations/Softmax.cc | 123 | ||||
-rw-r--r-- | runtime/onert/core/src/interp/operations/TransposeConv.cc | 141 |
14 files changed, 0 insertions, 1991 deletions
diff --git a/runtime/onert/core/src/interp/operations/BinaryArithmeticOps.cc b/runtime/onert/core/src/interp/operations/BinaryArithmeticOps.cc deleted file mode 100644 index 86e883524..000000000 --- a/runtime/onert/core/src/interp/operations/BinaryArithmeticOps.cc +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 2019 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 <cker/operation/BinaryArithmeticOps.h> - -#include "OperationUtil.h" - -#include "interp/Registration.h" -#include "ir/operation/BinaryArithmetic.h" -#include "misc/polymorphic_downcast.h" -#include "cker/Types.h" - -namespace onert -{ -namespace interp -{ -namespace -{ - -enum class OpType -{ - ADD, - SUB, - MUL -}; - -void prepare(ExecEnv *env, const ir::Operation &node) -{ - const auto &arithmetic_node = - nnfw::misc::polymorphic_downcast<const ir::operation::BinaryArithmetic &>(node); - - const auto lhs_index = node.getInputs().at(arithmetic_node.LHS); - const auto rhs_index = node.getInputs().at(arithmetic_node.RHS); - const auto out_index = node.getOutputs().at(0); - - const auto lhs_tensor = env->tensorAt(lhs_index); - const auto rhs_tensor = env->tensorAt(rhs_index); - - // Check shape and type lhs is same with rhs - // TODO Util function to compare TensorInfo - if (lhs_tensor->data_type() != rhs_tensor->data_type()) - { - throw std::runtime_error{"Interp(" + arithmetic_node.name() + "): Different input types"}; - } - - bool try_broadcast = (lhs_tensor->tensorInfo().shape() != rhs_tensor->tensorInfo().shape()); - if (try_broadcast) - { - bool success = true; - auto out_shape = calcBroadcastShape(lhs_tensor->tensorInfo().shape(), - rhs_tensor->tensorInfo().shape(), success); - if (!success) - { - throw std::runtime_error{"Interp(" + arithmetic_node.name() + "): Fail to brodcasting"}; - } - - auto output_info = - ir::OperandInfo::createStaticInfo(out_shape, lhs_tensor->tensorInfo().typeInfo()); - // We can handle already allocated (ex. model output) - env->allocateIfNeeded(out_index, output_info); - } - else - { - // Output's shape and type is same with input - auto output_info = lhs_tensor->tensorInfo(); - // We can handle already allocated (ex. model output) - env->allocateIfNeeded(out_index, output_info); - } - - auto out_tensor = env->tensorAt(out_index); - // Check shape and type lhs is same with output - // TODO Util function to compare TensorInfo - if (lhs_tensor->data_type() != out_tensor->data_type()) - { - throw std::runtime_error{"Interp(" + arithmetic_node.name() + "): Invalid output type"}; - } -} - -inline void setActivationParams(float min, float max, nnfw::cker::BinaryArithmeticOpParam *params) -{ - params->float_activation_min = min; - params->float_activation_max = max; -} - -inline void setActivationParams(int32_t min, int32_t max, - nnfw::cker::BinaryArithmeticOpParam *params) -{ - params->quantized_activation_min = min; - params->quantized_activation_max = max; -} - -template <typename raw_type, OpType op_type> -void invoke(const ITensor *lhs_tensor, const ITensor *rhs_tensor, const ITensor *out_tensor, - const ir::operation::BinaryArithmetic::Param ¶m) -{ - const auto lhs_buffer = lhs_tensor->bufferRO(); - const auto rhs_buffer = rhs_tensor->bufferRO(); - auto out_buffer = out_tensor->buffer(); - - nnfw::cker::BinaryArithmeticOpParam cker_param; - raw_type activation_min, activation_max; - calculateActivationRange(param.activation, &activation_min, &activation_max); - setActivationParams(activation_min, activation_max, &cker_param); - const raw_type *lhs_ptr = reinterpret_cast<const raw_type *>(lhs_buffer); - const raw_type *rhs_ptr = reinterpret_cast<const raw_type *>(rhs_buffer); - raw_type *out_ptr = reinterpret_cast<raw_type *>(out_buffer); - - const auto cker_op_type = - (op_type == OpType::ADD) - ? nnfw::cker::BinaryArithmeticOpType::ADD - : ((op_type == OpType::SUB) ? nnfw::cker::BinaryArithmeticOpType::SUB - : nnfw::cker::BinaryArithmeticOpType::MUL); - - const bool need_broadcast = nnfw::cker::ProcessBroadcastShapes( - convertShape(lhs_tensor->tensorInfo().shape()), - convertShape(rhs_tensor->tensorInfo().shape()), &cker_param); - - if (need_broadcast) - { - const auto lhs_shape = convertShape(lhs_tensor->tensorInfo().shape()); - const auto rhs_shape = convertShape(rhs_tensor->tensorInfo().shape()); - const auto out_shape = convertShape(out_tensor->tensorInfo().shape()); - nnfw::cker::BroadcastBinaryArithmeticOp<cker_op_type>(cker_param, lhs_shape, lhs_ptr, rhs_shape, - rhs_ptr, out_shape, out_ptr); - return; - } - - const auto lhs_shape = convertShape(lhs_tensor->tensorInfo().shape()); - const auto rhs_shape = convertShape(rhs_tensor->tensorInfo().shape()); - const auto out_shape = convertShape(out_tensor->tensorInfo().shape()); - nnfw::cker::BinaryArithmeticOp<cker_op_type>(cker_param, lhs_shape, lhs_ptr, rhs_shape, rhs_ptr, - out_shape, out_ptr); -} - -template <OpType op_type> -void invokeBinaryArithmetic(const ExecEnv *env, const ir::operation::BinaryArithmetic &node) -{ - const auto lhs_index = node.getInputs().at(node.LHS); - const auto rhs_index = node.getInputs().at(node.RHS); - const auto out_index = node.getOutputs().at(0); - const auto lhs_tensor = env->tensorAt(lhs_index); - const auto rhs_tensor = env->tensorAt(rhs_index); - const auto out_tensor = env->tensorAt(out_index); - const auto data_type = lhs_tensor->data_type(); - - if (data_type == ir::DataType::INT32) - { - invoke<int32_t, op_type>(lhs_tensor, rhs_tensor, out_tensor, node.param()); - } - else if (data_type == ir::DataType::FLOAT32) - { - invoke<float, op_type>(lhs_tensor, rhs_tensor, out_tensor, node.param()); - } - else - { - throw std::runtime_error{"NYI: Unsupported data type"}; - } -} - -void invokeBinaryArithmeticOps(const ExecEnv *env, const ir::Operation &node) -{ - const auto &arithmetic_node = - nnfw::misc::polymorphic_downcast<const ir::operation::BinaryArithmetic &>(node); - - switch (arithmetic_node.param().arithmetic_type) - { - case ir::operation::BinaryArithmetic::ArithmeticType::ADD: - invokeBinaryArithmetic<OpType::ADD>(env, arithmetic_node); - break; - case ir::operation::BinaryArithmetic::ArithmeticType::SUB: - invokeBinaryArithmetic<OpType::SUB>(env, arithmetic_node); - break; - case ir::operation::BinaryArithmetic::ArithmeticType::MUL: - invokeBinaryArithmetic<OpType::MUL>(env, arithmetic_node); - break; - default: - throw std::runtime_error{"Interp(BinaryArithmetic): NYI unsupported operation " + - arithmetic_node.name()}; - break; - } -} - -} // namespace - -OpKernel *getBinaryArithmetic() -{ - static OpKernel kernel = {prepare, invokeBinaryArithmeticOps}; - return &kernel; -} - -} // namespace interp -} // namespace onert diff --git a/runtime/onert/core/src/interp/operations/Concat.cc b/runtime/onert/core/src/interp/operations/Concat.cc deleted file mode 100644 index efc46c66b..000000000 --- a/runtime/onert/core/src/interp/operations/Concat.cc +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2019 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 <cker/operation/Concatenation.h> - -#include "OperationUtil.h" - -#include "interp/Registration.h" -#include "ir/operation/Concat.h" -#include "misc/polymorphic_downcast.h" - -namespace onert -{ -namespace interp -{ -namespace concat -{ - -void prepareConcat(ExecEnv *env, const ir::Operation &node) -{ - const auto &concat_node = nnfw::misc::polymorphic_downcast<const ir::operation::Concat &>(node); - - const auto first_index = node.getInputs().at(0); - const auto out_index = node.getOutputs().at(0); - - const auto first_tensor = env->tensorAt(first_index); - uint32_t out_axis_dimension = 0; - const int32_t axis_raw = concat_node.param().axis; - const uint32_t axis = (axis_raw < 0) ? (axis_raw + first_tensor->num_dimensions()) : axis_raw; - - // All inputs shape should be same except axis dimension - // All inputs type should be same - for (auto input : node.getInputs()) - { - assert(first_tensor->num_dimensions() == env->tensorAt(input)->num_dimensions()); - assert(first_tensor->data_type() == env->tensorAt(input)->data_type()); - for (uint32_t i = 0; i < first_tensor->num_dimensions(); i++) - { - if (i == axis) - { - out_axis_dimension += env->tensorAt(input)->dimension(i); - continue; - } - assert(first_tensor->dimension(i) == env->tensorAt(input)->dimension(i)); - } - } - - // Make output tensor info using first input tensor info, and accumulated axis dimension value - auto out_shape = first_tensor->tensorInfo().shape(); - out_shape.dim(axis) = out_axis_dimension; - env->allocateIfNeeded(out_index, ir::OperandInfo::createStaticInfo( - out_shape, first_tensor->tensorInfo().typeInfo())); - - auto out_tensor = env->tensorAt(out_index); - UNUSED_RELEASE(out_tensor); - - // Output shape should be same with input except axis dimension - // Output type should be same with input - assert(first_tensor->data_type() == out_tensor->data_type()); - for (uint32_t i = 0; i < first_tensor->num_dimensions(); i++) - { - if (i == axis) - { - continue; - } - assert(first_tensor->dimension(i) == out_tensor->dimension(i)); - } -} - -void invoke(const std::vector<const ITensor *> in_tensors, const ITensor *out_tensor, uint32_t axis) -{ - const uint32_t count = in_tensors.size(); - - // Calculate - nnfw::cker::ConcatenationParams cker_param; - cker_param.axis = (int8_t)axis; - cker_param.inputs_count = count; - - const auto out_shape = convertShape(out_tensor->tensorInfo().shape()); - - std::vector<nnfw::cker::Shape> in_shapes; - std::vector<const nnfw::cker::Shape *> in_shape_ptrs; - in_shapes.reserve(count); - in_shape_ptrs.reserve(count); - std::vector<const float *> in_ptrs; - for (uint32_t i = 0; i < count; i++) - { - in_shapes.push_back(convertShape(in_tensors[i]->tensorInfo().shape())); - in_shape_ptrs.push_back(&in_shapes[i]); - in_ptrs.push_back(reinterpret_cast<const float *>(in_tensors[i]->bufferRO())); - } - - auto out_buffer = out_tensor->buffer(); - float *out_ptr = reinterpret_cast<float *>(out_buffer); - - nnfw::cker::Concatenation<float>(cker_param, in_shape_ptrs.data(), in_ptrs.data(), out_shape, - out_ptr); -} - -void invokeConcat(const ExecEnv *env, const ir::Operation &node) -{ - const auto &concat_node = nnfw::misc::polymorphic_downcast<const ir::operation::Concat &>(node); - const int32_t axis_raw = concat_node.param().axis; - - std::vector<const ITensor *> in_tensors; - for (const auto &e : concat_node.getInputs()) - { - in_tensors.emplace_back(env->tensorAt(e)); - } - - const auto out_index = node.getOutputs().at(0); - const auto out_tensor = env->tensorAt(out_index); - const uint32_t axis = (axis_raw < 0) ? (axis_raw + out_tensor->num_dimensions()) : axis_raw; - - const auto data_type = in_tensors[0]->data_type(); - if (data_type == ir::DataType::FLOAT32) - { - invoke(in_tensors, out_tensor, axis); - } - else - { - throw std::runtime_error{"NYI: Support float32 only"}; - } -} -} // namespace concat - -OpKernel *getConcat() -{ - static OpKernel kernel = {concat::prepareConcat, concat::invokeConcat}; - return &kernel; -} - -} // namespace interp -} // namespace onert diff --git a/runtime/onert/core/src/interp/operations/Conv2D.cc b/runtime/onert/core/src/interp/operations/Conv2D.cc deleted file mode 100644 index bb00b828c..000000000 --- a/runtime/onert/core/src/interp/operations/Conv2D.cc +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2019 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 <cker/operation/Conv.h> - -#include "OperationUtil.h" - -#include "interp/Registration.h" -#include "ir/operation/Conv2D.h" -#include "util/Utils.h" -#include "util/ShapeInference.h" -#include "misc/polymorphic_downcast.h" - -namespace onert -{ -namespace interp -{ -namespace conv2d -{ - -void prepareConv2D(ExecEnv *env, const ir::Operation &node) -{ - const auto in_index = node.getInputs().at(ir::operation::Conv2D::INPUT); - const auto kernel_index = node.getInputs().at(ir::operation::Conv2D::KERNEL); - const auto bias_index = node.getInputs().at(ir::operation::Conv2D::BIAS); - const auto out_index = node.getOutputs().at(0); - - const auto in_tensor = env->tensorAt(in_index); - const auto kernel_tensor = env->tensorAt(kernel_index); - const auto bias_tensor = env->tensorAt(bias_index); - - assert(in_tensor->num_dimensions() == 4); - assert(kernel_tensor->num_dimensions() == 4); - assert(bias_tensor->num_dimensions() == 1); - - UNUSED_RELEASE(in_tensor); - UNUSED_RELEASE(kernel_tensor); - UNUSED_RELEASE(bias_tensor); - - const auto output_info = env->graph().operands().at(out_index).info(); - if (output_info.total_size() == 0) - { - // Handle unspecified output shape - const auto &conv_node = nnfw::misc::polymorphic_downcast<const ir::operation::Conv2D &>(node); - const auto infered_output_shape = shape_inference::inferConv2DShape( - in_tensor->tensorInfo().shape(), kernel_tensor->tensorInfo().shape(), conv_node.param()); - env->allocateIfNeeded( - out_index, ir::OperandInfo::createStaticInfo(infered_output_shape, output_info.typeInfo())); - } - else - { - env->allocateIfNeeded(out_index, output_info); - } - - auto out_tensor = env->tensorAt(out_index); - UNUSED_RELEASE(out_tensor); - - // Handle same ifm & ofm data type only - assert(in_tensor->data_type() == out_tensor->data_type()); - assert(out_tensor->num_dimensions() == 4); -} - -void invoke(const ITensor *ifm_tensor, const ITensor *ker_tensor, const ITensor *bias_tensor, - const ITensor *ofm_tensor, const ir::operation::Conv2D::Param ¶m) -{ - // TODO Support NCHW frontned - const auto ifm_shape = ifm_tensor->tensorInfo().shape().asFeature(ir::Layout::NHWC); - const auto ofm_shape = ofm_tensor->tensorInfo().shape().asFeature(ir::Layout::NHWC); - // Kernel format is [depth_out, kernel_height, kernel_width, depth_in]. - const auto &ker_shape = ker_tensor->tensorInfo().shape(); - const auto ker_height = ker_shape.dim(1); - const auto ker_width = ker_shape.dim(2); - const auto padding = ir::calculatePadding(param.padding, ifm_shape, ofm_shape, param.stride, - ker_width, ker_height); - - // Calculate - float activation_min, activation_max; - calculateActivationRange(param.activation, &activation_min, &activation_max); - - nnfw::cker::ConvParams cker_param; - cker_param.padding_type = convertPaddingType(param.padding.type); - cker_param.padding_values.width = padding.left; - cker_param.padding_values.height = padding.top; - cker_param.stride_width = param.stride.horizontal; - cker_param.stride_height = param.stride.vertical; - cker_param.dilation_width_factor = 1; - cker_param.dilation_height_factor = 1; - cker_param.float_activation_min = activation_min; - cker_param.float_activation_max = activation_max; - - const auto cker_ifm_shape = convertShape(ifm_tensor->tensorInfo().shape()); - const auto cker_ker_shape = convertShape(ker_tensor->tensorInfo().shape()); - const auto cker_bias_shape = convertShape(bias_tensor->tensorInfo().shape()); - const auto cker_ofm_shape = convertShape(ofm_tensor->tensorInfo().shape()); - const float *ifm_ptr = reinterpret_cast<const float *>(ifm_tensor->bufferRO()); - const float *ker_ptr = reinterpret_cast<const float *>(ker_tensor->bufferRO()); - const float *bias_ptr = reinterpret_cast<const float *>(bias_tensor->bufferRO()); - float *ofm_ptr = reinterpret_cast<float *>(ofm_tensor->buffer()); - - nnfw::cker::Conv conv_kernel; - conv_kernel(cker_param, cker_ifm_shape, ifm_ptr, cker_ker_shape, ker_ptr, cker_bias_shape, - bias_ptr, cker_ofm_shape, ofm_ptr); -} - -void invokeConv2D(const ExecEnv *env, const ir::Operation &node) -{ - const auto &conv_node = nnfw::misc::polymorphic_downcast<const ir::operation::Conv2D &>(node); - - const auto ifm_index = node.getInputs().at(ir::operation::Conv2D::INPUT); - const auto ker_index = node.getInputs().at(ir::operation::Conv2D::KERNEL); - const auto bias_index = node.getInputs().at(ir::operation::Conv2D::BIAS); - const auto ofm_index = node.getOutputs().at(0); - - const auto ifm_tensor = env->tensorAt(ifm_index); - const auto ker_tensor = env->tensorAt(ker_index); - const auto bias_tensor = env->tensorAt(bias_index); - const auto ofm_tensor = env->tensorAt(ofm_index); - - const auto data_type = ifm_tensor->data_type(); - if (data_type == ir::DataType::FLOAT32) - { - invoke(ifm_tensor, ker_tensor, bias_tensor, ofm_tensor, conv_node.param()); - } - else - { - throw std::runtime_error{"NYI: Support float32 only"}; - } -} -} // namespace conv2d - -OpKernel *getConv2D() -{ - static OpKernel kernel = {conv2d::prepareConv2D, conv2d::invokeConv2D}; - return &kernel; -} - -} // namespace interp -} // namespace onert diff --git a/runtime/onert/core/src/interp/operations/DepthwiseConv2D.cc b/runtime/onert/core/src/interp/operations/DepthwiseConv2D.cc deleted file mode 100644 index 0473855d9..000000000 --- a/runtime/onert/core/src/interp/operations/DepthwiseConv2D.cc +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2019 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 <cker/operation/DepthwiseConv.h> -#include <misc/polymorphic_downcast.h> - -#include "OperationUtil.h" - -#include "interp/Registration.h" -#include "ir/operation/DepthwiseConv2D.h" -#include "util/Utils.h" -#include "util/ShapeInference.h" - -namespace onert -{ -namespace interp -{ - -namespace -{ - -void prepareDepthwiseConv(ExecEnv *env, const ir::Operation &node) -{ - const auto in_index = node.getInputs().at(ir::operation::DepthwiseConv2D::INPUT); - const auto kernel_index = node.getInputs().at(ir::operation::DepthwiseConv2D::KERNEL); - const auto bias_index = node.getInputs().at(ir::operation::DepthwiseConv2D::BIAS); - const auto out_index = node.getOutputs().at(0); - - const auto in_tensor = env->tensorAt(in_index); - const auto kernel_tensor = env->tensorAt(kernel_index); - const auto bias_tensor = env->tensorAt(bias_index); - - assert(in_tensor->num_dimensions() == 4); - assert(kernel_tensor->num_dimensions() == 4); - assert(bias_tensor->num_dimensions() == 1); - - UNUSED_RELEASE(in_tensor); - UNUSED_RELEASE(kernel_tensor); - UNUSED_RELEASE(bias_tensor); - - // TODO handle unspecified output shape: - // calculate output shape using ifm shape, kernel shape, padding, stride - const auto output_info = env->graph().operands().at(out_index).info(); - if (output_info.total_size() == 0) - { - // Handle unspecified output shape - const auto &depth_conv_node = - nnfw::misc::polymorphic_downcast<const ir::operation::DepthwiseConv2D &>(node); - const auto infered_output_shape = shape_inference::inferDepthwiseConv2DShape( - in_tensor->tensorInfo().shape(), kernel_tensor->tensorInfo().shape(), - depth_conv_node.param()); - env->allocateIfNeeded( - out_index, ir::OperandInfo::createStaticInfo(infered_output_shape, output_info.typeInfo())); - } - else - { - env->allocateIfNeeded(out_index, output_info); - } - - auto out_tensor = env->tensorAt(out_index); - UNUSED_RELEASE(out_tensor); - - // Handle same ifm & ofm data type only - assert(in_tensor->data_type() == out_tensor->data_type()); - assert(out_tensor->num_dimensions() == 4); -} - -void invoke(const ITensor *ifm_tensor, const ITensor *ker_tensor, const ITensor *bias_tensor, - const ITensor *ofm_tensor, const ir::operation::DepthwiseConv2D::Param ¶m) -{ - // TODO Support NCHW frontend - const auto ifm_shape = ifm_tensor->tensorInfo().shape().asFeature(ir::Layout::NHWC); - const auto ofm_shape = ofm_tensor->tensorInfo().shape().asFeature(ir::Layout::NHWC); - // Kernel format is [1, kernel_height, kernel_width, depth_out]. - const auto &ker_shape = ker_tensor->tensorInfo().shape(); - const auto ker_height = ker_shape.dim(1); - const auto ker_width = ker_shape.dim(2); - const auto padding = ir::calculatePadding(param.padding, ifm_shape, ofm_shape, param.stride, - ker_width, ker_height); - - // Calculate - float activation_min, activation_max; - calculateActivationRange(param.activation, &activation_min, &activation_max); - - nnfw::cker::DepthwiseConvParams cker_param; - cker_param.padding_values.width = padding.left; - cker_param.padding_values.height = padding.top; - cker_param.depth_multiplier = param.multiplier; - cker_param.stride_width = param.stride.horizontal; - cker_param.stride_height = param.stride.vertical; - cker_param.dilation_width_factor = 1; - cker_param.dilation_height_factor = 1; - cker_param.float_activation_min = activation_min; - cker_param.float_activation_max = activation_max; - - const auto cker_ifm_shape = convertShape(ifm_tensor->tensorInfo().shape()); - const auto cker_ker_shape = convertShape(ker_tensor->tensorInfo().shape()); - const auto cker_bias_shape = convertShape(bias_tensor->tensorInfo().shape()); - const auto cker_ofm_shape = convertShape(ofm_tensor->tensorInfo().shape()); - const float *ifm_ptr = reinterpret_cast<const float *>(ifm_tensor->bufferRO()); - const float *ker_ptr = reinterpret_cast<const float *>(ker_tensor->bufferRO()); - const float *bias_ptr = reinterpret_cast<const float *>(bias_tensor->bufferRO()); - float *ofm_ptr = reinterpret_cast<float *>(ofm_tensor->buffer()); - - nnfw::cker::DepthwiseConv(cker_param, cker_ifm_shape, ifm_ptr, cker_ker_shape, ker_ptr, - cker_bias_shape, bias_ptr, cker_ofm_shape, ofm_ptr); -} - -void invokeDepthwiseConv(const ExecEnv *env, const ir::Operation &node) -{ - const auto &conv_node = static_cast<const ir::operation::DepthwiseConv2D &>(node); - - const auto ifm_index = node.getInputs().at(ir::operation::DepthwiseConv2D::INPUT); - const auto ker_index = node.getInputs().at(ir::operation::DepthwiseConv2D::KERNEL); - const auto bias_index = node.getInputs().at(ir::operation::DepthwiseConv2D::BIAS); - const auto ofm_index = node.getOutputs().at(0); - - const auto ifm_tensor = env->tensorAt(ifm_index); - const auto ker_tensor = env->tensorAt(ker_index); - const auto bias_tensor = env->tensorAt(bias_index); - const auto ofm_tensor = env->tensorAt(ofm_index); - - const auto data_type = ifm_tensor->data_type(); - if (data_type == ir::DataType::FLOAT32) - { - invoke(ifm_tensor, ker_tensor, bias_tensor, ofm_tensor, conv_node.param()); - } - else - { - throw std::runtime_error{"NYI: Support float32 only"}; - } -} - -} // namespace - -OpKernel *getDepthwiseConv2D() -{ - static OpKernel kernel = {prepareDepthwiseConv, invokeDepthwiseConv}; - return &kernel; -} - -} // namespace interp -} // namespace onert diff --git a/runtime/onert/core/src/interp/operations/ElementwiseActivations.cc b/runtime/onert/core/src/interp/operations/ElementwiseActivations.cc deleted file mode 100644 index c8773bef4..000000000 --- a/runtime/onert/core/src/interp/operations/ElementwiseActivations.cc +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <cmath> - -#include "OperationUtil.h" - -#include "interp/Registration.h" - -#include "ir/operation/ElementwiseActivation.h" - -#include <misc/polymorphic_downcast.h> -#include <cker/operation/Logistic.h> -#include <cker/operation/Tanh.h> - -namespace onert -{ -namespace interp -{ -namespace -{ - -enum class ActivationType -{ - Logistic, - ReLU, - Tanh -}; - -void prepare(ExecEnv *env, const ir::Operation &node) -{ - const auto input_index = node.getInputs().at(0); - const auto output_index = node.getOutputs().at(0); - - const auto input_tensor = env->tensorAt(input_index); - - const auto output_info = env->graph().operands().at(output_index).info(); - if (output_info.total_size() == 0) - { - // Output's shape and type is same with input - auto input_info = input_tensor->tensorInfo(); - // We can handle already allocated (ex. model output) - env->allocateIfNeeded(output_index, input_info); - } - else - { - env->allocateIfNeeded(output_index, output_info); - } - - const auto output_tensor = env->tensorAt(output_index); - // Check shape and type lhs is same with output - // TODO Util function to compare TensorInfo - if (input_tensor->data_type() != output_tensor->data_type()) - { - throw std::runtime_error{"Interp(ElementwiseActivation): Invalid output type"}; - } -} - -template <ActivationType act_type> -void evalFloat(const float *input_ptr, float *output_ptr, uint64_t num_elements, float alpha, - float beta) -{ - std::function<float(const float &)> fn = [](const float &) { return std::nanf(""); }; - switch (act_type) - { - case ActivationType::ReLU: - fn = [alpha, beta](const float &in) { return std::min(std::max(beta, in), alpha); }; - break; - case ActivationType::Tanh: - fn = [](const float &in) { return std::tanh(in); }; - break; - default: - throw std::runtime_error{"Interp(ElementwiseActivation): NYI - Unsupported activation"}; - break; - } - - const float *input_end = input_ptr + num_elements; - for (; input_ptr < input_end; input_ptr++, output_ptr++) - { - *output_ptr = fn(*input_ptr); - } -} - -template <ActivationType act_type> void invoke(const ExecEnv *env, const ir::Operation &node) -{ - const auto input_index = node.getInputs().at(0); - const auto output_index = node.getOutputs().at(0); - - // Check lhs shape is same with rhs (with broadcast) - const auto input_tensor = env->tensorAt(input_index); - const auto output_tensor = env->tensorAt(output_index); - - const auto data_type = input_tensor->data_type(); - if (data_type == ir::DataType::FLOAT32) - { - uint64_t elements = input_tensor->num_elements(); - const float *input_start = reinterpret_cast<const float *>(input_tensor->bufferRO()); - float *out = reinterpret_cast<float *>(output_tensor->buffer()); - if (act_type == ActivationType::Logistic) - { - const auto cker_input_shape = convertShape(input_tensor->tensorInfo().shape()); - const auto cker_output_shape = convertShape(output_tensor->tensorInfo().shape()); - nnfw::cker::Logistic(cker_input_shape, input_start, cker_output_shape, out); - } - else - { - const auto &act_node = - nnfw::misc::polymorphic_downcast<const ir::operation::ElementwiseActivation &>(node); - evalFloat<act_type>(input_start, out, elements, act_node.param().alpha, - act_node.param().beta); - } - } - else - { - throw std::runtime_error{"Interp(" + node.name() + "): NYI - Support float only"}; - } -} - -void invokeElementwiseActivation(const ExecEnv *env, const ir::Operation &node) -{ - const auto &act_node = - nnfw::misc::polymorphic_downcast<const ir::operation::ElementwiseActivation &>(node); - switch (act_node.param().op_type) - { - case ir::operation::ElementwiseActivation::Type::LOGISTIC: - invoke<ActivationType::Logistic>(env, node); - break; - case ir::operation::ElementwiseActivation::Type::RELU: - invoke<ActivationType::ReLU>(env, node); - break; - case ir::operation::ElementwiseActivation::Type::TANH: - invoke<ActivationType::Tanh>(env, node); - break; - default: - throw std::runtime_error("Interp(" + node.name() + "): NYI - Unsupported activation"); - } -} - -} // namespace - -OpKernel *getElementwiseActivation() -{ - static OpKernel kernel = {prepare, invokeElementwiseActivation}; - return &kernel; -} - -} // namespace interp -} // namespace onert diff --git a/runtime/onert/core/src/interp/operations/FullyConnected.cc b/runtime/onert/core/src/interp/operations/FullyConnected.cc deleted file mode 100644 index 12f529dab..000000000 --- a/runtime/onert/core/src/interp/operations/FullyConnected.cc +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2019 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 <cker/operation/FullyConnected.h> - -#include "OperationUtil.h" - -#include "interp/Registration.h" -#include "ir/operation/FullyConnected.h" -#include "misc/polymorphic_downcast.h" - -namespace onert -{ -namespace interp -{ -namespace fc -{ - -void prepareFC(ExecEnv *env, const ir::Operation &node) -{ - const auto in_index = node.getInputs().at(ir::operation::FullyConnected::INPUT); - const auto kernel_index = node.getInputs().at(ir::operation::FullyConnected::WEIGHT); - const auto bias_index = node.getInputs().at(ir::operation::FullyConnected::BIAS); - const auto out_index = node.getOutputs().at(0); - - const auto in_tensor = env->tensorAt(in_index); - const auto kernel_tensor = env->tensorAt(kernel_index); - const auto bias_tensor = env->tensorAt(bias_index); - - UNUSED_RELEASE(in_tensor); - UNUSED_RELEASE(kernel_tensor); - UNUSED_RELEASE(bias_tensor); - - assert(in_tensor->num_dimensions() >= 2); - assert(kernel_tensor->num_dimensions() == 2); - assert(bias_tensor->num_dimensions() == 1); - - const auto input_size_with_batch = in_tensor->num_elements(); - const auto num_units = kernel_tensor->dimension(0); - const auto input_size = kernel_tensor->dimension(1); - const auto batch_size = input_size_with_batch / input_size; - assert(input_size_with_batch % input_size == 0); - assert(num_units == bias_tensor->dimension(0)); - - // Make output tensor info - ir::Shape output_shape(2); - output_shape.dim(0) = batch_size; - output_shape.dim(1) = num_units; - const auto out_info = - ir::OperandInfo::createStaticInfo(output_shape, in_tensor->tensorInfo().typeInfo()); - env->allocateIfNeeded(out_index, out_info); - - auto out_tensor = env->tensorAt(out_index); - UNUSED_RELEASE(out_tensor); - - // Handle same ifm & ofm data type only - assert(in_tensor->data_type() == out_tensor->data_type()); - assert(out_tensor->num_dimensions() == 2); - assert(out_tensor->dimension(0) == batch_size); - assert(out_tensor->dimension(1) == num_units); -} - -void invoke(const ITensor *ifm_tensor, const ITensor *ker_tensor, const ITensor *bias_tensor, - const ITensor *ofm_tensor, const ir::operation::FullyConnected::Param ¶m) -{ - const auto ifm_buffer = ifm_tensor->bufferRO(); - const auto ker_buffer = ker_tensor->bufferRO(); - const auto bias_buffer = bias_tensor->bufferRO(); - auto ofm_buffer = ofm_tensor->buffer(); - - // Calculate - nnfw::cker::FullyConnectedParams cker_param; - cker_param.activation = convertActivationType(param.activation); - calculateActivationRange(param.activation, &cker_param.float_activation_min, - &cker_param.float_activation_max); - const auto cker_ifm_shape = convertShape(ifm_tensor->tensorInfo().shape()); - const auto cker_ker_shape = convertShape(ker_tensor->tensorInfo().shape()); - const auto cker_bias_shape = convertShape(bias_tensor->tensorInfo().shape()); - const auto cker_ofm_shape = convertShape(ofm_tensor->tensorInfo().shape()); - const float *ifm_ptr = reinterpret_cast<const float *>(ifm_buffer); - const float *ker_ptr = reinterpret_cast<const float *>(ker_buffer); - const float *bias_ptr = reinterpret_cast<const float *>(bias_buffer); - float *ofm_ptr = reinterpret_cast<float *>(ofm_buffer); - - nnfw::cker::FullyConnected(cker_param, cker_ifm_shape, ifm_ptr, cker_ker_shape, ker_ptr, - cker_bias_shape, bias_ptr, cker_ofm_shape, ofm_ptr); -} - -void invokeFC(const ExecEnv *env, const ir::Operation &node) -{ - const auto &conv_node = - nnfw::misc::polymorphic_downcast<const ir::operation::FullyConnected &>(node); - - const auto ifm_index = node.getInputs().at(ir::operation::FullyConnected::INPUT); - const auto ker_index = node.getInputs().at(ir::operation::FullyConnected::WEIGHT); - const auto bias_index = node.getInputs().at(ir::operation::FullyConnected::BIAS); - const auto ofm_index = node.getOutputs().at(0); - - const auto ifm_tensor = env->tensorAt(ifm_index); - const auto ker_tensor = env->tensorAt(ker_index); - const auto bias_tensor = env->tensorAt(bias_index); - const auto ofm_tensor = env->tensorAt(ofm_index); - - const auto data_type = ifm_tensor->data_type(); - if (data_type == ir::DataType::FLOAT32) - { - invoke(ifm_tensor, ker_tensor, bias_tensor, ofm_tensor, conv_node.param()); - } - else - { - throw std::runtime_error{"NYI: Support float only"}; - } -} -} // namespace fc - -OpKernel *getFullyConnected() -{ - static OpKernel kernel = {fc::prepareFC, fc::invokeFC}; - return &kernel; -} - -} // namespace interp -} // namespace onert diff --git a/runtime/onert/core/src/interp/operations/Gather.cc b/runtime/onert/core/src/interp/operations/Gather.cc deleted file mode 100644 index 9e82def5f..000000000 --- a/runtime/onert/core/src/interp/operations/Gather.cc +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2019 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 <cker/operation/Gather.h> - -#include "OperationUtil.h" - -#include "interp/Registration.h" -#include "ir/operation/Gather.h" -#include "misc/polymorphic_downcast.h" - -namespace onert -{ -namespace interp -{ -namespace -{ - -void prepareGather(ExecEnv *env, const ir::Operation &node) -{ - const auto input_index = node.getInputs().at(ir::operation::Gather::INPUT); - const auto indices_index = node.getInputs().at(ir::operation::Gather::INDICES); - const auto output_index = node.getOutputs().at(0); - - const auto input_tensor = env->tensorAt(input_index); - const auto indices_tensor = env->tensorAt(indices_index); - - // TODO handle unspecified output shape: - // calculate output shape using ifm shape, kernel shape, padding, stride - const auto output_info = env->graph().operands().at(output_index).info(); - if (output_info.total_size() == 0) - { - throw std::runtime_error{"Interp(Gather): NYI for unspecified output shape"}; - } - else - { - env->allocateIfNeeded(output_index, output_info); - } - - if (indices_tensor->data_type() != ir::DataType::INT32) - { - throw std::runtime_error{"Interp(Gather): Invalid indices data type"}; - } - - auto output_tensor = env->tensorAt(output_index); - auto output_rank = input_tensor->num_dimensions() + indices_tensor->num_dimensions() - 1; - - if (output_rank != output_tensor->num_dimensions()) - { - throw std::runtime_error{"Interp(Gather): Invalid output rank"}; - } - if (output_tensor->data_type() != input_tensor->data_type()) - { - throw std::runtime_error{"Interp(Gather): Invalid output data type"}; - } - - if (input_tensor->data_type() == ir::DataType::QUANT_UINT8_ASYMM && - input_tensor->tensorInfo().typeInfo() != output_tensor->tensorInfo().typeInfo()) - { - throw std::runtime_error{ - "Interp(Gather): Cannot handle different I/O QUANT_UINT8_ASYMM scale/offset"}; - } -} - -template <typename raw_type> -void invoke(const ITensor *input_tensors, const ITensor *indices_tensors, - const ITensor *output_tensor, uint32_t axis) -{ - // Calculate - nnfw::cker::GatherParams cker_param; - cker_param.axis = (int8_t)axis; - - const auto cker_input_shapes = convertShape(input_tensors->tensorInfo().shape()); - const auto cker_indices_shape = convertShape(indices_tensors->tensorInfo().shape()); - const auto cker_output_shape = convertShape(output_tensor->tensorInfo().shape()); - const raw_type *input_ptr = reinterpret_cast<const raw_type *>(input_tensors->bufferRO()); - const int32_t *indices_ptr = reinterpret_cast<const int32_t *>(indices_tensors->bufferRO()); - raw_type *output_ptr = reinterpret_cast<raw_type *>(output_tensor->buffer()); - - nnfw::cker::Gather<raw_type>(cker_param, cker_input_shapes, input_ptr, cker_indices_shape, - indices_ptr, cker_output_shape, output_ptr); -} - -void invokeGather(const ExecEnv *env, const ir::Operation &node) -{ - const auto &gather_node = nnfw::misc::polymorphic_downcast<const ir::operation::Gather &>(node); - const int32_t axis_raw = gather_node.param().axis; - - const auto input_index = node.getInputs().at(ir::operation::Gather::INPUT); - const auto indices_index = node.getInputs().at(ir::operation::Gather::INDICES); - const auto output_index = node.getOutputs().at(0); - - const auto input_tensor = env->tensorAt(input_index); - const auto indices_tensor = env->tensorAt(indices_index); - const auto output_tensor = env->tensorAt(output_index); - const uint32_t axis = (axis_raw < 0) ? (axis_raw + input_tensor->num_dimensions()) : axis_raw; - - const auto data_type = input_tensor->data_type(); - - switch (data_type) - { - case ir::DataType::FLOAT32: - invoke<float>(input_tensor, indices_tensor, output_tensor, axis); - break; - case ir::DataType::INT32: - invoke<int32_t>(input_tensor, indices_tensor, output_tensor, axis); - break; - case ir::DataType::QUANT_UINT8_ASYMM: - invoke<uint8_t>(input_tensor, indices_tensor, output_tensor, axis); - break; - default: - throw std::runtime_error{"Interp(Gather): NYI - Not supported type"}; - } -} - -} // namespace - -OpKernel *getGather() -{ - static OpKernel kernel = {prepareGather, invokeGather}; - return &kernel; -} - -} // namespace interp -} // namespace onert diff --git a/runtime/onert/core/src/interp/operations/InstanceNorm.cc b/runtime/onert/core/src/interp/operations/InstanceNorm.cc deleted file mode 100644 index 2538bcc39..000000000 --- a/runtime/onert/core/src/interp/operations/InstanceNorm.cc +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <cker/operation/InstanceNorm.h> - -#include "OperationUtil.h" - -#include "interp/Registration.h" -#include "ir/operation/InstanceNorm.h" -#include "misc/polymorphic_downcast.h" - -namespace onert -{ -namespace interp -{ -namespace instancenorm -{ - -void prepareInstanceNorm(ExecEnv *env, const ir::Operation &node) -{ - const auto &instancenorm_node = - nnfw::misc::polymorphic_downcast<const ir::operation::InstanceNorm &>(node); - - const auto input_index = node.getInputs().at(instancenorm_node.INPUT); - const auto output_index = node.getOutputs().at(0); - const auto input_tensor = env->tensorAt(input_index); - - if (input_tensor->num_dimensions() != 4) - { - throw std::runtime_error{"Interp(InstanceNorm): Input should be 4D-tensor"}; - } - - // Output shape should be same with input - env->allocateIfNeeded(output_index, input_tensor->tensorInfo()); - - auto output_tensor = env->tensorAt(output_index); - UNUSED_RELEASE(output_tensor); - - // Handle same ifm & ofm data type only - assert(input_tensor->data_type() == output_tensor->data_type()); - assert(input_tensor->tensorInfo().shape() == output_tensor->tensorInfo().shape()); -} - -inline void setActivationParams(float min, float max, nnfw::cker::InstanceNormParams *params) -{ - params->float_activation_min = min; - params->float_activation_max = max; -} - -void invoke(const ITensor *input_tensor, const ITensor *gamma_tensor, const ITensor *beta_tensor, - const ITensor *output_tensor, const ir::operation::InstanceNorm::Param ¶m) -{ - // Calculate - float activation_min, activation_max; - calculateActivationRange(param.activation, &activation_min, &activation_max); - - nnfw::cker::InstanceNormParams cker_param; - cker_param.epsilon = param.epsilon; - cker_param.float_activation_min = activation_min; - cker_param.float_activation_max = activation_max; - - const auto cker_input_shape = convertShape(input_tensor->tensorInfo().shape()); - const auto cker_gamma_shape = convertShape(gamma_tensor->tensorInfo().shape()); - const auto cker_beta_shape = convertShape(beta_tensor->tensorInfo().shape()); - const auto cker_output_shape = convertShape(output_tensor->tensorInfo().shape()); - const float *input_ptr = reinterpret_cast<const float *>(input_tensor->bufferRO()); - const float *gamma_ptr = reinterpret_cast<const float *>(gamma_tensor->bufferRO()); - const float *beta_ptr = reinterpret_cast<const float *>(beta_tensor->bufferRO()); - float *output_ptr = reinterpret_cast<float *>(output_tensor->buffer()); - - nnfw::cker::InstanceNorm(cker_param, cker_input_shape, input_ptr, cker_gamma_shape, gamma_ptr, - cker_beta_shape, beta_ptr, cker_output_shape, output_ptr); -} - -void invokeInstanceNorm(const ExecEnv *env, const ir::Operation &node) -{ - const auto &instancenorm_node = - nnfw::misc::polymorphic_downcast<const ir::operation::InstanceNorm &>(node); - - const auto input_index = node.getInputs().at(instancenorm_node.INPUT); - const auto gamma_index = node.getInputs().at(instancenorm_node.GAMMA); - const auto beta_index = node.getInputs().at(instancenorm_node.BETA); - const auto out_index = node.getOutputs().at(0); - const auto input_tensor = env->tensorAt(input_index); - const auto gamma_tensor = env->tensorAt(gamma_index); - const auto beta_tensor = env->tensorAt(beta_index); - const auto out_tensor = env->tensorAt(out_index); - const auto data_type = input_tensor->data_type(); - - if (data_type == ir::DataType::FLOAT32) - { - invoke(input_tensor, gamma_tensor, beta_tensor, out_tensor, instancenorm_node.param()); - } - else - { - throw std::runtime_error{"NYI: Unsupported data type"}; - } -} -} // namespace instancenorm - -OpKernel *getInstanceNorm() -{ - static OpKernel kernel = {instancenorm::prepareInstanceNorm, instancenorm::invokeInstanceNorm}; - return &kernel; -} - -} // namespace interp -} // namespace onert diff --git a/runtime/onert/core/src/interp/operations/OperationUtil.h b/runtime/onert/core/src/interp/operations/OperationUtil.h deleted file mode 100644 index 2fdf098f0..000000000 --- a/runtime/onert/core/src/interp/operations/OperationUtil.h +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (c) 2019 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_INTERP_OPERATIONS_OPERATION_UTILS_H_ -#define __ONERT_INTERP_OPERATIONS_OPERATION_UTILS_H_ - -#include "ir/Shape.h" -#include "ir/InternalType.h" -#include "ir/Padding.h" - -#include <cker/Shape.h> -#include <cker/Types.h> - -namespace onert -{ -namespace interp -{ - -inline nnfw::cker::Shape convertShape(const ir::Shape &shape) -{ - auto dimensions = std::vector<uint32_t>(shape.dims().begin(), shape.dims().end()); - - std::vector<int32_t> raw_shape; - raw_shape.resize(dimensions.size()); - - for (uint32_t i = 0; i < dimensions.size(); ++i) - { - raw_shape[i] = dimensions[i]; - } - - return nnfw::cker::GetShape(raw_shape); -} - -inline nnfw::cker::Shape convertExtendShape(const ir::Shape &shape) -{ - auto dimensions = std::vector<uint32_t>(shape.dims().begin(), shape.dims().end()); - - const int32_t extended_rank = 4; - int32_t raw_shape[extended_rank]; - uint32_t start = extended_rank - dimensions.size(); - - for (uint32_t i = 0; i < extended_rank; ++i) - { - if (i < start) - { - raw_shape[i] = 1; - } - else - { - raw_shape[i] = dimensions[i - start]; - } - } - - return nnfw::cker::Shape(extended_rank, raw_shape); -} - -inline nnfw::cker::FusedActivationFunctionType -convertActivationType(const ir::Activation activation) -{ - switch (activation) - { - case ir::Activation::NONE: - return nnfw::cker::FusedActivationFunctionType::kNone; - case ir::Activation::RELU: - return nnfw::cker::FusedActivationFunctionType::kRelu; - case ir::Activation::RELU1: - return nnfw::cker::FusedActivationFunctionType::kRelu1; - case ir::Activation::RELU6: - return nnfw::cker::FusedActivationFunctionType::kRelu6; - default: - throw std::runtime_error{"CPU backend: Cannot convert activation type"}; - } -} - -template <typename T> -void calculateActivationRange(ir::Activation activation, T *activation_min, T *activation_max) -{ - if (activation == ir::Activation::RELU) - { - *activation_min = 0; - *activation_max = std::numeric_limits<T>::max(); - } - else if (activation == ir::Activation::RELU6) - { - *activation_min = 0; - *activation_max = 6; - } - else if (activation == ir::Activation::RELU1) - { - *activation_min = -1; - *activation_max = 1; - } - else if (activation == ir::Activation::NONE) - { - *activation_min = std::numeric_limits<T>::lowest(); - *activation_max = std::numeric_limits<T>::max(); - } - else - { - throw std::runtime_error{"Unsupported activation type"}; - } -} - -inline ir::Shape calcBroadcastShape(const ir::Shape &lhs, const ir::Shape &rhs, bool &success) -{ - int lhs_rank = lhs.rank(); - int rhs_rank = rhs.rank(); - - int out_rank = (lhs_rank > rhs_rank ? lhs_rank : rhs_rank); - ir::Shape out_shape(out_rank); - - int lhs_idim = lhs_rank - 1; - int rhs_idim = rhs_rank - 1; - success = true; - for (int out_idim = out_rank - 1; out_idim >= 0; out_idim--) - { - if (lhs_idim == -1 && rhs_idim == -1) - { - // invalid result - success = false; - break; - } - - if (lhs_idim == -1) - { - out_shape.dim(out_idim) = rhs.dim(rhs_idim); - rhs_idim--; - } - else if (rhs_idim == -1) - { - out_shape.dim(out_idim) = lhs.dim(lhs_idim); - lhs_idim--; - } - else - { - if (lhs.dim(lhs_idim) == rhs.dim(rhs_idim)) - { - out_shape.dim(out_idim) = lhs.dim(lhs_idim); - lhs_idim--; - rhs_idim--; - } - else if (lhs.dim(lhs_idim) == 1) - { - out_shape.dim(out_idim) = rhs.dim(rhs_idim); - lhs_idim--; - rhs_idim--; - } - else if (rhs.dim(rhs_idim) == 1) - { - out_shape.dim(out_idim) = lhs.dim(lhs_idim); - lhs_idim--; - rhs_idim--; - } - else - { - // invalid result - success = false; - break; - } - } - } - - if (lhs_idim != -1 || rhs_idim != -1) - { - // invalid result - success = false; - } - return out_shape; -} - -inline nnfw::cker::PaddingType convertPaddingType(ir::PaddingType ir_padding_type) -{ - switch (ir_padding_type) - { - case ir::PaddingType::EXPLICIT: - return nnfw::cker::PaddingType::kNone; - case ir::PaddingType::SAME: - return nnfw::cker::PaddingType::kSame; - case ir::PaddingType::VALID: - return nnfw::cker::PaddingType::kValid; - default: - throw std::runtime_error("Wrong padding type."); - break; - } -} - -} // namespace interp -} // namespace onert - -#endif // __ONERT_INTERP_OPERATIONS_OPERATION_UTILS_H_ diff --git a/runtime/onert/core/src/interp/operations/Pad.cc b/runtime/onert/core/src/interp/operations/Pad.cc deleted file mode 100644 index c8dce698d..000000000 --- a/runtime/onert/core/src/interp/operations/Pad.cc +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2019 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 <cker/operation/Pad.h> - -#include "OperationUtil.h" - -#include "interp/Registration.h" -#include "ir/operation/Pad.h" - -namespace onert -{ -namespace interp -{ -namespace -{ - -void preparePad(ExecEnv *env, const ir::Operation &node) -{ - const auto input_index = node.getInputs().at(ir::operation::Pad::INPUT); - const auto output_index = node.getOutputs().at(0); - - const auto input_tensor = env->tensorAt(input_index); - - const auto output_info = env->graph().operands().at(output_index).info(); - - // Check shape and type lhs is same with rhs - // TODO Util function to compare TensorInfo - if (output_info.total_size() == 0) - { - throw std::runtime_error{"Interp(Pad): NYI unspecified output shape"}; - } - else - { - env->allocateIfNeeded(output_index, output_info); - } - - const auto output_tensor = env->tensorAt(output_index); - if (input_tensor->data_type() != output_tensor->data_type()) - { - throw std::runtime_error{"Interp(Pad): Invalid output type"}; - } -} - -void invoke(const ITensor *input_tensor, const ITensor *pad_tensor, const ITensor *output_tensor) -{ - const auto input_buffer = input_tensor->bufferRO(); - const auto pad_buffer = pad_tensor->bufferRO(); - auto output_buffer = output_tensor->buffer(); - - int32_t pad_rank = pad_tensor->dimension(0); - - const auto cker_input_shape = convertShape(input_tensor->tensorInfo().shape()); - const auto cker_output_shape = convertShape(output_tensor->tensorInfo().shape()); - const float *input_ptr = reinterpret_cast<const float *>(input_buffer); - const int32_t *pad_ptr = reinterpret_cast<const int32_t *>(pad_buffer); - float *output_ptr = reinterpret_cast<float *>(output_buffer); - - nnfw::cker::Pad<float>(pad_ptr, pad_rank, cker_input_shape, input_ptr, cker_output_shape, - output_ptr, nullptr); -} - -void invokePad(const ExecEnv *env, const ir::Operation &node) -{ - const auto input_index = node.getInputs().at(ir::operation::Pad::INPUT); - const auto pad_index = node.getInputs().at(ir::operation::Pad::PAD); - const auto output_index = node.getOutputs().at(0); - - const auto input_tensor = env->tensorAt(input_index); - const auto pad_tensor = env->tensorAt(pad_index); - const auto output_tensor = env->tensorAt(output_index); - - const auto data_type = input_tensor->data_type(); - - if (data_type == ir::DataType::FLOAT32) - { - invoke(input_tensor, pad_tensor, output_tensor); - } - else - { - throw std::runtime_error{"Interp(Pad): NYI - Unsupported data type"}; - } -} -} // namespace - -OpKernel *getPad() -{ - static OpKernel kernel = {preparePad, invokePad}; - return &kernel; -} - -} // namespace interp -} // namespace onert diff --git a/runtime/onert/core/src/interp/operations/Pool2D.cc b/runtime/onert/core/src/interp/operations/Pool2D.cc deleted file mode 100644 index 92f9d70b2..000000000 --- a/runtime/onert/core/src/interp/operations/Pool2D.cc +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2019 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 <cker/operation/AveragePool.h> -#include <cker/operation/MaxPool.h> - -#include "OperationUtil.h" - -#include "interp/Registration.h" -#include "ir/operation/Pool2D.h" -#include "util/Utils.h" -#include "util/ShapeInference.h" -#include "misc/polymorphic_downcast.h" - -namespace onert -{ -namespace interp -{ -namespace pool2d -{ - -void preparePool2D(ExecEnv *env, const ir::Operation &node) -{ - const auto &pool_node = nnfw::misc::polymorphic_downcast<const ir::operation::Pool2D &>(node); - const auto in_index = node.getInputs().at(pool_node.INPUT); - const auto out_index = node.getOutputs().at(0); - - const auto in_tensor = env->tensorAt(in_index); - UNUSED_RELEASE(in_tensor); - - assert(in_tensor->num_dimensions() == 4); - - const auto output_info = env->graph().operands().at(out_index).info(); - if (output_info.total_size() == 0) - { - // Handle unspecified output shape - const auto infered_output_shape = - shape_inference::inferPoolShape(in_tensor->tensorInfo().shape(), pool_node.param()); - env->allocateIfNeeded( - out_index, ir::OperandInfo::createStaticInfo(infered_output_shape, output_info.typeInfo())); - } - else - { - env->allocateIfNeeded(out_index, output_info); - } - - auto out_tensor = env->tensorAt(out_index); - UNUSED_RELEASE(out_tensor); - - // Handle same ifm & ofm data type only - assert(in_tensor->data_type() == out_tensor->data_type()); - assert(out_tensor->num_dimensions() == 4); -} - -template <typename T> -void invoke(const nnfw::cker::PoolParams ¶ms, const nnfw::cker::Shape &in_shape, - const T *in_ptr, const nnfw::cker::Shape &out_shape, T *out_ptr, - ir::operation::Pool2D::PoolType op_type) -{ - switch (op_type) - { - case ir::operation::Pool2D::PoolType::AVG: - nnfw::cker::AveragePool<T>(params, in_shape, in_ptr, out_shape, out_ptr); - break; - case ir::operation::Pool2D::PoolType::MAX: - nnfw::cker::MaxPool<T>(params, in_shape, in_ptr, out_shape, out_ptr); - break; - default: - throw std::runtime_error{"Interp(Pool2D): NYI unsupported operation"}; - break; - } -} - -void invokePool2DOps(const ExecEnv *env, const ir::Operation &node) -{ - const auto &pool_node = nnfw::misc::polymorphic_downcast<const ir::operation::Pool2D &>(node); - - const auto in_index = node.getInputs().at(0); - const auto out_index = node.getOutputs().at(0); - - // Check lhs shape is same with rhs (with broadcast) - const auto in_tensor = env->tensorAt(in_index); - const auto out_tensor = env->tensorAt(out_index); - - // TODO support NCHW frontend - const auto ifm_shape = in_tensor->tensorInfo().shape().asFeature(ir::Layout::NHWC); - const auto ofm_shape = out_tensor->tensorInfo().shape().asFeature(ir::Layout::NHWC); - const auto param = pool_node.param(); - const auto padding = - ir::calculatePadding(param.padding, ifm_shape, ofm_shape, param.stride, param.kw, param.kh); - // Calculate - nnfw::cker::PoolParams cker_param; - cker_param.filter_width = param.kw; - cker_param.filter_height = param.kh; - cker_param.padding_values.width = padding.left; - cker_param.padding_values.height = padding.top; - cker_param.stride_width = param.stride.horizontal; - cker_param.stride_height = param.stride.vertical; - - const auto data_type = in_tensor->data_type(); - if (data_type == ir::DataType::FLOAT32) - { - calculateActivationRange(param.activation, &cker_param.float_activation_min, - &cker_param.float_activation_max); - - const auto in_shape = convertShape(in_tensor->tensorInfo().shape()); - const auto out_shape = convertShape(out_tensor->tensorInfo().shape()); - const float *in_ptr = reinterpret_cast<const float *>(in_tensor->bufferRO()); - float *out_ptr = reinterpret_cast<float *>(out_tensor->buffer()); - // Now, invoke() supports only Pool2D in float - invoke<float>(cker_param, in_shape, in_ptr, out_shape, out_ptr, param.op_type); - } - else - { - throw std::runtime_error{"NYI: Support float only"}; - } -} -} // namespace pool2d - -OpKernel *getPool2D() -{ - static OpKernel kernel = {pool2d::preparePool2D, pool2d::invokePool2DOps}; - return &kernel; -} - -} // namespace interp -} // namespace onert diff --git a/runtime/onert/core/src/interp/operations/Reshape.cc b/runtime/onert/core/src/interp/operations/Reshape.cc deleted file mode 100644 index 3a118456b..000000000 --- a/runtime/onert/core/src/interp/operations/Reshape.cc +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2019 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 "interp/Registration.h" - -namespace onert -{ -namespace interp -{ -namespace -{ - -void prepare(ExecEnv *env, const ir::Operation &node) -{ - const auto in_index = node.getInputs().at(0); - const auto out_index = node.getOutputs().at(0); - - // Unspecified shape is not supported in operation node spec now - const auto output_info = env->graph().operands().at(out_index).info(); - env->allocateAndShareIfNeeded(out_index, output_info, in_index); - - assert(output_info.total_size() == env->graph().operands().at(in_index).info().total_size()); -} - -void invoke(const ExecEnv *env, const ir::Operation &node) -{ - const auto in_index = node.getInputs().at(0); - const auto out_index = node.getOutputs().at(0); - - if (env->tensorAt(in_index)->bufferRO() == env->tensorAt(out_index)->bufferRO()) - { - // Same data - return; - } - - const auto output_info = env->graph().operands().at(out_index).info(); - memcpy(env->tensorAt(out_index)->buffer(), env->tensorAt(in_index)->bufferRO(), - output_info.total_size()); -} - -} // namespace - -OpKernel *getReshape() -{ - static OpKernel kernel = {prepare, invoke}; - return &kernel; -} - -} // namespace interp -} // namespace onert diff --git a/runtime/onert/core/src/interp/operations/Softmax.cc b/runtime/onert/core/src/interp/operations/Softmax.cc deleted file mode 100644 index d30f78deb..000000000 --- a/runtime/onert/core/src/interp/operations/Softmax.cc +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2019 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 <cker/operation/SoftMax.h> - -#include "OperationUtil.h" - -#include "interp/Registration.h" -#include "ir/operation/Softmax.h" -#include "misc/polymorphic_downcast.h" - -namespace onert -{ -namespace interp -{ -namespace -{ - -void prepareSoftMax(ExecEnv *env, const ir::Operation &node) -{ - const auto in_index = node.getInputs().at(0); - const auto out_index = node.getOutputs().at(0); - - const auto in_tensor = env->tensorAt(in_index); - UNUSED_RELEASE(in_tensor); - - assert((in_tensor->num_dimensions() == 4) || (in_tensor->num_dimensions() == 2)); - - // Output shape should be same with input - // Output type is pre-defined in model - const auto output_shape = env->graph().operands().at(in_index).info().shape(); - const auto output_type = env->graph().operands().at(out_index).info().typeInfo(); - - const auto output_info = ir::OperandInfo::createStaticInfo(output_shape, output_type); - env->allocateIfNeeded(out_index, output_info); - - auto out_tensor = env->tensorAt(out_index); - UNUSED_RELEASE(out_tensor); - - // Check output shape is same with input - assert(out_tensor->num_dimensions() == out_tensor->num_dimensions()); - for (uint32_t i = 0; i < in_tensor->num_dimensions(); i++) - { - assert(in_tensor->dimension(i) == out_tensor->dimension(i)); - } -} - -void invoke(const ITensor *in_tensor, const ITensor *out_tensor, - const ir::operation::Softmax::Param ¶m) -{ - const float *in_ptr = reinterpret_cast<const float *>(in_tensor->bufferRO()); - float *out_ptr = reinterpret_cast<float *>(out_tensor->buffer()); - - float beta = param.beta; - - if (in_tensor->num_dimensions() == 2) - { - uint32_t batch_size = in_tensor->dimension(0); - uint32_t input_size = in_tensor->dimension(1); - - nnfw::cker::Softmax(in_ptr, input_size, batch_size, beta, out_ptr); - } - else if (in_tensor->num_dimensions() == 4) - { - const auto in_shape = convertShape(in_tensor->tensorInfo().shape()); - const auto out_shape = convertShape(out_tensor->tensorInfo().shape()); - - nnfw::cker::SoftmaxParams cker_param; - cker_param.beta = beta; - - nnfw::cker::Softmax(cker_param, in_shape, in_ptr, out_shape, out_ptr); - } - else - { - throw std::runtime_error{"Unsuported input dimension: support 2D or 4D"}; - } -} - -void invokeSoftMax(const ExecEnv *env, const ir::Operation &node) -{ - const auto &softmax_node = nnfw::misc::polymorphic_downcast<const ir::operation::Softmax &>(node); - - const auto in_index = node.getInputs().at(0); - const auto out_index = node.getOutputs().at(0); - - const auto in_tensor = env->tensorAt(in_index); - const auto out_tensor = env->tensorAt(out_index); - - const auto in_data_type = in_tensor->data_type(); - const auto out_data_type = out_tensor->data_type(); - if ((in_data_type == ir::DataType::FLOAT32) && (out_data_type == ir::DataType::FLOAT32)) - { - invoke(in_tensor, out_tensor, softmax_node.param()); - } - else - { - throw std::runtime_error{"NYI: Support float32 only"}; - } -} - -} // namespace - -OpKernel *getSoftmax() -{ - static OpKernel kernel = {prepareSoftMax, invokeSoftMax}; - return &kernel; -} - -} // namespace interp -} // namespace onert diff --git a/runtime/onert/core/src/interp/operations/TransposeConv.cc b/runtime/onert/core/src/interp/operations/TransposeConv.cc deleted file mode 100644 index cc2ced26b..000000000 --- a/runtime/onert/core/src/interp/operations/TransposeConv.cc +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2019 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 <cker/operation/TransposeConv.h> -#include <misc/polymorphic_downcast.h> - -#include "OperationUtil.h" - -#include "interp/Registration.h" -#include "ir/operation/TransposeConv.h" - -namespace onert -{ -namespace interp -{ -namespace -{ - -void prepareTransposeConv(ExecEnv *env, const ir::Operation &node) -{ - const auto ifm_index = node.getInputs().at(ir::operation::TransposeConv::INPUT); - const auto ker_index = node.getInputs().at(ir::operation::TransposeConv::KERNEL); - const auto ofm_shape_index = node.getInputs().at(ir::operation::TransposeConv::OUTPUT_SHAPE); - const auto ofm_index = node.getOutputs().at(0); - - const auto ifm_tensor = env->tensorAt(ifm_index); - const auto ker_tensor = env->tensorAt(ker_index); - const auto ofm_shape_tensor = env->tensorAt(ofm_shape_index); - - assert(ifm_tensor->num_dimensions() == 4); - assert(ker_tensor->num_dimensions() == 4); - assert(ofm_shape_tensor->num_dimensions() == 1); - - UNUSED_RELEASE(ifm_tensor); - UNUSED_RELEASE(ker_tensor); - UNUSED_RELEASE(ofm_shape_tensor); - - const auto output_info = env->graph().operands().at(ofm_index).info(); - if (output_info.total_size() == 0) - { - // TODO: Handle unspecified output shape - throw std::runtime_error{"Interp(TConv): NYI unspecified output shape"}; - } - else - { - env->allocateIfNeeded(ofm_index, output_info); - } - - auto ofm_tensor = env->tensorAt(ofm_index); - UNUSED_RELEASE(ofm_tensor); - - // Handle same ifm & ofm data type only - if (ifm_tensor->data_type() != ofm_tensor->data_type()) - { - throw std::runtime_error{"Interp(TConv): Different I/O data dype"}; - } - - if (ofm_tensor->num_dimensions() != 4) - { - throw std::runtime_error{"Interp(TConv): Invalid output rank"}; - } -} - -void invoke(const ITensor *ifm_tensor, const ITensor *ker_tensor, const ITensor *ofm_tensor, - const ir::operation::TransposeConv::Param ¶m) -{ - const auto ifm_shape = ifm_tensor->tensorInfo().shape().asFeature(ir::Layout::NHWC); - const auto ofm_shape = ofm_tensor->tensorInfo().shape().asFeature(ir::Layout::NHWC); - // Kernel format is [depth_out, kernel_height, kernel_width, depth_in]. - const auto ker_shape = ker_tensor->tensorInfo().shape(); - const auto ker_height = ker_shape.dim(1); - const auto ker_width = ker_shape.dim(2); - const auto padding = ir::calculatePadding(param.padding, ofm_shape, ifm_shape, param.stride, - ker_width, ker_height); - - nnfw::cker::TransposeConvParams cker_param; - cker_param.padding_values.width = padding.left; - cker_param.padding_values.height = padding.top; - cker_param.stride_width = param.stride.horizontal; - cker_param.stride_height = param.stride.vertical; - cker_param.dilation_width_factor = 1; - cker_param.dilation_height_factor = 1; - - const auto cker_ifm_shape = convertShape(ifm_tensor->tensorInfo().shape()); - const auto cker_ker_shape = convertShape(ker_tensor->tensorInfo().shape()); - const auto cker_ofm_shape = convertShape(ofm_tensor->tensorInfo().shape()); - const float *ifm_ptr = reinterpret_cast<const float *>(ifm_tensor->bufferRO()); - const float *ker_ptr = reinterpret_cast<const float *>(ker_tensor->bufferRO()); - float *ofm_ptr = reinterpret_cast<float *>(ofm_tensor->buffer()); - - nnfw::cker::TransposeConv(cker_param, cker_ifm_shape, ifm_ptr, cker_ker_shape, ker_ptr, - cker_ofm_shape, ofm_ptr); -} - -void invokeTransposeConv(const ExecEnv *env, const ir::Operation &node) -{ - const auto &tconv_node = - nnfw::misc::polymorphic_downcast<const ir::operation::TransposeConv &>(node); - - const auto ifm_index = node.getInputs().at(ir::operation::TransposeConv::INPUT); - const auto ker_index = node.getInputs().at(ir::operation::TransposeConv::KERNEL); - const auto ofm_index = node.getOutputs().at(0); - - const auto ifm_tensor = env->tensorAt(ifm_index); - const auto ker_tensor = env->tensorAt(ker_index); - const auto ofm_tensor = env->tensorAt(ofm_index); - - const auto data_type = ifm_tensor->data_type(); - if (data_type == ir::DataType::FLOAT32) - { - invoke(ifm_tensor, ker_tensor, ofm_tensor, tconv_node.param()); - } - else - { - throw std::runtime_error{"Interp(TConv): Support float32 only"}; - } -} - -} // namespace - -OpKernel *getTransposeConv() -{ - static OpKernel kernel = {prepareTransposeConv, invokeTransposeConv}; - return &kernel; -} - -} // namespace interp -} // namespace onert |