These are the future replacement of the `Pool` operation.
Signed-off-by: Sergei Barannikov <s.barannikov@samsung.com>
set(MIR_SOURCES
+ src/ops/AvgPool2DOp.cpp
src/ops/BinaryElementwiseOp.cpp
src/ops/ConcatOp.cpp
src/ops/Conv2DOp.cpp
src/ops/DepthwiseConv2DOp.cpp
src/ops/FullyConnectedOp.cpp
src/ops/GatherOp.cpp
+ src/ops/MaxPool2DOp.cpp
src/ops/PadOp.cpp
src/ops/PoolOp.cpp
src/ops/ReduceMeanOp.cpp
class IrDotDumper : public IVisitor
{
public:
+ void visit(ops::AvgPool2DOp &op) override;
void visit(ops::CappedReluOp &op) override;
void visit(ops::ConcatOp &op) override;
void visit(ops::ConstantOp &op) override;
void visit(ops::GatherOp &op) override;
void visit(ops::InputOp &op) override;
void visit(ops::LeakyReluOp &op) override;
+ void visit(ops::MaxPool2DOp &op) override;
void visit(ops::OutputOp &op) override;
void visit(ops::PadOp &op) override;
void visit(ops::PoolOp &op) override;
#define _MIR_OPDEFS_H_
#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/InputOp.h"
#include "mir/ops/LeakyReluOp.h"
#include "mir/ops/MaxOp.h"
+#include "mir/ops/MaxPool2DOp.h"
#include "mir/ops/MulOp.h"
#include "mir/ops/OutputOp.h"
#include "mir/ops/PadOp.h"
#endif // HANDLE_OP
HANDLE_OP(add, AddOp)
+HANDLE_OP(avgPool2D, AvgPool2DOp)
HANDLE_OP(cappedReLU, CappedReluOp)
HANDLE_OP(concat, ConcatOp)
HANDLE_OP(constant, ConstantOp)
HANDLE_OP(input, InputOp)
HANDLE_OP(leakyReLU, LeakyReluOp)
HANDLE_OP(max, MaxOp)
+HANDLE_OP(maxPool2D, MaxPool2DOp)
HANDLE_OP(mul, MulOp)
HANDLE_OP(output, OutputOp)
HANDLE_OP(pad, PadOp)
--- /dev/null
+/*
+ * 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 _MIR_OPS_AVG_POOL_OP_H_
+#define _MIR_OPS_AVG_POOL_OP_H_
+
+#include "mir/Operation.h"
+#include "mir/DataFormat.h"
+
+#include <cstdint>
+#include <vector>
+
+namespace mir
+{
+namespace ops
+{
+
+class AvgPool2DOp : public Operation
+{
+public:
+ AvgPool2DOp(Output *arg, std::vector<std::int32_t> window_size, std::vector<std::int32_t> strides,
+ std::vector<std::int32_t> padding_before, std::vector<std::int32_t> padding_after,
+ bool include_pad, DataFormat data_format)
+ : Operation(Type::avgPool2D, {arg}), _window_size(std::move(window_size)),
+ _strides(std::move(strides)), _padding_before(std::move(padding_before)),
+ _padding_after(std::move(padding_after)), _include_pad(include_pad),
+ _data_format(data_format)
+ {
+ inferOutputShapes();
+ }
+
+ Operation *copyWithInputs(const std::vector<Output *> &inputs) override
+ {
+ return new AvgPool2DOp(inputs[0], _window_size, _strides, _padding_before, _padding_after,
+ _include_pad, _data_format);
+ };
+
+ const std::vector<std::int32_t> &getWindowSize() const { return _window_size; }
+
+ const std::vector<std::int32_t> &getStrides() const { return _strides; }
+
+ const std::vector<std::int32_t> &getPaddingBefore() const { return _padding_before; }
+
+ const std::vector<std::int32_t> &getPaddingAfter() const { return _padding_after; }
+
+ bool getIncludePad() const { return _include_pad; }
+
+ DataFormat getDataFormat() const { return _data_format; }
+
+private:
+ void inferOutputShapes();
+
+ std::vector<std::int32_t> _window_size;
+ std::vector<std::int32_t> _strides;
+ std::vector<std::int32_t> _padding_before;
+ std::vector<std::int32_t> _padding_after;
+ bool _include_pad;
+ DataFormat _data_format;
+};
+
+} // namespace ops
+} // namespace mir
+
+#endif //_MIR_OPS_AVG_POOL_OP_H_
--- /dev/null
+/*
+ * 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 _MIR_OPS_MAX_POOL_OP_H_
+#define _MIR_OPS_MAX_POOL_OP_H_
+
+#include "mir/Operation.h"
+#include "mir/DataFormat.h"
+
+#include <cstdint>
+#include <vector>
+
+namespace mir
+{
+namespace ops
+{
+
+class MaxPool2DOp : public Operation
+{
+public:
+ MaxPool2DOp(Output *arg, std::vector<std::int32_t> window_size, std::vector<std::int32_t> strides,
+ std::vector<std::int32_t> padding_before, std::vector<std::int32_t> padding_after,
+ DataFormat data_format)
+ : Operation(Type::maxPool2D, {arg}), _window_size(std::move(window_size)),
+ _strides(std::move(strides)), _padding_before(std::move(padding_before)),
+ _padding_after(std::move(padding_after)), _data_format(data_format)
+ {
+ inferOutputShapes();
+ }
+
+ Operation *copyWithInputs(const std::vector<Output *> &inputs) override
+ {
+ return new MaxPool2DOp(inputs[0], _window_size, _strides, _padding_before, _padding_after,
+ _data_format);
+ };
+
+ const std::vector<std::int32_t> &getWindowSize() const { return _window_size; }
+
+ const std::vector<std::int32_t> &getStrides() const { return _strides; }
+
+ const std::vector<std::int32_t> &getPaddingBefore() const { return _padding_before; }
+
+ const std::vector<std::int32_t> &getPaddingAfter() const { return _padding_after; }
+
+ DataFormat getDataFormat() const { return _data_format; }
+
+private:
+ void inferOutputShapes();
+
+ std::vector<std::int32_t> _window_size;
+ std::vector<std::int32_t> _strides;
+ std::vector<std::int32_t> _padding_before;
+ std::vector<std::int32_t> _padding_after;
+ DataFormat _data_format;
+};
+
+} // namespace ops
+} // namespace mir
+
+#endif //_MIR_OPS_MAX_POOL_OP_H_
return shapes;
}
+void IrDotDumper::visit(ops::AvgPool2DOp &op)
+{
+ auto nodeInfo = DotIrNodeInfo()
+ .withType("AvgPool2D", op.getName())
+ .withInShapes(getInputShapes(op))
+ .withOutShapes(getOutputShapes(op))
+ .withShape("Window size", Shape(op.getWindowSize()))
+ .withStride(Shape(op.getStrides()))
+ .withShape("Padding before", Shape(op.getPaddingBefore()))
+ .withShape("Padding after", Shape(op.getPaddingAfter()));
+
+ _dot_builder.updateWithOp(&op, nodeInfo);
+}
+
void IrDotDumper::visit(ops::CappedReluOp &op)
{
auto nodeInfo = DotIrNodeInfo()
_dot_builder.updateWithOp(&op, nodeInfo);
}
+void IrDotDumper::visit(ops::MaxPool2DOp &op)
+{
+ auto nodeInfo = DotIrNodeInfo()
+ .withType("MaxPool2D", op.getName())
+ .withInShapes(getInputShapes(op))
+ .withOutShapes(getOutputShapes(op))
+ .withShape("Window size", Shape(op.getWindowSize()))
+ .withStride(Shape(op.getStrides()))
+ .withShape("Padding before", Shape(op.getPaddingBefore()))
+ .withShape("Padding after", Shape(op.getPaddingAfter()));
+
+ _dot_builder.updateWithOp(&op, nodeInfo);
+}
+
void IrDotDumper::visit(ops::SoftmaxOp &op)
{
auto nodeInfo = DotIrNodeInfo()
--- /dev/null
+/*
+ * 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 "mir/ops/AvgPool2DOp.h"
+
+namespace mir
+{
+namespace ops
+{
+
+void AvgPool2DOp::inferOutputShapes()
+{
+ const auto &input_shape = getInputShape(0);
+ const int batch_dim_index = getDataBatchDimIndex(_data_format);
+ const int channel_dim_index = getDataChannelDimIndex(_data_format);
+
+ constexpr int num_spatial_dims = 2;
+
+ assert(input_shape.rank() == 4);
+ assert(_window_size.size() == num_spatial_dims);
+ assert(_strides.size() == num_spatial_dims);
+ assert(_padding_before.size() == num_spatial_dims);
+ assert(_padding_after.size() == num_spatial_dims);
+
+ 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 < num_spatial_dims; i++)
+ {
+ const int spatial_dim_index = getDataSpatialDimIndex(_data_format, i);
+ const std::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_size[i]) / _strides[i] + 1;
+ }
+
+ setOutputShape(0, output_shape);
+}
+
+} // namespace ops
+} // namespace mir
--- /dev/null
+/*
+ * 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 "mir/ops/MaxPool2DOp.h"
+
+namespace mir
+{
+namespace ops
+{
+
+void MaxPool2DOp::inferOutputShapes()
+{
+ const auto &input_shape = getInputShape(0);
+ const int batch_dim_index = getDataBatchDimIndex(_data_format);
+ const int channel_dim_index = getDataChannelDimIndex(_data_format);
+
+ constexpr int num_spatial_dims = 2;
+
+ assert(input_shape.rank() == 4);
+ assert(_window_size.size() == num_spatial_dims);
+ assert(_strides.size() == num_spatial_dims);
+ assert(_padding_before.size() == num_spatial_dims);
+ assert(_padding_after.size() == num_spatial_dims);
+
+ 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 < num_spatial_dims; i++)
+ {
+ const int spatial_dim_index = getDataSpatialDimIndex(_data_format, i);
+ const std::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_size[i]) / _strides[i] + 1;
+ }
+
+ setOutputShape(0, output_shape);
+}
+
+} // namespace ops
+} // namespace mir