From e9a0c4ef87134d061ba952bb89c0dfe01eedc37e Mon Sep 17 00:00:00 2001 From: qiaolongfei Date: Tue, 10 Oct 2017 19:57:30 -0700 Subject: [PATCH 1/3] expose AppendBackward of ProgramDesc to python --- paddle/framework/backward.h | 2 ++ paddle/pybind/protobuf.cc | 6 ++++++ .../paddle/v2/framework/tests/test_program.py | 17 +++++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/paddle/framework/backward.h b/paddle/framework/backward.h index 7ffe4c28103f9..24a79d28b3858 100644 --- a/paddle/framework/backward.h +++ b/paddle/framework/backward.h @@ -27,6 +27,8 @@ extern std::unique_ptr Backward( const OperatorBase& forwardOp, const std::unordered_set& no_grad_vars); +// TODO(someone): Add target as parameter and generate backward op +// according to target. void AppendBackward(ProgramDescBind& program_desc, const std::unordered_set& no_grad_vars); diff --git a/paddle/pybind/protobuf.cc b/paddle/pybind/protobuf.cc index 116c99bd2c1ca..807694fc08fe6 100644 --- a/paddle/pybind/protobuf.cc +++ b/paddle/pybind/protobuf.cc @@ -15,6 +15,7 @@ limitations under the License. */ #include "paddle/pybind/protobuf.h" #include #include +#include "paddle/framework/backward.h" #include "paddle/framework/block_desc.h" #include "paddle/framework/op_desc.h" #include "paddle/framework/program_desc.h" @@ -116,6 +117,11 @@ void BindProgramDesc(py::module &m) { py::return_value_policy::reference) .def("append_block", &ProgramDescBind::AppendBlock, py::return_value_policy::reference) + .def("backward", + [](ProgramDescBind &program_desc, + const std::unordered_set &no_grad_vars) { + AppendBackward(program_desc, no_grad_vars); + }) .def("block", &ProgramDescBind::Block, py::return_value_policy::reference) .def("num_blocks", &ProgramDescBind::Size); } diff --git a/python/paddle/v2/framework/tests/test_program.py b/python/paddle/v2/framework/tests/test_program.py index b82d1760d65a2..6eae378c91eb1 100644 --- a/python/paddle/v2/framework/tests/test_program.py +++ b/python/paddle/v2/framework/tests/test_program.py @@ -1,4 +1,6 @@ import unittest + +import paddle.v2.framework.core as core from paddle.v2.framework.graph import g_program @@ -31,6 +33,21 @@ def test_program(self): self.assertEqual(1, b.idx) self.assertEqual(0, b.parent_idx) + def test_backward(self): + prog = core.ProgramDesc.__create_program_desc__() + self.assertIsNotNone(prog) + block = prog.block(0) + self.assertIsNotNone(block) + + sum_op_desc = block.append_op() + sum_op_desc.set_type("sum") + sum_op_desc.set_input("X", ["x1", "x2"]) + sum_op_desc.set_output("Out", ["out"]) + + self.assertEqual(len(block.all_ops()), 1) + prog.backward(set()) + self.assertEqual(len(block.all_ops()), 3) + if __name__ == '__main__': unittest.main() From 2e554693cc65ee406da46ab711d80656da31886d Mon Sep 17 00:00:00 2001 From: qiaolongfei Date: Tue, 10 Oct 2017 20:11:50 -0700 Subject: [PATCH 2/3] assgin todo to a certain person --- paddle/framework/backward.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paddle/framework/backward.h b/paddle/framework/backward.h index 24a79d28b3858..f1ab8056450c9 100644 --- a/paddle/framework/backward.h +++ b/paddle/framework/backward.h @@ -27,7 +27,7 @@ extern std::unique_ptr Backward( const OperatorBase& forwardOp, const std::unordered_set& no_grad_vars); -// TODO(someone): Add target as parameter and generate backward op +// TODO(jiayi): Add target as parameter and generate backward op // according to target. void AppendBackward(ProgramDescBind& program_desc, const std::unordered_set& no_grad_vars); From e8cad5a1d00967fb83ff9632672e0650a5f67af8 Mon Sep 17 00:00:00 2001 From: qiaolongfei Date: Tue, 10 Oct 2017 22:46:16 -0700 Subject: [PATCH 3/3] add more unit test for test_append_backward --- paddle/pybind/protobuf.cc | 2 +- .../paddle/v2/framework/tests/test_program.py | 27 ++++++++++++++----- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/paddle/pybind/protobuf.cc b/paddle/pybind/protobuf.cc index 807694fc08fe6..0e73939424633 100644 --- a/paddle/pybind/protobuf.cc +++ b/paddle/pybind/protobuf.cc @@ -117,7 +117,7 @@ void BindProgramDesc(py::module &m) { py::return_value_policy::reference) .def("append_block", &ProgramDescBind::AppendBlock, py::return_value_policy::reference) - .def("backward", + .def("append_backward", [](ProgramDescBind &program_desc, const std::unordered_set &no_grad_vars) { AppendBackward(program_desc, no_grad_vars); diff --git a/python/paddle/v2/framework/tests/test_program.py b/python/paddle/v2/framework/tests/test_program.py index 6eae378c91eb1..83e184494ad23 100644 --- a/python/paddle/v2/framework/tests/test_program.py +++ b/python/paddle/v2/framework/tests/test_program.py @@ -33,20 +33,33 @@ def test_program(self): self.assertEqual(1, b.idx) self.assertEqual(0, b.parent_idx) - def test_backward(self): + def test_append_backward(self): prog = core.ProgramDesc.__create_program_desc__() self.assertIsNotNone(prog) block = prog.block(0) self.assertIsNotNone(block) + mul_op_desc = block.append_op() + mul_op_desc.set_type("mul") + mul_op_desc.set_input("X", ["x1"]) + mul_op_desc.set_input("Y", ["y1"]) + mul_op_desc.set_output("Out", ["out1"]) + sum_op_desc = block.append_op() - sum_op_desc.set_type("sum") - sum_op_desc.set_input("X", ["x1", "x2"]) - sum_op_desc.set_output("Out", ["out"]) + sum_op_desc.set_type("elementwise_add") + sum_op_desc.set_input("X", ["out1"]) + sum_op_desc.set_input("Y", ["b1"]) + sum_op_desc.set_output("Out", ["out2"]) - self.assertEqual(len(block.all_ops()), 1) - prog.backward(set()) - self.assertEqual(len(block.all_ops()), 3) + expect_ops = [ + "mul", "elementwise_add", "elementwise_add_grad", "mul_grad" + ] + actual_ops = [] + prog.append_backward(set()) + for op in block.all_ops(): + actual_ops.append(op.type()) + print(actual_ops) + self.assertEqual(actual_ops, expect_ops) if __name__ == '__main__':