Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions paddle/operators/reduce_op.cc
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,16 @@ The result tensor has 1 fewer dimension than the input unless keep_dim is true.
}
};

class ReduceProdOpMaker : public ReduceOpMaker {
public:
ReduceProdOpMaker(framework::OpProto *proto,
framework::OpAttrChecker *op_checker)
: ReduceOpMaker(proto, op_checker) {
SetComment("ReduceProd", "prod");
AddComment(comment_);
}
};

class ReduceSumOpMaker : public ReduceOpMaker {
public:
ReduceSumOpMaker(framework::OpProto *proto,
Expand Down Expand Up @@ -167,6 +177,8 @@ class ReduceMinOpMaker : public ReduceOpMaker {
} // namespace paddle

namespace ops = paddle::operators;
REGISTER_OP(reduce_prod, ops::ReduceOp, ops::ReduceProdOpMaker,
reduce_prod_grad, ops::ReduceGradOp);

REGISTER_OP(reduce_sum, ops::ReduceOp, ops::ReduceSumOpMaker, reduce_sum_grad,
ops::ReduceGradOp);
Expand Down
17 changes: 17 additions & 0 deletions paddle/operators/reduce_op.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ template <typename T, int MajorType = Eigen::RowMajor,
typename IndexType = Eigen::DenseIndex>
using EigenScalar = framework::EigenScalar<T, MajorType, IndexType>;

struct ProdFunctor {
template <typename Place, typename X, typename Y, typename Dim>
void operator()(const Place& place, X& x, Y& y, const Dim& dim) {
y.device(place) = x.prod(dim);
}
};

struct ProdGradFunctor {
template <typename Place, typename X, typename Y, typename DX, typename DY,
typename Dim>
void operator()(const Place& place, X& x, Y& y, DX& dx, DY& dy,
const Dim& dim, int size) {
dx.device(place) = dy.broadcast(dim) * dx;
}
};

struct SumFunctor {
template <typename Place, typename X, typename Y, typename Dim>
void operator()(const Place& place, X& x, Y& y, const Dim& dim) {
Expand Down Expand Up @@ -213,6 +229,7 @@ class ReduceGradKernel : public framework::OpKernel<T> {

#define FOR_EACH_KERNEL_FUNCTOR(__macro) \
__macro(reduce_sum, SumFunctor, SumGradFunctor); \
__macro(reduce_prod, ProdFunctor, ProdGradFunctor); \
__macro(reduce_mean, MeanFunctor, MeanGradFunctor); \
__macro(reduce_max, MaxFunctor, MaxOrMinGradFunctor); \
__macro(reduce_min, MinFunctor, MaxOrMinGradFunctor);
13 changes: 13 additions & 0 deletions python/paddle/v2/fluid/tests/test_reduce_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@
from op_test import OpTest


class TestProdOp(OpTest):
def setUp(self):
self.op_type = "reduce_prod"
self.inputs = {'X': np.random.random((5, 6, 10)).astype("float32")}
self.outputs = {'Out': self.inputs['X'].prod(axis=0)}

def test_check_output(self):
self.check_output()

def test_check_grad(self):
self.check_grad(['X'], 'Out')


class TestSumOp(OpTest):
def setUp(self):
self.op_type = "reduce_sum"
Expand Down