From: Сергей Баранников/AI Tools Lab /SRR/Engineer/삼성전자 Date: Mon, 2 Sep 2019 14:50:30 +0000 (+0300) Subject: [mir] Remove support for Reduce and Pool (#7074) X-Git-Tag: accepted/tizen/unified/20190903.052428~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=374a491002c9d1c97b56aef5f3019a79bf25c495;p=platform%2Fcore%2Fml%2Fnnfw.git [mir] Remove support for Reduce and Pool (#7074) - Reduce and Pool operations were replaced by `ReduceMean`, `AvgPool2D` and `MaxPool2D`. - Make `ReduceOp` a base class for `ReduceMeanOp`. Signed-off-by: Sergei Barannikov --- diff --git a/compiler/mir/CMakeLists.txt b/compiler/mir/CMakeLists.txt index 7b27ee0..56a8037 100644 --- a/compiler/mir/CMakeLists.txt +++ b/compiler/mir/CMakeLists.txt @@ -9,8 +9,7 @@ set(MIR_SOURCES src/ops/GatherOp.cpp src/ops/MaxPool2DOp.cpp src/ops/PadOp.cpp - src/ops/PoolOp.cpp - src/ops/ReduceMeanOp.cpp + src/ops/ReduceOp.cpp src/ops/SqueezeOp.cpp src/ops/SliceOp.cpp src/ops/TransposeOp.cpp diff --git a/compiler/mir/include/mir/IrDotDumper.h b/compiler/mir/include/mir/IrDotDumper.h index 17334c3..62d6135 100644 --- a/compiler/mir/include/mir/IrDotDumper.h +++ b/compiler/mir/include/mir/IrDotDumper.h @@ -45,8 +45,6 @@ public: void visit(ops::MaxPool2DOp &op) override; void visit(ops::OutputOp &op) override; void visit(ops::PadOp &op) override; - void visit(ops::PoolOp &op) override; - void visit(ops::ReduceOp &op) override; void visit(ops::ReduceMeanOp &op) override; void visit(ops::ReluOp &op) override; void visit(ops::ReshapeOp &op) override; diff --git a/compiler/mir/include/mir/OpDefs.h b/compiler/mir/include/mir/OpDefs.h index e115ee2..8af91d0 100644 --- a/compiler/mir/include/mir/OpDefs.h +++ b/compiler/mir/include/mir/OpDefs.h @@ -20,7 +20,6 @@ #include "mir/ops/AddOp.h" #include "mir/ops/AvgPool2DOp.h" #include "mir/ops/CappedReluOp.h" -#include "mir/ops/CommonProps.h" #include "mir/ops/ConcatOp.h" #include "mir/ops/ConstantOp.h" #include "mir/ops/Conv2DOp.h" @@ -37,8 +36,6 @@ #include "mir/ops/MulOp.h" #include "mir/ops/OutputOp.h" #include "mir/ops/PadOp.h" -#include "mir/ops/PoolOp.h" -#include "mir/ops/ReduceOp.h" #include "mir/ops/ReduceMeanOp.h" #include "mir/ops/ReluOp.h" #include "mir/ops/ReshapeOp.h" diff --git a/compiler/mir/include/mir/Operations.inc b/compiler/mir/include/mir/Operations.inc index 0967759..e9ccd1a 100644 --- a/compiler/mir/include/mir/Operations.inc +++ b/compiler/mir/include/mir/Operations.inc @@ -37,8 +37,6 @@ HANDLE_OP(maxPool2D, MaxPool2DOp) HANDLE_OP(mul, MulOp) HANDLE_OP(output, OutputOp) HANDLE_OP(pad, PadOp) -HANDLE_OP(pool, PoolOp) -HANDLE_OP(reduce, ReduceOp) HANDLE_OP(reduceMean, ReduceMeanOp) HANDLE_OP(ReLU, ReluOp) HANDLE_OP(reshape, ReshapeOp) diff --git a/compiler/mir/include/mir/ir_dot_node_info.h b/compiler/mir/include/mir/ir_dot_node_info.h index d8bda1a..8852dd2 100644 --- a/compiler/mir/include/mir/ir_dot_node_info.h +++ b/compiler/mir/include/mir/ir_dot_node_info.h @@ -17,9 +17,9 @@ #ifndef _MIR_IR_DOT_NODE_INFO_H_ #define _MIR_IR_DOT_NODE_INFO_H_ +#include "mir/Operation.h" #include "mir/Shape.h" #include "mir/ops/CommonProps.h" -#include "mir/ops/PoolOp.h" namespace mir { @@ -39,7 +39,6 @@ public: using NamedShape = std::pair; using MiscVal = std::pair; using PadType = ops::PaddingType; - using PoolType = ops::PoolOp::PoolingType; class Stringable { @@ -66,7 +65,6 @@ public: DotIrNodeInfo &withStride(const Shape &stride_shape); DotIrNodeInfo &withShape(const std::string &shape_name, const Shape &shape); DotIrNodeInfo &withPadType(PadType pad_type); - DotIrNodeInfo &withPoolType(PoolType pool_type); DotIrNodeInfo &withMisc(const std::string &name, Stringable val); /** @@ -104,7 +102,6 @@ private: PadType _pad_type = PadType::Valid; bool _has_pool = false; - PoolType _pool_type = PoolType::MAX; }; template DotIrNodeInfo::Stringable::Stringable(T val) : _val(std::to_string(val)) {} diff --git a/compiler/mir/include/mir/ops/PoolOp.h b/compiler/mir/include/mir/ops/PoolOp.h deleted file mode 100644 index 2370aa0..0000000 --- a/compiler/mir/include/mir/ops/PoolOp.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2018 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 _MIR_OPS_POOL_OP_H_ -#define _MIR_OPS_POOL_OP_H_ - -#include "mir/Operation.h" -#include "mir/DataFormat.h" -#include "mir/ops/CommonProps.h" -#include -#include - -namespace mir -{ -namespace ops -{ - -class PoolOp : public Operation -{ -public: - enum class PoolingType - { - MAX, - AVG, - MIN - }; - - enum class BorderType - { - ZEROFILLED, // elements outside of input considered zero - EMPTY // Consider that there are no elements outside of input shape - }; - - PoolOp(Output *arg, PoolingType pooling_type, const Shape &window_shape, const Shape &strides, - std::vector padding_before, std::vector padding_after, - BorderType border_type, DataFormat data_format = DataFormat::NHWC) - : Operation(Type::pool, {arg}), _pooling_type(pooling_type), _window_shape(window_shape), - _strides(strides), _padding_before(std::move(padding_before)), - _padding_after(std::move(padding_after)), _border_type(border_type), - _data_format(data_format) - { - inferOutputShapes(); - } - - Operation *copyWithInputs(const std::vector &inputs) override - { - return new PoolOp(inputs[0], _pooling_type, _window_shape, _strides, _padding_before, - _padding_after, _border_type, _data_format); - }; - - BorderType getBorderType() const { return _border_type; } - - PoolingType getPoolingType() const { return _pooling_type; } - - const Shape &getWindowShape() const { return _window_shape; } - - const Shape &getStrides() const { return _strides; } - - const std::vector &getPaddingBefore() const { return _padding_before; } - - const std::vector &getPaddingAfter() const { return _padding_after; } - - DataFormat getDataFormat() const { return _data_format; } - -private: - void inferOutputShapes(); - - PoolingType _pooling_type; - Shape _window_shape; - Shape _strides; - std::vector _padding_before; - std::vector _padding_after; - BorderType _border_type; - DataFormat _data_format; -}; - -} // namespace ops -} // namespace mir - -#endif //_MIR_OPS_POOL_OP_H_ diff --git a/compiler/mir/include/mir/ops/ReduceMeanOp.h b/compiler/mir/include/mir/ops/ReduceMeanOp.h index fc7ebc1..957bd7e 100644 --- a/compiler/mir/include/mir/ops/ReduceMeanOp.h +++ b/compiler/mir/include/mir/ops/ReduceMeanOp.h @@ -17,7 +17,7 @@ #ifndef _MIR_OPS_REDUCE_MEAN_OP_H_ #define _MIR_OPS_REDUCE_MEAN_OP_H_ -#include "mir/Operation.h" +#include "mir/ops/ReduceOp.h" #include namespace mir @@ -25,30 +25,18 @@ namespace mir namespace ops { -class ReduceMeanOp : public Operation +class ReduceMeanOp : public ReduceOp { public: ReduceMeanOp(Output *arg, std::vector reduction_dims, bool keep_dims) - : Operation(Type::reduceMean, {arg}), _reduction_dims(std::move(reduction_dims)), - _keep_dims(keep_dims) + : ReduceOp(Type::reduceMean, arg, std::move(reduction_dims), keep_dims) { - inferOutputShapes(); } Operation *copyWithInputs(const std::vector &inputs) override { - return new ReduceMeanOp(inputs[0], _reduction_dims, _keep_dims); + return new ReduceMeanOp(inputs[0], getReductionDims(), getKeepDims()); } - - const std::vector &getReductionDims() const { return _reduction_dims; }; - - bool getKeepDims() const { return _keep_dims; }; - -private: - void inferOutputShapes(); - - std::vector _reduction_dims; - bool _keep_dims; }; } // namespace ops diff --git a/compiler/mir/include/mir/ops/ReduceOp.h b/compiler/mir/include/mir/ops/ReduceOp.h index aa7f956..a9171a1 100644 --- a/compiler/mir/include/mir/ops/ReduceOp.h +++ b/compiler/mir/include/mir/ops/ReduceOp.h @@ -27,73 +27,23 @@ namespace ops class ReduceOp : public Operation { -public: - enum class FuncType - { - mean, // TODO add other reducers - }; - - /** - * @brief Reduces with (a,b) -> a + b / n where n is the size of dimension(s) being reduced - * @param reduce_dims vector of ints denoting reduction dimensions. assume it is sorted - * @param keep_dims whether to keep the original rank - * @param func_type function to reduce the tensor with (should be associative) - */ - ReduceOp(Output *arg, std::vector reduce_dims, bool keep_dims, FuncType func_type) - : Operation(Type::reduce, {arg}), _reduce_dims(std::move(reduce_dims)), _keep_dims(keep_dims), - _func_type(func_type) +protected: + ReduceOp(Type type, Output *arg, std::vector reduction_dims, bool keep_dims) + : Operation(type, {arg}), _reduction_dims(std::move(reduction_dims)), _keep_dims(keep_dims) { - - // Infer output shapes. - const auto &input_shape = getInputShape(0); - const auto &red_dims = getReductionDims(); - Shape output_shape; - - if (getKeepDims()) - { - output_shape = input_shape; - for (auto red_axis : red_dims) - { - output_shape.dim(red_axis) = 1; - } - } - else - { - // This mask contains true for axis indexes that should be reduced - // for example, if we want to reduce 1 and 3 axes, with total number of dims 4 - // mask will contain: [false, true, false, true] - std::vector reduce_axis_mask(input_shape.rank(), false); - for (auto axis : red_dims) - reduce_axis_mask[axis] = true; - - // Actual shape inference - std::vector out_dims; - out_dims.reserve(input_shape.rank() - red_dims.size()); - for (int32_t axis_id = 0; axis_id < input_shape.rank(); axis_id++) - { - if (!reduce_axis_mask[axis_id]) - out_dims.emplace_back(input_shape.dim(axis_id)); - } - output_shape = Shape(out_dims); - } - - setOutputShape(0, output_shape); - }; - - Operation *copyWithInputs(const std::vector &inputs) override - { - return new ReduceOp(inputs[0], _reduce_dims, _keep_dims, _func_type); + inferOutputShapes(); } - const std::vector &getReductionDims() const { return _reduce_dims; }; +public: + const std::vector &getReductionDims() const { return _reduction_dims; }; bool getKeepDims() const { return _keep_dims; }; - FuncType getFuncType() const { return _func_type; }; private: - std::vector _reduce_dims; + void inferOutputShapes(); + + std::vector _reduction_dims; bool _keep_dims; - FuncType _func_type; }; } // namespace ops diff --git a/compiler/mir/src/IrDotDumper.cpp b/compiler/mir/src/IrDotDumper.cpp index 404bf92..d4eab84 100644 --- a/compiler/mir/src/IrDotDumper.cpp +++ b/compiler/mir/src/IrDotDumper.cpp @@ -139,21 +139,6 @@ void IrDotDumper::visit(ops::SoftmaxOp &op) _dot_builder.updateWithOp(&op, nodeInfo); } -void IrDotDumper::visit(ops::PoolOp &op) -{ - auto nodeInfo = DotIrNodeInfo() - .withType("Pool2D") - .withInShapes(getInputShapes(op)) - .withOutShapes(getOutputShapes(op)) - .withShape("PoolWindow", op.getWindowShape()) - .withPoolType(op.getPoolingType()) - .withStride(op.getStrides()) - .withShape("Padding before", Shape(op.getPaddingBefore())) - .withShape("Padding after", Shape(op.getPaddingAfter())); - - _dot_builder.updateWithOp(&op, nodeInfo); -} - void IrDotDumper::visit(ops::ReluOp &op) { auto nodeInfo = DotIrNodeInfo() @@ -272,23 +257,6 @@ void IrDotDumper::visit(ops::SqrtOp &op) _dot_builder.updateWithOp(&op, node_info); } -void IrDotDumper::visit(ops::ReduceOp &op) -{ - static const std::map types{ - {ops::ReduceOp::FuncType::mean, "mean"}}; - - auto node_info = - DotIrNodeInfo() - .withType("ReduceOp") - .withInShapes(getInputShapes(op)) - .withOutShapes(getOutputShapes(op)) - .withShape("Reduction dims", Shape(op.getReductionDims())) // appropriated shape to dims - .withMisc("Keep Dims", op.getKeepDims()) - .withMisc("OPType", types.at(op.getFuncType())); - - _dot_builder.updateWithOp(&op, node_info); -} - void IrDotDumper::visit(ops::ReduceMeanOp &op) { auto node_info = diff --git a/compiler/mir/src/ir_dot_node_info.cpp b/compiler/mir/src/ir_dot_node_info.cpp index a365c6a..e0968ff 100644 --- a/compiler/mir/src/ir_dot_node_info.cpp +++ b/compiler/mir/src/ir_dot_node_info.cpp @@ -73,13 +73,6 @@ DotIrNodeInfo &DotIrNodeInfo::withPadType(DotIrNodeInfo::PadType pad_type) return *this; } -DotIrNodeInfo &DotIrNodeInfo::withPoolType(DotIrNodeInfo::PoolType pool_type) -{ - this->_pool_type = pool_type; - this->_has_pool = true; - return *this; -} - std::string DotIrNodeInfo::getLabel() const { std::stringstream ss; @@ -125,33 +118,7 @@ std::string DotIrNodeInfo::labelForPadAndPool() const assert(false && "Unknown Padding type"); break; } - if (_has_pool) - ss << " | "; - else - ss << "}"; - } - if (_has_pool) - { - if (!_has_pad) - ss << "{"; - - std::string pool_type_str; - switch (_pool_type) - { - case PoolType::MAX: - pool_type_str = "MAX"; - break; - case PoolType::AVG: - pool_type_str = "AVG"; - break; - case PoolType::MIN: - pool_type_str = "MIN"; - break; - default: - assert(false && "Unknown PoolType"); - } - ss << "PoolType: " << pool_type_str; ss << "}"; } diff --git a/compiler/mir/src/ops/PoolOp.cpp b/compiler/mir/src/ops/PoolOp.cpp deleted file mode 100644 index 988fef9..0000000 --- a/compiler/mir/src/ops/PoolOp.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2018 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 "mir/ops/PoolOp.h" - -namespace mir -{ -namespace ops -{ - -void PoolOp::inferOutputShapes() -{ - const auto &input_shape = getInputShape(0); - const int batch_dim_index = getDataBatchDimIndex(_data_format); - const int channel_dim_index = getDataChannelDimIndex(_data_format); - - assert(input_shape.rank() == 4); - assert(_window_shape.rank() == 2); - assert(_strides.rank() == 2); - assert(_padding_before.size() == 2); - assert(_padding_after.size() == 2); - - Shape output_shape(4); - - output_shape.dim(batch_dim_index) = input_shape.dim(batch_dim_index); - output_shape.dim(channel_dim_index) = input_shape.dim(channel_dim_index); - - for (int i = 0; i < 2; i++) - { - const int spatial_dim_index = getDataSpatialDimIndex(_data_format, i); - const int32_t padded_input = - input_shape.dim(spatial_dim_index) + _padding_before.at(i) + _padding_after.at(i); - // out_size = ceil((in_size - window_size + 1) / stride) = - // (in_size - window_size + 1 + stride - 1) / stride = - // (in_size - window_size) / stride + 1 - output_shape.dim(spatial_dim_index) = - (padded_input - _window_shape.dim(i)) / _strides.dim(i) + 1; - } - - setOutputShape(0, output_shape); -} - -} // namespace ops -} // namespace mir diff --git a/compiler/mir/src/ops/ReduceMeanOp.cpp b/compiler/mir/src/ops/ReduceOp.cpp similarity index 97% rename from compiler/mir/src/ops/ReduceMeanOp.cpp rename to compiler/mir/src/ops/ReduceOp.cpp index 8fe23b3..c03f109 100644 --- a/compiler/mir/src/ops/ReduceMeanOp.cpp +++ b/compiler/mir/src/ops/ReduceOp.cpp @@ -21,7 +21,7 @@ namespace mir namespace ops { -void ReduceMeanOp::inferOutputShapes() +void ReduceOp::inferOutputShapes() { const auto &input_shape = getInputShape(0); const auto &reduction_dims = getReductionDims();