From 6fdfcf18d88681cd03e68655d3d2bda4e5a1a57f Mon Sep 17 00:00:00 2001 From: xiongkun Date: Wed, 13 Jul 2022 12:31:19 +0000 Subject: [PATCH 1/6] fix the outputs of net is x,x --- .../fluid/dygraph/dygraph_to_static/partial_program.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/python/paddle/fluid/dygraph/dygraph_to_static/partial_program.py b/python/paddle/fluid/dygraph/dygraph_to_static/partial_program.py index 318585972f0e6..4faa4a098e016 100644 --- a/python/paddle/fluid/dygraph/dygraph_to_static/partial_program.py +++ b/python/paddle/fluid/dygraph/dygraph_to_static/partial_program.py @@ -441,11 +441,18 @@ def _prepare(self, inputs): continue input_vars.append(var) + # mapping from name(string) -> VarBase + out_varbase_map = {} + def create_out(var_id): var = self._outputs[var_id] assert isinstance(var, framework.Variable) var_desc = var.desc varbase = None + + if var_desc.name() in out_varbase_map: + return out_varbase_map[var_desc.name()] + if not framework._in_eager_mode_: var_base = core.VarBase(var_desc.dtype(), var_desc.shape(), var_desc.name(), var_desc.type(), False) @@ -453,6 +460,7 @@ def create_out(var_id): var_base = core.eager.Tensor(var_desc.dtype(), var_desc.shape(), var_desc.name(), var_desc.type(), False) + out_varbase_map[var_desc.name()] = var_base return var_base # Create VarBase to receive output data. From 9b39d75d2fc1fee85c5c37e78ca79eda3f1bf6b1 Mon Sep 17 00:00:00 2001 From: xiongkun Date: Thu, 14 Jul 2022 03:12:10 +0000 Subject: [PATCH 2/6] add unittest for duplicate output --- .../test_duplicate_output.py | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 python/paddle/fluid/tests/unittests/dygraph_to_static/test_duplicate_output.py diff --git a/python/paddle/fluid/tests/unittests/dygraph_to_static/test_duplicate_output.py b/python/paddle/fluid/tests/unittests/dygraph_to_static/test_duplicate_output.py new file mode 100644 index 0000000000000..75daaaa5d4142 --- /dev/null +++ b/python/paddle/fluid/tests/unittests/dygraph_to_static/test_duplicate_output.py @@ -0,0 +1,65 @@ +# Copyright (c) 2019 PaddlePaddle Authors. 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. + +from __future__ import print_function + +import numpy as np +import unittest + +import paddle + +np.random.seed(1) + +if fluid.is_compiled_with_cuda(): + place = fluid.CUDAPlace(0) +else: + place = fluid.CPUPlace() + + +class SimpleNet(paddle.nn.Layer): + + def __init__(self): + super().__init__() + self._linear = paddle.nn.Linear(1, 1) + + def forward(self, x): + """ forward with duplicate outputs. + """ + x = self._linear(x) + return x, x + + +class TestDuplicateOutput(unittest.TestCase): + """ + TestCase for the transformation from control flow `if/else` + dependent on tensor in Dygraph into Static `fluid.layers.cond`. + """ + + def setUp(self): + self.net = paddle.jit.to_static(SimpleNet()) + self.x = paddle.to_tensor([1.0]) + + def _run_static(self): + loss0, loss1 = self.net(self.x) + loss0.backward() + param = self.net.parameters() + self.assertEqual(param[0].grad.numpy(), 1.0) + + def test_ast_to_func(self): + self._run_static() + + +if __name__ == '__main__': + with paddle.fluid.framework._test_eager_guard(): + unittest.main() From c607c8d595e6011be3d03a975a589029070172cd Mon Sep 17 00:00:00 2001 From: xiongkun Date: Thu, 14 Jul 2022 06:38:35 +0000 Subject: [PATCH 3/6] fix --- .../unittests/dygraph_to_static/test_duplicate_output.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/paddle/fluid/tests/unittests/dygraph_to_static/test_duplicate_output.py b/python/paddle/fluid/tests/unittests/dygraph_to_static/test_duplicate_output.py index 75daaaa5d4142..aea7a1910b0b6 100644 --- a/python/paddle/fluid/tests/unittests/dygraph_to_static/test_duplicate_output.py +++ b/python/paddle/fluid/tests/unittests/dygraph_to_static/test_duplicate_output.py @@ -21,10 +21,10 @@ np.random.seed(1) -if fluid.is_compiled_with_cuda(): - place = fluid.CUDAPlace(0) +if paddle.fluid.is_compiled_with_cuda(): + place = paddle.fluid.CUDAPlace(0) else: - place = fluid.CPUPlace() + place = paddle.fluid.CPUPlace() class SimpleNet(paddle.nn.Layer): From f230eda557655a0ace0dad311d347463010d765b Mon Sep 17 00:00:00 2001 From: xiongkun Date: Wed, 20 Jul 2022 13:18:04 +0000 Subject: [PATCH 4/6] fix _infer_program use the original program not the amp program. --- .../dygraph_to_static/partial_program.py | 69 +++++++------------ 1 file changed, 26 insertions(+), 43 deletions(-) diff --git a/python/paddle/fluid/dygraph/dygraph_to_static/partial_program.py b/python/paddle/fluid/dygraph/dygraph_to_static/partial_program.py index 4faa4a098e016..6808a91f94b6b 100644 --- a/python/paddle/fluid/dygraph/dygraph_to_static/partial_program.py +++ b/python/paddle/fluid/dygraph/dygraph_to_static/partial_program.py @@ -239,34 +239,6 @@ def _train_pure_fp16_program(self): self._set_grad_type(self._params, train_pure_fp16_program) return train_pure_fp16_program - @LazyInitialized - def _infer_program_id(self): - return _hash_with_id(self._infer_program, self) - - @LazyInitialized - def _train_program_id(self): - program_id = _hash_with_id(self._train_program, self) - core._set_cached_executor_build_strategy(program_id, - self._build_strategy) - - return program_id - - @LazyInitialized - def _train_amp_program_id(self): - program_id = _hash_with_id(self._train_amp_program, self) - core._set_cached_executor_build_strategy(program_id, - self._build_strategy) - - return program_id - - @LazyInitialized - def _train_pure_fp16_program_id(self): - program_id = _hash_with_id(self._train_pure_fp16_program, self) - core._set_cached_executor_build_strategy(program_id, - self._build_strategy) - - return program_id - def _verify_program(self, main_program): """ Verify that the program parameter is initialized, prune some unused params, @@ -341,7 +313,7 @@ def _get_end_op_index(self): elif _in_pure_fp16_guard(): infer_program = self._infer_pure_fp16_program else: - infer_program = self._infer_program + infer_program = self.infer_program return infer_program.desc.block(0).op_size() def __call__(self, inputs): @@ -380,26 +352,37 @@ def _cast_fp16_if_pure_fp16(self, in_vars): @property def program(self): if self.training: - if _in_amp_guard(): - return self._train_amp_program - elif _in_pure_fp16_guard(): - return self._train_pure_fp16_program - else: - return self._train_program + return self.train_program else: - return self._infer_program + return self.infer_program @property def program_id(self): if self.training: - if _in_amp_guard(): - return self._train_amp_program_id - elif _in_pure_fp16_guard(): - return self._train_pure_fp16_program_id - else: - return self._train_program_id + program_id = _hash_with_id(self.train_program, self) + core._set_cached_executor_build_strategy(program_id, + self._build_strategy) + return program_id + else: + return _hash_with_id(self.infer_program, self) + + @property + def train_program(self): + if _in_amp_guard(): + return self._train_amp_program + elif _in_pure_fp16_guard(): + return self._train_pure_fp16_program else: - return self._infer_program_id + return self._train_program + + @property + def infer_program(self): + if _in_amp_guard(): + return self._infer_amp_program + elif _in_pure_fp16_guard(): + return self._infer_pure_fp16_program + else: + return self._infer_program def _prepare(self, inputs): """ From 1bd8438ef32e477d571ef551aa3056f2f827e520 Mon Sep 17 00:00:00 2001 From: xiongkun Date: Thu, 21 Jul 2022 07:24:48 +0000 Subject: [PATCH 5/6] get _***program_id back and avoid duplicate cache ing --- .../dygraph_to_static/partial_program.py | 53 +++++++++++++++++-- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/python/paddle/fluid/dygraph/dygraph_to_static/partial_program.py b/python/paddle/fluid/dygraph/dygraph_to_static/partial_program.py index 6808a91f94b6b..5cfbd42f6f1c6 100644 --- a/python/paddle/fluid/dygraph/dygraph_to_static/partial_program.py +++ b/python/paddle/fluid/dygraph/dygraph_to_static/partial_program.py @@ -239,6 +239,42 @@ def _train_pure_fp16_program(self): self._set_grad_type(self._params, train_pure_fp16_program) return train_pure_fp16_program + @LazyInitialized + def _infer_program_id(self): + return _hash_with_id(self._infer_program, self) + + @LazyInitialized + def _infer_pure_fp16_program_id(self): + return _hash_with_id(self._infer_pure_fp16_program, self) + + @LazyInitialized + def _infer_amp_program_id(self): + return _hash_with_id(self._infer_amp_program, self) + + @LazyInitialized + def _train_program_id(self): + program_id = _hash_with_id(self._train_program, self) + core._set_cached_executor_build_strategy(program_id, + self._build_strategy) + + return program_id + + @LazyInitialized + def _train_amp_program_id(self): + program_id = _hash_with_id(self._train_amp_program, self) + core._set_cached_executor_build_strategy(program_id, + self._build_strategy) + + return program_id + + @LazyInitialized + def _train_pure_fp16_program_id(self): + program_id = _hash_with_id(self._train_pure_fp16_program, self) + core._set_cached_executor_build_strategy(program_id, + self._build_strategy) + + return program_id + def _verify_program(self, main_program): """ Verify that the program parameter is initialized, prune some unused params, @@ -359,12 +395,19 @@ def program(self): @property def program_id(self): if self.training: - program_id = _hash_with_id(self.train_program, self) - core._set_cached_executor_build_strategy(program_id, - self._build_strategy) - return program_id + if _in_amp_guard(): + return self._train_amp_program_id + elif _in_pure_fp16_guard(): + return self._train_pure_fp16_program_id + else: + return self._train_program_id else: - return _hash_with_id(self.infer_program, self) + if _in_amp_guard(): + return self._infer_amp_program_id + elif _in_pure_fp16_guard(): + return self._infer_pure_fp16_program_id + else: + return self._infer_program_id @property def train_program(self): From 6cfd5a64c9bf50c06d671cb2bf47583d7b251b6e Mon Sep 17 00:00:00 2001 From: xiongkun Date: Thu, 21 Jul 2022 08:00:58 +0000 Subject: [PATCH 6/6] fix --- .../paddle/fluid/dygraph/dygraph_to_static/partial_program.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/paddle/fluid/dygraph/dygraph_to_static/partial_program.py b/python/paddle/fluid/dygraph/dygraph_to_static/partial_program.py index 5cfbd42f6f1c6..da7cdc7f8f525 100644 --- a/python/paddle/fluid/dygraph/dygraph_to_static/partial_program.py +++ b/python/paddle/fluid/dygraph/dygraph_to_static/partial_program.py @@ -242,7 +242,7 @@ def _train_pure_fp16_program(self): @LazyInitialized def _infer_program_id(self): return _hash_with_id(self._infer_program, self) - + @LazyInitialized def _infer_pure_fp16_program_id(self): return _hash_with_id(self._infer_pure_fp16_program, self)