This is a future replacement of `Reduce` operation.
Signed-off-by: Sergei Barannikov <s.barannikov@samsung.com>
src/ops/GatherOp.cpp
src/ops/PadOp.cpp
src/ops/PoolOp.cpp
+ src/ops/ReduceMeanOp.cpp
src/ops/SqueezeOp.cpp
src/ops/SliceOp.cpp
src/ops/TransposeOp.cpp
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;
void visit(ops::ResizeOp &op) override;
#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"
#include "mir/ops/ResizeOp.h"
HANDLE_OP(pad, PadOp)
HANDLE_OP(pool, PoolOp)
HANDLE_OP(reduce, ReduceOp)
+HANDLE_OP(reduceMean, ReduceMeanOp)
HANDLE_OP(ReLU, ReluOp)
HANDLE_OP(reshape, ReshapeOp)
HANDLE_OP(resizeIm, ResizeOp)
--- /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_REDUCE_MEAN_OP_H_
+#define _MIR_OPS_REDUCE_MEAN_OP_H_
+
+#include "mir/Operation.h"
+#include <vector>
+
+namespace mir
+{
+namespace ops
+{
+
+class ReduceMeanOp : public Operation
+{
+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)
+ {
+ inferOutputShapes();
+ }
+
+ Operation *copyWithInputs(const std::vector<Output *> &inputs) override
+ {
+ return new ReduceMeanOp(inputs[0], _reduction_dims, _keep_dims);
+ }
+
+ 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
+} // namespace mir
+
+#endif //_MIR_OPS_REDUCE_MEAN_OP_H_
*/
#include "mir/IrDotDumper.h"
-
#include "mir/OpDefs.h"
#include <map>
_dot_builder.updateWithOp(&op, node_info);
}
+void IrDotDumper::visit(ops::ReduceMeanOp &op)
+{
+ auto node_info =
+ DotIrNodeInfo()
+ .withType("ReduceMeanOp", op.getName())
+ .withInShapes(getInputShapes(op))
+ .withOutShapes(getOutputShapes(op))
+ .withShape("Reduction dims", Shape(op.getReductionDims())) // appropriated shape to dims
+ .withMisc("Keep dims", op.getKeepDims());
+
+ _dot_builder.updateWithOp(&op, node_info);
+}
+
void IrDotDumper::visit(ops::ResizeOp &op)
{
static const std::map<ops::ResizeOp::ResizeMethod, const char *> modes{
--- /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/ReduceMeanOp.h"
+
+namespace mir
+{
+namespace ops
+{
+
+void ReduceMeanOp::inferOutputShapes()
+{
+ const auto &input_shape = getInputShape(0);
+ const auto &reduction_dims = getReductionDims();
+ Shape output_shape;
+
+ if (getKeepDims())
+ {
+ output_shape = input_shape;
+ for (const int dim : reduction_dims)
+ {
+ output_shape.dim(dim) = 1;
+ }
+ }
+ else
+ {
+ // This mask contains 'true' for dimension indices that should be reduced.
+ // for example, if we want to reduce 1 and 3 dimensions with total number of dimensions 4,
+ // the mask will contain: [false, true, false, true].
+ std::vector<bool> reduction_dims_mask(input_shape.rank(), false);
+ for (auto axis : reduction_dims)
+ reduction_dims_mask[axis] = true;
+
+ std::vector<std::int32_t> out_dims;
+ out_dims.reserve(input_shape.rank() - reduction_dims.size());
+ for (int axis_id = 0; axis_id < input_shape.rank(); axis_id++)
+ {
+ if (!reduction_dims_mask[axis_id])
+ out_dims.emplace_back(input_shape.dim(axis_id));
+ }
+ output_shape = Shape(out_dims);
+ }
+
+ setOutputShape(0, output_shape);
+}
+
+} // namespace ops
+} // namespace mir
#include "mir/ops/ReshapeOp.h"
#include "mir/ops/ResizeOp.h"
#include "mir/ops/SqueezeOp.h"
-#include "mir/ops/ReduceOp.h"
+#include "mir/ops/ReduceMeanOp.h"
#include "mir/Shape.h"
#include <vector>
auto input = g.create<ops::InputOp>("input", Shape{10, 2, 10, 9});
- auto n = g.create<ops::ReduceOp>("reduce", input->getOutput(0), std::vector<int32_t>{1, 3}, false,
- ops::ReduceOp::FuncType::mean);
+ auto n =
+ g.create<ops::ReduceMeanOp>("reduce", input->getOutput(0), std::vector<int32_t>{1, 3}, false);
ASSERT_EQ(resultShape, n->getOutputShape(0));
}