[mir] Remove support for Reduce and Pool (#7074)
authorСергей Баранников/AI Tools Lab /SRR/Engineer/삼성전자 <s.barannikov@samsung.com>
Mon, 2 Sep 2019 14:50:30 +0000 (17:50 +0300)
committerAlexander Efimov/AI Tools Lab/./Samsung Electronics <a.efimov@samsung.com>
Mon, 2 Sep 2019 14:50:30 +0000 (17:50 +0300)
- Reduce and Pool operations were replaced by `ReduceMean`, `AvgPool2D` and `MaxPool2D`.
- Make `ReduceOp` a base class for `ReduceMeanOp`.

Signed-off-by: Sergei Barannikov <s.barannikov@samsung.com>
12 files changed:
compiler/mir/CMakeLists.txt
compiler/mir/include/mir/IrDotDumper.h
compiler/mir/include/mir/OpDefs.h
compiler/mir/include/mir/Operations.inc
compiler/mir/include/mir/ir_dot_node_info.h
compiler/mir/include/mir/ops/PoolOp.h [deleted file]
compiler/mir/include/mir/ops/ReduceMeanOp.h
compiler/mir/include/mir/ops/ReduceOp.h
compiler/mir/src/IrDotDumper.cpp
compiler/mir/src/ir_dot_node_info.cpp
compiler/mir/src/ops/PoolOp.cpp [deleted file]
compiler/mir/src/ops/ReduceOp.cpp [moved from compiler/mir/src/ops/ReduceMeanOp.cpp with 97% similarity]

index 7b27ee0..56a8037 100644 (file)
@@ -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
index 17334c3..62d6135 100644 (file)
@@ -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;
index e115ee2..8af91d0 100644 (file)
@@ -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"
index 0967759..e9ccd1a 100644 (file)
@@ -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)
index d8bda1a..8852dd2 100644 (file)
@@ -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<std::string, Shape>;
   using MiscVal = std::pair<std::string, std::string>;
   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 <typename T> 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 (file)
index 2370aa0..0000000
+++ /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 <vector>
-#include <cmath>
-
-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<int32_t> padding_before, std::vector<int32_t> 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<Output *> &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<int32_t> &getPaddingBefore() const { return _padding_before; }
-
-  const std::vector<int32_t> &getPaddingAfter() const { return _padding_after; }
-
-  DataFormat getDataFormat() const { return _data_format; }
-
-private:
-  void inferOutputShapes();
-
-  PoolingType _pooling_type;
-  Shape _window_shape;
-  Shape _strides;
-  std::vector<int32_t> _padding_before;
-  std::vector<int32_t> _padding_after;
-  BorderType _border_type;
-  DataFormat _data_format;
-};
-
-} // namespace ops
-} // namespace mir
-
-#endif //_MIR_OPS_POOL_OP_H_
index fc7ebc1..957bd7e 100644 (file)
@@ -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 <vector>
 
 namespace mir
@@ -25,30 +25,18 @@ namespace mir
 namespace ops
 {
 
-class ReduceMeanOp : public Operation
+class ReduceMeanOp : public ReduceOp
 {
 public:
   ReduceMeanOp(Output *arg, std::vector<int> 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<Output *> &inputs) override
   {
-    return new ReduceMeanOp(inputs[0], _reduction_dims, _keep_dims);
+    return new ReduceMeanOp(inputs[0], getReductionDims(), getKeepDims());
   }
-
-  const std::vector<int> &getReductionDims() const { return _reduction_dims; };
-
-  bool getKeepDims() const { return _keep_dims; };
-
-private:
-  void inferOutputShapes();
-
-  std::vector<int> _reduction_dims;
-  bool _keep_dims;
 };
 
 } // namespace ops
index aa7f956..a9171a1 100644 (file)
@@ -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<int32_t> 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<int> 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<bool> reduce_axis_mask(input_shape.rank(), false);
-      for (auto axis : red_dims)
-        reduce_axis_mask[axis] = true;
-
-      // Actual shape inference
-      std::vector<int32_t> 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<Output *> &inputs) override
-  {
-    return new ReduceOp(inputs[0], _reduce_dims, _keep_dims, _func_type);
+    inferOutputShapes();
   }
 
-  const std::vector<int32_t> &getReductionDims() const { return _reduce_dims; };
+public:
+  const std::vector<int> &getReductionDims() const { return _reduction_dims; };
 
   bool getKeepDims() const { return _keep_dims; };
 
-  FuncType getFuncType() const { return _func_type; };
 private:
-  std::vector<int32_t> _reduce_dims;
+  void inferOutputShapes();
+
+  std::vector<int> _reduction_dims;
   bool _keep_dims;
-  FuncType _func_type;
 };
 
 } // namespace ops
index 404bf92..d4eab84 100644 (file)
@@ -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<ops::ReduceOp::FuncType, const char *> 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 =
index a365c6a..e0968ff 100644 (file)
@@ -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 (file)
index 988fef9..0000000
+++ /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
similarity index 97%
rename from compiler/mir/src/ops/ReduceMeanOp.cpp
rename to compiler/mir/src/ops/ReduceOp.cpp
index 8fe23b3..c03f109 100644 (file)
@@ -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();