From da61df5c6f698a9f90dad3b1ce2e44e19670b306 Mon Sep 17 00:00:00 2001 From: zyfncg Date: Tue, 21 Dec 2021 21:07:59 +0800 Subject: [PATCH] Fix inplace problem of setitem (#38298) * add inplace_map for trace_op in pybind * fix inplace problem of setitem * refactor the param format of trace_op Co-authored-by: pangyoki --- paddle/fluid/pybind/imperative.cc | 30 ++++++++++++------- python/paddle/fluid/dygraph/tracer.py | 10 +++++-- python/paddle/fluid/framework.py | 4 ++- .../tests/unittests/test_set_value_op.py | 18 +++++++++++ python/paddle/fluid/variable_index.py | 9 +++++- 5 files changed, 57 insertions(+), 14 deletions(-) diff --git a/paddle/fluid/pybind/imperative.cc b/paddle/fluid/pybind/imperative.cc index 1d73ecbab5e..a99f6761ee3 100644 --- a/paddle/fluid/pybind/imperative.cc +++ b/paddle/fluid/pybind/imperative.cc @@ -2189,65 +2189,75 @@ void BindImperative(py::module *m_ptr) { [](imperative::Tracer &self, const std::string &type, const PyNameVarBaseMap &ins, const PyNameVarBaseMap &outs, framework::AttributeMap attrs, const platform::XPUPlace &place, - bool trace_backward) { + bool trace_backward, + const std::map &inplace_map = {}) { auto ins_map = ConvertToNameVarBaseMap(ins); auto outs_map = ConvertToNameVarBaseMap(outs); { py::gil_scoped_release release; self.TraceOp(type, std::move(ins_map), std::move(outs_map), - std::move(attrs), place, trace_backward); + std::move(attrs), place, trace_backward, + inplace_map); } }) .def("trace", [](imperative::Tracer &self, const std::string &type, const PyNameVarBaseMap &ins, const PyNameVarBaseMap &outs, framework::AttributeMap attrs, const platform::CUDAPlace &place, - bool trace_backward) { + bool trace_backward, + const std::map &inplace_map = {}) { auto ins_map = ConvertToNameVarBaseMap(ins); auto outs_map = ConvertToNameVarBaseMap(outs); { py::gil_scoped_release release; self.TraceOp(type, std::move(ins_map), std::move(outs_map), - std::move(attrs), place, trace_backward); + std::move(attrs), place, trace_backward, + inplace_map); } }) .def("trace", [](imperative::Tracer &self, const std::string &type, const PyNameVarBaseMap &ins, const PyNameVarBaseMap &outs, framework::AttributeMap attrs, const platform::NPUPlace &place, - bool trace_backward) { + bool trace_backward, + const std::map &inplace_map = {}) { auto ins_map = ConvertToNameVarBaseMap(ins); auto outs_map = ConvertToNameVarBaseMap(outs); { py::gil_scoped_release release; self.TraceOp(type, std::move(ins_map), std::move(outs_map), - std::move(attrs), place, trace_backward); + std::move(attrs), place, trace_backward, + inplace_map); } }) .def("trace", [](imperative::Tracer &self, const std::string &type, const PyNameVarBaseMap &ins, const PyNameVarBaseMap &outs, framework::AttributeMap attrs, const platform::MLUPlace &place, - bool trace_backward) { + bool trace_backward, + const std::map &inplace_map = {}) { auto ins_map = ConvertToNameVarBaseMap(ins); auto outs_map = ConvertToNameVarBaseMap(outs); { py::gil_scoped_release release; self.TraceOp(type, std::move(ins_map), std::move(outs_map), - std::move(attrs), place, trace_backward); + std::move(attrs), place, trace_backward, + inplace_map); } }) .def("trace", [](imperative::Tracer &self, const std::string &type, const PyNameVarBaseMap &ins, const PyNameVarBaseMap &outs, framework::AttributeMap attrs, const platform::CPUPlace &place, - bool trace_backward) { + bool trace_backward, + const std::map &inplace_map = {}) { auto ins_map = ConvertToNameVarBaseMap(ins); auto outs_map = ConvertToNameVarBaseMap(outs); { py::gil_scoped_release release; self.TraceOp(type, std::move(ins_map), std::move(outs_map), - std::move(attrs), place, trace_backward); + std::move(attrs), place, trace_backward, + inplace_map); } }); diff --git a/python/paddle/fluid/dygraph/tracer.py b/python/paddle/fluid/dygraph/tracer.py index 2047968085b..2ecb0998dd3 100644 --- a/python/paddle/fluid/dygraph/tracer.py +++ b/python/paddle/fluid/dygraph/tracer.py @@ -39,10 +39,16 @@ class Tracer(core.Tracer): self._train_mode = True - def trace_op(self, type, inputs, outputs, attrs, stop_gradient=False): + def trace_op(self, + type, + inputs, + outputs, + attrs, + stop_gradient=False, + inplace_map=None): self.trace(type, inputs, outputs, attrs, framework._current_expected_place(), self._has_grad and - not stop_gradient) + not stop_gradient, inplace_map if inplace_map else {}) def train_mode(self): self._train_mode = True diff --git a/python/paddle/fluid/framework.py b/python/paddle/fluid/framework.py index 76ef638c3ea..fe041ded8ec 100644 --- a/python/paddle/fluid/framework.py +++ b/python/paddle/fluid/framework.py @@ -3262,6 +3262,7 @@ class Block(object): """ if in_dygraph_mode(): attrs = kwargs.get("attrs", {}) + inplace_map = kwargs.get("inplace_map", None) type = kwargs.get("type", None) op = Operator( block=self, @@ -3280,7 +3281,8 @@ class Block(object): kwargs.get("inputs", {}), kwargs.get("outputs", {}), attrs if attrs else {}, - kwargs.get("stop_gradient", False)) + kwargs.get("stop_gradient", False), + inplace_map) else: from paddle.fluid.dygraph.base import param_guard diff --git a/python/paddle/fluid/tests/unittests/test_set_value_op.py b/python/paddle/fluid/tests/unittests/test_set_value_op.py index f4636ab3d11..42225468bc4 100644 --- a/python/paddle/fluid/tests/unittests/test_set_value_op.py +++ b/python/paddle/fluid/tests/unittests/test_set_value_op.py @@ -1330,6 +1330,24 @@ class TestGradientTruncated(unittest.TestCase): array = array[0] +class TestSetValueInplace(unittest.TestCase): + def test_inplace(self): + paddle.disable_static() + with paddle.fluid.dygraph.guard(): + paddle.seed(100) + a = paddle.rand(shape=[1, 4]) + a.stop_gradient = False + b = a[:] + c = b + b[paddle.to_tensor(0)] = 1.0 + + self.assertTrue(id(b) == id(c)) + self.assertTrue(np.array_equal(b.numpy(), c.numpy())) + self.assertEqual(b.inplace_version, 1) + + paddle.enable_static() + + class TestSetValueInplaceLeafVar(unittest.TestCase): def test_inplace_var_become_leaf_var(self): paddle.disable_static() diff --git a/python/paddle/fluid/variable_index.py b/python/paddle/fluid/variable_index.py index 5aa7f9c972f..f3763cb447f 100644 --- a/python/paddle/fluid/variable_index.py +++ b/python/paddle/fluid/variable_index.py @@ -665,9 +665,16 @@ def _setitem_impl_(var, item, value): "paddle.Tensor to a paddle.Tensor, but received {}".format( type(value))) + if paddle.fluid.framework.in_dygraph_mode(): + var._bump_inplace_version() + cur_block = default_main_program().current_block() cur_block.append_op( - type="set_value", inputs=inputs, outputs={'Out': var}, attrs=attrs) + type="set_value", + inputs=inputs, + outputs={'Out': var}, + attrs=attrs, + inplace_map={"Input": "Out"}) return var -- GitLab