From 5a09b418012ccf434463abbbe5a3139947c7f3cf Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=98=A4=ED=98=95=EC=84=9D/On-Device=20Lab=28SR=29/Staff?= =?utf8?q?=20Engineer/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Wed, 22 May 2019 15:51:00 +0900 Subject: [PATCH] Revise padding parameter setting for depthwise convolution (#5234) * Revise padding parameter setting for depthwise convolution - Resolve explicit padding param value at frontend - Introduce util function to calculate padding from type and additional info - Use introduced function on backend Signed-off-by: Hyeongseok Oh * Update function name --- runtimes/neurun/backend/acl_cl/StageGenerator.cc | 29 +++--------------- runtimes/neurun/backend/acl_neon/StageGenerator.cc | 29 +++--------------- runtimes/neurun/backend/cpu/StageGenerator.cc | 32 ++++---------------- .../include/model/operation/DepthwiseConv2DNode.h | 7 ----- runtimes/neurun/core/include/util/Padding.h | 4 +++ runtimes/neurun/core/src/util/Padding.cc | 24 +++++++++++++++ .../frontend/nnapi/wrapper/OperationFactory.cc | 35 +++++++++++++++++++--- 7 files changed, 72 insertions(+), 88 deletions(-) diff --git a/runtimes/neurun/backend/acl_cl/StageGenerator.cc b/runtimes/neurun/backend/acl_cl/StageGenerator.cc index 8058e17..7182095 100644 --- a/runtimes/neurun/backend/acl_cl/StageGenerator.cc +++ b/runtimes/neurun/backend/acl_cl/StageGenerator.cc @@ -350,31 +350,10 @@ void StageGenerator::visit(const model::operation::DepthwiseConv2DNode &node) param.stride = stride; - // TODO : Extract this to a function - const auto padding_type = node.param().padding.type; - param.padding = [&]() { - if (padding_type != model::PaddingType::EXPLICIT) // implicit padding - { - assert((padding_type == model::PaddingType::SAME) || - (padding_type == model::PaddingType::VALID)); - - return (padding_type == model::PaddingType::SAME) - ? neurun::util::same_padding(_ctx.at(ifm_index).shape().asFeature(), - _ctx.at(ofm_index).shape().asFeature(), param.stride, - ker_shape.W, ker_shape.H) - : neurun::util::valid_padding(); - } - else // explicit padding - { - model::ExplicitPadding padding; - padding.left = _ctx.at({node.param().padding_left_index}).asScalar(); - padding.right = _ctx.at({node.param().padding_right_index}).asScalar(); - padding.top = _ctx.at({node.param().padding_top_index}).asScalar(); - padding.bottom = _ctx.at({node.param().padding_bottom_index}).asScalar(); - - return padding; - } - }(); + const auto ifm_shape = _ctx.at(ifm_index).shape().asFeature(); + const auto ofm_shape = _ctx.at(ofm_index).shape().asFeature(); + param.padding = neurun::util::calculatePadding(node.param().padding, ifm_shape, ofm_shape, + param.stride, ker_shape.W, ker_shape.H); param.multiplier = multiplier; param.activation = node.param().activation; diff --git a/runtimes/neurun/backend/acl_neon/StageGenerator.cc b/runtimes/neurun/backend/acl_neon/StageGenerator.cc index d3b464c..9503986 100644 --- a/runtimes/neurun/backend/acl_neon/StageGenerator.cc +++ b/runtimes/neurun/backend/acl_neon/StageGenerator.cc @@ -317,31 +317,10 @@ void StageGenerator::visit(const model::operation::DepthwiseConv2DNode &node) param.stride = stride; - // TODO : Extract this to a function - const auto padding_type = node.param().padding.type; - param.padding = [&]() { - if (padding_type != model::PaddingType::EXPLICIT) // implicit padding - { - assert((padding_type == model::PaddingType::SAME) || - (padding_type == model::PaddingType::VALID)); - - return (padding_type == model::PaddingType::SAME) - ? neurun::util::same_padding(_ctx.at(ifm_index).shape().asFeature(), - _ctx.at(ofm_index).shape().asFeature(), param.stride, - ker_shape.W, ker_shape.H) - : neurun::util::valid_padding(); - } - else // explicit padding - { - model::ExplicitPadding padding; - padding.left = _ctx.at({node.param().padding_left_index}).asScalar(); - padding.right = _ctx.at({node.param().padding_right_index}).asScalar(); - padding.top = _ctx.at({node.param().padding_top_index}).asScalar(); - padding.bottom = _ctx.at({node.param().padding_bottom_index}).asScalar(); - - return padding; - } - }(); + const auto ifm_shape = _ctx.at(ifm_index).shape().asFeature(); + const auto ofm_shape = _ctx.at(ofm_index).shape().asFeature(); + param.padding = neurun::util::calculatePadding(node.param().padding, ifm_shape, ofm_shape, + param.stride, ker_shape.W, ker_shape.H); param.multiplier = multiplier; param.activation = node.param().activation; diff --git a/runtimes/neurun/backend/cpu/StageGenerator.cc b/runtimes/neurun/backend/cpu/StageGenerator.cc index 90ba443..a2abde1 100644 --- a/runtimes/neurun/backend/cpu/StageGenerator.cc +++ b/runtimes/neurun/backend/cpu/StageGenerator.cc @@ -209,33 +209,11 @@ void StageGenerator::visit(const model::operation::DepthwiseConv2DNode &node) param.stride = stride; - // TODO : Extract this to a function - const auto padding_type = node.param().padding.type; - param.padding = [&]() { - if (padding_type != model::PaddingType::EXPLICIT) // implicit padding - { - assert((padding_type == model::PaddingType::SAME) || - (padding_type == model::PaddingType::VALID)); - - return (padding_type == model::PaddingType::SAME) - ? neurun::util::same_padding(_ctx.at(ifm_index).shape().asFeature(), - _ctx.at(ofm_index).shape().asFeature(), param.stride, - _ctx.at(ker_index).shape().asKernel().W, - _ctx.at(ker_index).shape().asKernel().H) - : neurun::util::valid_padding(); - } - else // explicit padding - { - model::ExplicitPadding padding; - padding.left = _ctx.at({node.param().padding_left_index}).asScalar(); - padding.right = _ctx.at({node.param().padding_right_index}).asScalar(); - padding.top = _ctx.at({node.param().padding_top_index}).asScalar(); - padding.bottom = _ctx.at({node.param().padding_bottom_index}).asScalar(); - - return padding; - } - }(); - + const auto ifm_shape = _ctx.at(ifm_index).shape().asFeature(); + const auto ofm_shape = _ctx.at(ofm_index).shape().asFeature(); + const auto ker_shape = _ctx.at(ker_index).shape().asKernel(); + param.padding = neurun::util::calculatePadding(node.param().padding, ifm_shape, ofm_shape, + param.stride, ker_shape.W, ker_shape.H); param.multiplier = multiplier; param.activation = node.param().activation; diff --git a/runtimes/neurun/core/include/model/operation/DepthwiseConv2DNode.h b/runtimes/neurun/core/include/model/operation/DepthwiseConv2DNode.h index 5d27eb5..c12a5f0 100644 --- a/runtimes/neurun/core/include/model/operation/DepthwiseConv2DNode.h +++ b/runtimes/neurun/core/include/model/operation/DepthwiseConv2DNode.h @@ -43,14 +43,7 @@ public: { OperandIndex hstride_index; OperandIndex vstride_index; - Padding padding; - - OperandIndex padding_left_index; - OperandIndex padding_right_index; - OperandIndex padding_top_index; - OperandIndex padding_bottom_index; - OperandIndex multiplier_index; Activation activation; }; diff --git a/runtimes/neurun/core/include/util/Padding.h b/runtimes/neurun/core/include/util/Padding.h index eacc05f..f5660ba 100644 --- a/runtimes/neurun/core/include/util/Padding.h +++ b/runtimes/neurun/core/include/util/Padding.h @@ -38,6 +38,10 @@ model::ExplicitPadding valid_padding(void); model::ExplicitPadding same_padding(const nnfw::misc::feature::Shape &ifm_shape, const nnfw::misc::feature::Shape &ofm_shape, const Stride &stride, uint32_t kw, uint32_t kh); +model::ExplicitPadding calculatePadding(const model::Padding &padding, + const nnfw::misc::feature::Shape &ifm_shape, + const nnfw::misc::feature::Shape &ofm_shape, + const Stride &stride, uint32_t kw, uint32_t kh); } // namespace util } // namespace neurun diff --git a/runtimes/neurun/core/src/util/Padding.cc b/runtimes/neurun/core/src/util/Padding.cc index badfb1c..79427e7 100644 --- a/runtimes/neurun/core/src/util/Padding.cc +++ b/runtimes/neurun/core/src/util/Padding.cc @@ -17,6 +17,7 @@ #include "util/Padding.h" #include +#include namespace neurun { @@ -71,5 +72,28 @@ model::ExplicitPadding same_padding(const nnfw::misc::feature::Shape &ifm_shape, return padding; } +model::ExplicitPadding calculatePadding(const model::Padding &padding, + const nnfw::misc::feature::Shape &ifm_shape, + const nnfw::misc::feature::Shape &ofm_shape, + const Stride &stride, uint32_t kw, uint32_t kh) +{ + if (padding.type == model::PaddingType::EXPLICIT) + { + return padding.param; + } + else if (padding.type == model::PaddingType::SAME) + { + return same_padding(ifm_shape, ofm_shape, stride, kw, kh); + } + else if (padding.type == model::PaddingType::VALID) + { + return valid_padding(); + } + else + { + throw std::runtime_error{"Cannot handle padding type"}; + } +} + } // namespace util } // namespace neurun diff --git a/runtimes/neurun/frontend/nnapi/wrapper/OperationFactory.cc b/runtimes/neurun/frontend/nnapi/wrapper/OperationFactory.cc index cd0c9ac..25e00a9 100644 --- a/runtimes/neurun/frontend/nnapi/wrapper/OperationFactory.cc +++ b/runtimes/neurun/frontend/nnapi/wrapper/OperationFactory.cc @@ -29,6 +29,30 @@ void replaceDataType(Operands &operands, const OperandIndex &index, const DataTy operands.at(index).type(type); } +ExplicitPadding setExplicitPaddingParam(Operands &operands, const OperandIndex &left_index, + const OperandIndex &right_index, + const OperandIndex &top_index, + const OperandIndex &bottom_index) +{ + auto left = operands.at(left_index).asScalar(); + auto right = operands.at(right_index).asScalar(); + auto top = operands.at(top_index).asScalar(); + auto bottom = operands.at(bottom_index).asScalar(); + + if (left < 0 || right < 0 || top < 0 || bottom < 0) + { + throw std::runtime_error{"Cannot handle negative explicit padding value"}; + } + + ExplicitPadding param; + param.left = static_cast(left); + param.right = static_cast(right); + param.top = static_cast(top); + param.bottom = static_cast(bottom); + + return param; +} + } // namespace OperationFactory &OperationFactory::instance() @@ -90,13 +114,16 @@ OperationFactory::OperationFactory() // 9 -> Depthwise multiplier // 10-> Activation Index + const auto padding_left_index = OperandIndex{init_param.inputs[3]}; + const auto padding_right_index = OperandIndex{init_param.inputs[4]}; + const auto padding_top_index = OperandIndex{init_param.inputs[5]}; + const auto padding_bottom_index = OperandIndex{init_param.inputs[6]}; const auto activation_index = OperandIndex{init_param.inputs[10]}; param.padding.type = PaddingType::EXPLICIT; - param.padding_left_index = OperandIndex{init_param.inputs[3]}; - param.padding_right_index = OperandIndex{init_param.inputs[4]}; - param.padding_top_index = OperandIndex{init_param.inputs[5]}; - param.padding_bottom_index = OperandIndex{init_param.inputs[6]}; + param.padding.param = + setExplicitPaddingParam(operands, padding_left_index, padding_right_index, + padding_top_index, padding_bottom_index); param.hstride_index = OperandIndex{init_param.inputs[7]}; param.vstride_index = OperandIndex{init_param.inputs[8]}; param.multiplier_index = OperandIndex{init_param.inputs[9]}; -- 2.7.4