From 04f23b7105eddb838fa223a7d00572e200473aa7 Mon Sep 17 00:00:00 2001 From: wuzhanfei Date: Mon, 5 Dec 2022 10:47:05 +0000 Subject: [PATCH 01/16] assert increment --- .../fleet/utils/hybrid_parallel_inference.py | 4 +- python/paddle/fluid/layers/control_flow.py | 119 +----------------- python/paddle/fluid/layers/rnn.py | 2 +- python/paddle/fluid/optimizer.py | 8 +- .../auto_parallel/test_while_op_partition.py | 4 +- .../fleet/hybrid_parallel_inference_helper.py | 4 +- .../fluid/tests/unittests/dist_transformer.py | 5 +- .../unittests/dygraph_to_static/test_loop.py | 9 +- .../unittests/npu/test_increment_op_npu.py | 2 +- .../tests/unittests/npu/test_while_op_npu.py | 9 +- .../unittests/test_array_read_write_op.py | 9 +- .../fluid/tests/unittests/test_assert_op.py | 13 +- .../test_async_ssa_graph_executor_mnist.py | 2 +- .../test_dynamic_rnn_stop_gradient.py | 4 +- .../unittests/test_eager_deletion_while_op.py | 9 +- .../tests/unittests/test_executor_and_mul.py | 7 +- .../unittests/test_fetch_lod_tensor_array.py | 5 +- .../fluid/tests/unittests/test_profiler.py | 4 +- .../tests/unittests/test_while_loop_op.py | 31 ++--- .../fluid/tests/unittests/test_while_op.py | 11 +- .../tests/unittests/xpu/test_while_op_xpu.py | 9 +- .../paddle/jit/dy2static/convert_operators.py | 4 +- 22 files changed, 91 insertions(+), 183 deletions(-) diff --git a/python/paddle/distributed/fleet/utils/hybrid_parallel_inference.py b/python/paddle/distributed/fleet/utils/hybrid_parallel_inference.py index 49aed0862f697..13688589383e1 100644 --- a/python/paddle/distributed/fleet/utils/hybrid_parallel_inference.py +++ b/python/paddle/distributed/fleet/utils/hybrid_parallel_inference.py @@ -62,7 +62,7 @@ class HybridParallelInferenceHelper: element_in_arr = layers.array_read(array=arr, i=step_idx) # write placehold data to global lod_tensor_array, # it need for send_v2 of lod_tensor_array - layers.increment(x=step_idx, value=1.0, in_place=True) + paddle.static.nn.control_flow.increment(x=step_idx, value=1.0, in_place=True) layers.array_write(element_in_arr, i=step_idx, array=arr) with paddle.fluid.device_guard(f'{device}:0'): @@ -135,7 +135,7 @@ class HybridParallelInferenceHelper: with while_op.block(): with paddle.fluid.device_guard(f'{device}:all'): input = layers.array_read(array=data, i=step_idx) - layers.increment(x=step_idx, value=1.0, in_place=True) + paddle.static.nn.control_flow.increment(x=step_idx, value=1.0, in_place=True) layers.array_write(input, i=step_idx, array=data) with paddle.fluid.device_guard(f'{device}:0'): diff --git a/python/paddle/fluid/layers/control_flow.py b/python/paddle/fluid/layers/control_flow.py index cd49f94e035b8..c2cc745de52c9 100755 --- a/python/paddle/fluid/layers/control_flow.py +++ b/python/paddle/fluid/layers/control_flow.py @@ -54,7 +54,6 @@ __all__ = [ 'While', 'Switch', - 'increment', 'array_write', 'array_read', 'cond', @@ -62,7 +61,6 @@ 'StaticRNN', 'reorder_lod_tensor_by_rank', 'Print', - 'Assert', 'is_empty', 'case', 'switch_case', @@ -455,78 +453,6 @@ def Print( return output -def Assert(cond, data=None, summarize=20, name=None): - ''' - This API creates an op that asserts the given condition is true. If the - condition is false, prints the tensors in data. ``summarize`` specifies the - number of the elements in the tensors to print. - - Args: - cond (Variable): The boolean condition tensor whose numel should be 1. - data (list|tuple, optional): list or tuple of tensors to print when - condition is not true. If it's ``None``, no tensor will be printed. - The default value is ``None``. - summarize (int, optional): Number of elements in the tensor to be - printed. If its value is -1, then all elements in the tensor will - be printed. The default value is 20. - name (str, optional): The default value is ``None`` . Normally users - don't have to set this parameter. For more information, please - refer to :ref:`api_guide_Name` . - - Returns: - Operator: the created operation. - - Raises: - TypeError: If ``cond`` is not boolean Variable. - TypeError: If ``data`` is not a list or tuple or ``None``. - TypeError: If ``summarize`` is not int. - TypeError: If ``name`` is not a string or ``None`` . - fluid.core.EnforceNotMet: If the condition is False in running time. - - Examples: - .. code-block:: python - - import paddle.fluid as fluid - import paddle.fluid.layers as layers - - x = layers.fill_constant(shape=[2, 3], dtype='float32', value=2.0) - condition = layers.reduce_max(x) < 1.0 # False - layers.Assert(condition, [x], 10, "example_assert_layer") - - exe = fluid.Executor() - try: - exe.run(fluid.default_main_program()) - # Print x and throws paddle.fluid.core.EnforceNotMet exception - # Example printed message for x: - # - # Variable: fill_constant_0.tmp_0 - # - lod: {} - # - place: CPUPlace() - # - shape: [2, 3] - # - layout: NCHW - # - dtype: float - # - data: [2 2 2 2 2 2] - except fluid.core.EnforceNotMet as e: - print("Assert Exception Example") - - ''' - check_variable_and_dtype(cond, "cond", ["bool"], "fluid.layers.Assert") - check_type(data, "data", (list, tuple, type(None)), "fluid.layers.Assert") - check_type(summarize, "summarize", int, "fluid.layers.Assert") - check_type(name, "name", (str, type(None)), "fluid.layers.Assert") - - layer_name = name if name else ('assert_' + cond.name) - helper = LayerHelper(layer_name, **locals()) - - op = helper.append_op( - type="assert", - inputs={"Cond": cond, "Data": [] if data is None else list(data)}, - attrs={"summarize": summarize}, - ) - - return op - - class BlockGuard: """ BlockGuard class. @@ -1216,7 +1142,7 @@ class While: cond = paddle.less_than(x=i, y=loop_len) while_op = fluid.layers.While(cond=cond) with while_op.block(): - i = fluid.layers.increment(x=i, value=1, in_place=True) + i = paddle.static.nn.control_flow.increment(x=i, value=1, in_place=True) paddle.assign(paddle.less_than(x=i, y=loop_len), cond) exe = fluid.Executor(fluid.CPUPlace()) @@ -1244,7 +1170,7 @@ class While: with while_op.block(): sums_tensor = fluid.layers.elementwise_add(x=data, y=data) fluid.layers.assign(sums_tensor, sums) # Update the value of sums_tensor defined in While to the sums which defined outside of While through layers.assign - i = fluid.layers.increment(x=i, value=1, in_place=True) + i = paddle.static.nn.control_flow.increment(x=i, value=1, in_place=True) data = fluid.layers.elementwise_add(x=data, y=one) paddle.assign(paddle.less_than(x=i, y=loop_len), cond) @@ -1607,47 +1533,6 @@ def max_sequence_len(rank_table): return res -def increment(x, value=1.0, in_place=True): - """ - The OP is usually used for control flow to increment the data of :attr:`x` by an amount :attr:`value`. - Notice that the number of elements in :attr:`x` must be equal to 1. - - Parameters: - x (Variable): A tensor that must always contain only one element, its data type supports - float32, float64, int32 and int64. - value (float, optional): The amount to increment the data of :attr:`x`. Default: 1.0. - in_place (bool, optional): Whether the OP should be performed in-place. Default: True. - - Returns: - Variable: The elementwise-incremented tensor with the same shape and data type as :attr:`x`. - - Examples: - .. code-block:: python - - import paddle.fluid as fluid - counter = fluid.layers.zeros(shape=[1], dtype='float32') # [0.] - fluid.layers.increment(counter) # [1.] - """ - if in_dygraph_mode(): - return _C_ops.increment_(x, value) - - check_variable_and_dtype( - x, 'x', ['float32', 'float64', 'int32', 'int64'], 'increment' - ) - helper = LayerHelper("increment", **locals()) - if not in_place: - out = helper.create_variable_for_type_inference(dtype=x.dtype) - else: - out = x - helper.append_op( - type='increment', - inputs={'X': [x]}, - outputs={'Out': [out]}, - attrs={'step': float(value)}, - ) - return out - - def array_write(x, i, array=None): """ This OP writes the input ``x`` into the i-th position of the ``array`` diff --git a/python/paddle/fluid/layers/rnn.py b/python/paddle/fluid/layers/rnn.py index 8b5721438d2e5..a1ea375a9be45 100644 --- a/python/paddle/fluid/layers/rnn.py +++ b/python/paddle/fluid/layers/rnn.py @@ -21,7 +21,7 @@ from paddle.utils import deprecated from . import nn from . import tensor -from . import control_flow +from paddle.static.nn import control_flow from . import utils from . import sequence_lod from .utils import * diff --git a/python/paddle/fluid/optimizer.py b/python/paddle/fluid/optimizer.py index ea10b49e9cc6f..7397db5bf8c23 100755 --- a/python/paddle/fluid/optimizer.py +++ b/python/paddle/fluid/optimizer.py @@ -7283,7 +7283,9 @@ def minimize(self, loss, startup_program=None): dtype='int32', persistable=True, ) - layers.increment(x=step, value=1.0, in_place=True) + paddle.static.nn.control_flow.increment( + x=step, value=1.0, in_place=True + ) # lookahead zero_var = layers.fill_constant( @@ -7517,7 +7519,9 @@ def _get_gm_cond_var(self, main_block): with device_guard("cpu"): # step_var = (step_var + 1) % k_step - layers.increment(x=step_var, value=1.0, in_place=True) + paddle.static.nn.control_flow.increment( + x=step_var, value=1.0, in_place=True + ) main_block.append_op( type='elementwise_mod', inputs={'X': step_var, 'Y': k_step_var}, diff --git a/python/paddle/fluid/tests/unittests/auto_parallel/test_while_op_partition.py b/python/paddle/fluid/tests/unittests/auto_parallel/test_while_op_partition.py index fcfd783f71f6d..92204cc7dd39a 100644 --- a/python/paddle/fluid/tests/unittests/auto_parallel/test_while_op_partition.py +++ b/python/paddle/fluid/tests/unittests/auto_parallel/test_while_op_partition.py @@ -189,7 +189,9 @@ def get_program(): cur_pred = mlp_while(pre_input) # 更新循环条件 - i = fluid.layers.increment(x=i, value=1, in_place=True) + i = paddle.static.nn.control_flow.increment( + x=i, value=1, in_place=True + ) fluid.layers.array_write(cur_pred, array=input_array, i=i) paddle.assign(paddle.less_than(x=i, y=loop_len), cond) diff --git a/python/paddle/fluid/tests/unittests/collective/fleet/hybrid_parallel_inference_helper.py b/python/paddle/fluid/tests/unittests/collective/fleet/hybrid_parallel_inference_helper.py index 542b1ba637936..c903359f68239 100644 --- a/python/paddle/fluid/tests/unittests/collective/fleet/hybrid_parallel_inference_helper.py +++ b/python/paddle/fluid/tests/unittests/collective/fleet/hybrid_parallel_inference_helper.py @@ -89,7 +89,9 @@ def test_hybrid_parallel_inference_helper_mp1pp2(self): with while_op.block(): with paddle.fluid.device_guard(f'{device}:all'): input = layers.array_read(array=data, i=step_idx) - layers.increment(x=step_idx, value=1.0, in_place=True) + paddle.static.nn.control_flow.increment( + x=step_idx, value=1.0, in_place=True + ) layers.array_write(input, i=step_idx, array=data) with paddle.fluid.device_guard(f'{device}:0'): diff --git a/python/paddle/fluid/tests/unittests/dist_transformer.py b/python/paddle/fluid/tests/unittests/dist_transformer.py index c6165dd753537..fad6c62cc3313 100644 --- a/python/paddle/fluid/tests/unittests/dist_transformer.py +++ b/python/paddle/fluid/tests/unittests/dist_transformer.py @@ -28,6 +28,7 @@ import paddle.fluid as fluid import paddle.fluid.layers as layers import paddle.nn.functional as F +import paddle.static.nn.control_flow as control_flow const_para_attr = fluid.ParamAttr(initializer=fluid.initializer.Constant(0.001)) const_bias_attr = const_para_attr @@ -1813,7 +1814,7 @@ def beam_search(): shape=[-1, 1, 1], dtype=pre_ids.dtype, ), - y=layers.increment(x=step_idx, value=1.0, in_place=False), + y=control_flow.increment(x=step_idx, value=1.0, in_place=False), axis=0, ) logits = wrap_decoder( @@ -1852,7 +1853,7 @@ def beam_search(): end_id=eos_idx, ) - layers.increment(x=step_idx, value=1.0, in_place=True) + control_flow.increment(x=step_idx, value=1.0, in_place=True) # update states layers.array_write(selected_ids, i=step_idx, array=ids) layers.array_write(selected_scores, i=step_idx, array=scores) diff --git a/python/paddle/fluid/tests/unittests/dygraph_to_static/test_loop.py b/python/paddle/fluid/tests/unittests/dygraph_to_static/test_loop.py index 06b17978d6687..9da4598425d07 100644 --- a/python/paddle/fluid/tests/unittests/dygraph_to_static/test_loop.py +++ b/python/paddle/fluid/tests/unittests/dygraph_to_static/test_loop.py @@ -19,6 +19,7 @@ import paddle import paddle.fluid as fluid +import paddle.static.nn.control_flow as control_flow from paddle.jit.api import declarative from paddle.jit.dy2static.loop_transformer import NameVisitor from paddle.utils import gast @@ -83,7 +84,7 @@ def while_loop_dyfunc_with_none(x): def for_loop_dyfunc(max_len): for i in range(max_len): ret = fluid.layers.zeros(shape=[1], dtype='float32') - fluid.layers.increment(ret, value=2.0, in_place=True) + control_flow.increment(ret, value=2.0, in_place=True) return ret @@ -104,14 +105,14 @@ def for_loop_dyfunc2(max_len): def for_loop_dyfunc3(max_len): ret = fluid.layers.zeros(shape=[1], dtype='float32') for i in range(1, 10, 2): - fluid.layers.increment(ret, value=2.0, in_place=True) + control_flow.increment(ret, value=2.0, in_place=True) return ret def for_loop_dyfunc4(max_len): ret = fluid.layers.zeros(shape=[1], dtype='float32') for i in range(10, 1, -2): - fluid.layers.increment(ret, value=2.0, in_place=True) + control_flow.increment(ret, value=2.0, in_place=True) return ret @@ -119,7 +120,7 @@ def for_loop_dyfunc_not_support(max_len): ret = fluid.layers.zeros(shape=[1], dtype='float32') a = -2 for i in range(10, 1, a): - fluid.layers.increment(ret, value=2.0, in_place=True) + control_flow.increment(ret, value=2.0, in_place=True) return ret diff --git a/python/paddle/fluid/tests/unittests/npu/test_increment_op_npu.py b/python/paddle/fluid/tests/unittests/npu/test_increment_op_npu.py index 39f11737bce6c..568f4d7a5a768 100644 --- a/python/paddle/fluid/tests/unittests/npu/test_increment_op_npu.py +++ b/python/paddle/fluid/tests/unittests/npu/test_increment_op_npu.py @@ -121,7 +121,7 @@ def test_npu(self): with paddle.static.program_guard(main_prog, startup_prog): a = paddle.static.data(name="a", shape=[1], dtype='float32') - b = fluid.layers.increment(a) + b = paddle.static.nn.control_flow.increment(a) place = paddle.NPUPlace(NPUPlace) diff --git a/python/paddle/fluid/tests/unittests/npu/test_while_op_npu.py b/python/paddle/fluid/tests/unittests/npu/test_while_op_npu.py index c63f11b85910c..043903b6e5d6e 100644 --- a/python/paddle/fluid/tests/unittests/npu/test_while_op_npu.py +++ b/python/paddle/fluid/tests/unittests/npu/test_while_op_npu.py @@ -21,6 +21,7 @@ from paddle.fluid.backward import append_backward import numpy from paddle.fluid import compiler, Program, program_guard +import paddle.static.nn.control_flow as control_flow paddle.enable_static() @@ -43,9 +44,9 @@ def simple_net(self): init = layers.zeros(shape=[10], dtype='float32') mem_array = layers.array_write(x=init, i=i) data_array = layers.array_write(x=d0, i=i) - i = layers.increment(i) + i = control_flow.increment(i) layers.array_write(d1, i, array=data_array) - i = layers.increment(i) + i = control_flow.increment(i) layers.array_write(d2, i, array=data_array) i = layers.zeros(shape=[1], dtype='int32') i = layers.cast(i, 'int64') @@ -71,7 +72,7 @@ def simple_net(self): prev = layers.array_read(array=mem_array, i=i) result = layers.sums(input=[d, prev]) - i = layers.increment(x=i, in_place=True) + i = control_flow.increment(x=i, in_place=True) layers.array_write(result, i=i, array=mem_array) paddle.assign(paddle.less_than(x=i, y=array_len), cond) @@ -80,7 +81,7 @@ def simple_net(self): prev2 = layers.array_read(array=mem_array, i=j) result2 = layers.sums(input=[d2, prev2]) - j = layers.increment(x=j, in_place=True) + j = control_flow.increment(x=j, in_place=True) layers.array_write(result2, i=j, array=mem_array) paddle.assign(paddle.less_than(x=j, y=array_len2), cond2) sum_result = layers.array_read(array=mem_array, i=j) diff --git a/python/paddle/fluid/tests/unittests/test_array_read_write_op.py b/python/paddle/fluid/tests/unittests/test_array_read_write_op.py index 907bb65cfce25..3cb9e7b33dc1e 100644 --- a/python/paddle/fluid/tests/unittests/test_array_read_write_op.py +++ b/python/paddle/fluid/tests/unittests/test_array_read_write_op.py @@ -20,6 +20,7 @@ import paddle.fluid as fluid import paddle.fluid.core as core import paddle.fluid.layers as layers +import paddle.static.nn.control_flow as control_flow from paddle.fluid import Program, program_guard from paddle.fluid.backward import append_backward from paddle.fluid.executor import Executor @@ -30,17 +31,17 @@ def _test_read_write(x): i = layers.zeros(shape=[1], dtype='int64') i.stop_gradient = False arr = layers.array_write(x=x[0], i=i) - i = layers.increment(x=i) + i = control_flow.increment(x=i) arr = layers.array_write(x=x[1], i=i, array=arr) - i = layers.increment(x=i) + i = control_flow.increment(x=i) arr = layers.array_write(x=x[2], i=i, array=arr) i = layers.zeros(shape=[1], dtype='int64') i.stop_gradient = False a0 = layers.array_read(array=arr, i=i) - i = layers.increment(x=i) + i = control_flow.increment(x=i) a1 = layers.array_read(array=arr, i=i) - i = layers.increment(x=i) + i = control_flow.increment(x=i) a2 = layers.array_read(array=arr, i=i) mean_a0 = paddle.mean(a0) diff --git a/python/paddle/fluid/tests/unittests/test_assert_op.py b/python/paddle/fluid/tests/unittests/test_assert_op.py index d59194aef56cb..f62ad38d459d1 100644 --- a/python/paddle/fluid/tests/unittests/test_assert_op.py +++ b/python/paddle/fluid/tests/unittests/test_assert_op.py @@ -17,6 +17,7 @@ import paddle import paddle.fluid as fluid import paddle.fluid.layers as layers +from paddle.static.nn.control_flow import Assert class TestAssertOp(unittest.TestCase): @@ -33,7 +34,7 @@ def net_func(): condition = layers.fill_constant( shape=[1], dtype='bool', value=True ) - layers.Assert(condition, []) + Assert(condition, []) self.run_network(net_func) @@ -42,7 +43,7 @@ def net_func(): condition = layers.fill_constant( shape=[1], dtype='bool', value=False ) - layers.Assert(condition) + Assert(condition) with self.assertRaises(ValueError): self.run_network(net_func) @@ -52,7 +53,7 @@ def net_func(): condition = layers.fill_constant( shape=[1, 2], dtype='bool', value=True ) - layers.Assert(condition, []) + Assert(condition, []) with self.assertRaises(ValueError): self.run_network(net_func) @@ -62,7 +63,7 @@ def net_func(): zero = layers.fill_constant(shape=[1], dtype='int64', value=0) one = layers.fill_constant(shape=[1], dtype='int64', value=1) condition = paddle.less_than(one, zero) # False - layers.Assert(condition, [zero, one]) + Assert(condition, [zero, one]) print("test_assert_print_data") with self.assertRaises(ValueError): @@ -72,7 +73,7 @@ def test_assert_summary(self): def net_func(): x = layers.fill_constant(shape=[10], dtype='float32', value=2.0) condition = paddle.max(x) < 1.0 - layers.Assert(condition, (x,), 5) + Assert(condition, (x,), 5) print("test_assert_summary") with self.assertRaises(ValueError): @@ -82,7 +83,7 @@ def test_assert_summary_greater_than_size(self): def net_func(): x = layers.fill_constant(shape=[2, 3], dtype='float32', value=2.0) condition = paddle.max(x) < 1.0 - layers.Assert(condition, [x], 10, name="test") + Assert(condition, [x], 10, name="test") print("test_assert_summary_greater_than_size") with self.assertRaises(ValueError): diff --git a/python/paddle/fluid/tests/unittests/test_async_ssa_graph_executor_mnist.py b/python/paddle/fluid/tests/unittests/test_async_ssa_graph_executor_mnist.py index 26eb0a628ab9a..27fb3e36bb007 100644 --- a/python/paddle/fluid/tests/unittests/test_async_ssa_graph_executor_mnist.py +++ b/python/paddle/fluid/tests/unittests/test_async_ssa_graph_executor_mnist.py @@ -62,7 +62,7 @@ def convolutional_neural_network(use_py_reader): acc = paddle.static.accuracy(input=prediction, label=label) i = fluid.layers.zeros(shape=[1], dtype='int64') array = fluid.layers.array_write(x=prediction, i=i) - fluid.layers.increment(i) + paddle.static.nn.control_flow.increment(i) fluid.layers.array_write(x=acc, i=i, array=array) return array, img, label, prediction, avg_loss, acc, py_reader diff --git a/python/paddle/fluid/tests/unittests/test_dynamic_rnn_stop_gradient.py b/python/paddle/fluid/tests/unittests/test_dynamic_rnn_stop_gradient.py index 3e3eefd5d278d..f839563344a86 100644 --- a/python/paddle/fluid/tests/unittests/test_dynamic_rnn_stop_gradient.py +++ b/python/paddle/fluid/tests/unittests/test_dynamic_rnn_stop_gradient.py @@ -51,7 +51,9 @@ def build_and_run_program(place, batch_size, beam_size, stop_gradient=False): topk_coordinates = paddle.stack([batch_pos, indices], axis=2) topk_coordinates.stop_gradient = stop_gradient score = paddle.gather_nd(x, topk_coordinates) - layers.increment(x=step_idx, value=1.0, in_place=True) + paddle.static.nn.control_flow.increment( + x=step_idx, value=1.0, in_place=True + ) layers.array_write(score, i=step_idx, array=scores) length_cond = paddle.less_than(x=step_idx, y=max_len) layers.assign(length_cond, cond) diff --git a/python/paddle/fluid/tests/unittests/test_eager_deletion_while_op.py b/python/paddle/fluid/tests/unittests/test_eager_deletion_while_op.py index 943642b857cce..bebb534319cb3 100644 --- a/python/paddle/fluid/tests/unittests/test_eager_deletion_while_op.py +++ b/python/paddle/fluid/tests/unittests/test_eager_deletion_while_op.py @@ -26,6 +26,7 @@ import paddle.fluid.compiler as compiler import paddle.fluid.core as core import paddle.fluid.layers as layers +import paddle.static.nn.control_flow as control_flow from paddle.fluid.executor import Executor paddle.enable_static() @@ -83,10 +84,10 @@ def run_main(self, place, with_data_parallel): mem_array = layers.array_write(x=init, i=i) data_array = layers.array_write(x=d0, i=i) - i = layers.increment(i) + i = control_flow.increment(i) layers.array_write(d1, i, array=data_array) - i = layers.increment(i) + i = control_flow.increment(i) layers.array_write(d2, i, array=data_array) i = layers.zeros(shape=[1], dtype='int64') @@ -112,7 +113,7 @@ def run_main(self, place, with_data_parallel): prev = paddle.reshape(prev, shape=[10]) result = layers.sums(input=[d, prev]) - i = layers.increment(x=i, in_place=True) + i = control_flow.increment(x=i, in_place=True) layers.array_write(result, i=i, array=mem_array) paddle.assign(paddle.less_than(x=i, y=array_len), cond) with while_op2.block(): @@ -122,7 +123,7 @@ def run_main(self, place, with_data_parallel): prev2 = paddle.reshape(prev2, shape=[10]) result2 = layers.sums(input=[d2, prev2]) - j = layers.increment(x=j, in_place=True) + j = control_flow.increment(x=j, in_place=True) layers.array_write(result2, i=j, array=mem_array) paddle.assign(paddle.less_than(x=j, y=array_len2), cond2) diff --git a/python/paddle/fluid/tests/unittests/test_executor_and_mul.py b/python/paddle/fluid/tests/unittests/test_executor_and_mul.py index 639f84295b24b..912d5a8490bfe 100644 --- a/python/paddle/fluid/tests/unittests/test_executor_and_mul.py +++ b/python/paddle/fluid/tests/unittests/test_executor_and_mul.py @@ -16,8 +16,9 @@ import numpy as np +import paddle.static.nn.control_flow as control_flow from paddle.fluid.executor import Executor -from paddle.fluid.layers import array_write, data, increment, mul, zeros +from paddle.fluid.layers import array_write, data, mul, zeros class TestExecutor(unittest.TestCase): @@ -26,13 +27,13 @@ def test_mul(self): a = data(name='a', shape=[784], dtype='float32') array = array_write(x=a, i=i) - i = increment(i) + i = control_flow.increment(i) b = data( name='b', shape=[784, 100], dtype='float32', append_batch_size=False ) array_write(x=b, i=i, array=array) - i = increment(i) + i = control_flow.increment(i) out = mul(x=a, y=b) array_write(x=out, i=i, array=array) diff --git a/python/paddle/fluid/tests/unittests/test_fetch_lod_tensor_array.py b/python/paddle/fluid/tests/unittests/test_fetch_lod_tensor_array.py index b2869d8888237..9a127edce18f1 100644 --- a/python/paddle/fluid/tests/unittests/test_fetch_lod_tensor_array.py +++ b/python/paddle/fluid/tests/unittests/test_fetch_lod_tensor_array.py @@ -20,6 +20,7 @@ import paddle.fluid as fluid import paddle.fluid.layers as layers +import paddle.static.nn.control_flow as control_flow class TestFetchLoDTensorArray(unittest.TestCase): @@ -35,9 +36,9 @@ def build_program(self, main_program, startup_program): opt.minimize(loss) array = layers.array_write(x=img, i=i) - i = layers.increment(i) + i = control_flow.increment(i) layers.array_write(x=label, i=i, array=array) - i = layers.increment(i) + i = control_flow.increment(i) layers.array_write(x=loss, i=i, array=array) return loss, array diff --git a/python/paddle/fluid/tests/unittests/test_profiler.py b/python/paddle/fluid/tests/unittests/test_profiler.py index 62d46d4cadc48..0f7459dd96893 100644 --- a/python/paddle/fluid/tests/unittests/test_profiler.py +++ b/python/paddle/fluid/tests/unittests/test_profiler.py @@ -50,7 +50,9 @@ def build_program(self, compile_program=True): with while_op.block(): hidden_n = fluid.layers.fc(input=hidden1, size=64, act='relu') layers.array_write(hidden_n, i, data_arr) - fluid.layers.increment(x=counter, value=1, in_place=True) + paddle.static.nn.control_flow.increment( + x=counter, value=1, in_place=True + ) paddle.assign(paddle.less_than(x=counter, y=until), cond) hidden_n = layers.array_read(data_arr, i) diff --git a/python/paddle/fluid/tests/unittests/test_while_loop_op.py b/python/paddle/fluid/tests/unittests/test_while_loop_op.py index 8c94834c9a28b..19193fb348399 100644 --- a/python/paddle/fluid/tests/unittests/test_while_loop_op.py +++ b/python/paddle/fluid/tests/unittests/test_while_loop_op.py @@ -20,6 +20,7 @@ import paddle.fluid as fluid import paddle.fluid.core as core import paddle.fluid.layers as layers +import paddle.static.nn.control_flow as control_flow from paddle.fluid.backward import append_backward from paddle.fluid.framework import Program, program_guard @@ -59,7 +60,7 @@ def cond(i, mem): def body(i, mem): mem = paddle.add(x=mem, y=one) - i = layers.increment(i) + i = control_flow.increment(i) return [i, mem] main_program = Program() @@ -100,7 +101,7 @@ def body(i, ten, test_dict, test_list, test_list_dict): test_list_dict[0]["test_key"] ) - i = layers.increment(i) + i = control_flow.increment(i) return [i, ten, test_dict, test_list, test_list_dict] main_program = Program() @@ -168,7 +169,7 @@ def internal_cond(j, init, sums): def internal_body(j, init, sums): init = paddle.add(x=init, y=ones) sums = paddle.add(x=init, y=sums) - j = layers.increment(j) + j = control_flow.increment(j) return [j, init, sums] result = layers.while_loop( @@ -178,7 +179,7 @@ def internal_body(j, init, sums): init = result[1] sums = result[2] sums = paddle.add(x=init, y=sums) - i = layers.increment(i) + i = control_flow.increment(i) return [i, j, init, sums] main_program = Program() @@ -223,7 +224,7 @@ def cond(i, x): def body(i, x): x = paddle.multiply(x=i, y=i) - i = layers.increment(i) + i = control_flow.increment(i) return [i, x] main_program = Program() @@ -318,7 +319,7 @@ def internal_body(j, x, mem_array): inner_prev = layers.array_read(array=mem_array, i=j) inner_sum_0 = paddle.add(x=inner_data, y=inner_prev) inner_sum_1 = paddle.add(x=x, y=inner_sum_0) - j = layers.increment(x=j, in_place=True) + j = control_flow.increment(x=j, in_place=True) layers.array_write(inner_sum_1, i=j, array=mem_array) return [j, x, mem_array] @@ -326,7 +327,7 @@ def internal_body(j, x, mem_array): outer_prev = layers.array_read(array=mem_array, i=i) outer_sum_0 = paddle.add(x=outer_data, y=outer_prev) outer_sum_1 = paddle.add(x=x, y=outer_sum_0) - i = layers.increment(x=i, in_place=True) + i = control_flow.increment(x=i, in_place=True) layers.array_write(outer_sum_1, i=i, array=mem_array) j, x, mem_array = layers.while_loop( internal_cond, internal_body, [j, x, mem_array] @@ -346,9 +347,9 @@ def internal_body(j, x, mem_array): init = layers.zeros(shape=[10], dtype='float32') mem_array = layers.array_write(x=init, i=i) data_array = layers.array_write(x=d0, i=i) - i = layers.increment(i) + i = control_flow.increment(i) layers.array_write(d1, i, array=data_array) - i = layers.increment(i) + i = control_flow.increment(i) layers.array_write(d2, i, array=data_array) i = layers.zeros(shape=[1], dtype='int64') i.stop_gradient = True @@ -438,7 +439,7 @@ def cond_returns_constant(i): return 1 def cond_returns_not_bool_tensor(i): - return layers.increment(i) + return control_flow.increment(i) def cond_returns_bool_tensor(i): return paddle.less_than(i, ten) @@ -450,14 +451,14 @@ def cond_receives_two_args(i, ten): return paddle.less_than(i, ten) def body(i): - return layers.increment(i) + return control_flow.increment(i) def body_returns_error_length(i): - i = layers.increment(i) + i = control_flow.increment(i) return [i, i] def body_returns_error_type(i, ten): - return layers.increment(i) + return control_flow.increment(i) def cond_returns_with_mutable_dict(i, test_dict): return i > 0 @@ -466,7 +467,7 @@ def body_returns_with_mutable_dict(i, test_dict): test_dict['new_key'] = layers.fill_constant( shape=[1], dtype='int64', value=1 ) - return layers.increment(i), test_dict + return control_flow.increment(i), test_dict def cond_returns_with_mutable_list(i, test_list): return i > 0 @@ -475,7 +476,7 @@ def body_returns_with_mutable_list(i, test_list): test_list.append( layers.fill_constant(shape=[1], dtype='int64', value=1) ) - return layers.increment(i), test_list + return control_flow.increment(i), test_list main_program = Program() startup_program = Program() diff --git a/python/paddle/fluid/tests/unittests/test_while_op.py b/python/paddle/fluid/tests/unittests/test_while_op.py index f77d9767f3c8b..b277cb334480b 100644 --- a/python/paddle/fluid/tests/unittests/test_while_op.py +++ b/python/paddle/fluid/tests/unittests/test_while_op.py @@ -20,6 +20,7 @@ import paddle.fluid as fluid import paddle.fluid.core as core import paddle.fluid.layers as layers +import paddle.static.nn.control_flow as control_flow from paddle.fluid.backward import append_backward from paddle.fluid.executor import Executor @@ -42,9 +43,9 @@ def simple_net(self): init = layers.zeros(shape=[10], dtype='float32') mem_array = layers.array_write(x=init, i=i) data_array = layers.array_write(x=d0, i=i) - i = layers.increment(i) + i = control_flow.increment(i) layers.array_write(d1, i, array=data_array) - i = layers.increment(i) + i = control_flow.increment(i) layers.array_write(d2, i, array=data_array) i = layers.zeros(shape=[1], dtype='int64') i.stop_gradient = True @@ -63,7 +64,7 @@ def simple_net(self): prev = layers.array_read(array=mem_array, i=i) result = layers.sums(input=[d, prev]) - i = layers.increment(x=i, in_place=True) + i = control_flow.increment(x=i, in_place=True) layers.array_write(result, i=i, array=mem_array) paddle.assign(paddle.less_than(x=i, y=array_len), cond) @@ -72,7 +73,7 @@ def simple_net(self): prev2 = layers.array_read(array=mem_array, i=j) result2 = layers.sums(input=[d2, prev2]) - j = layers.increment(x=j, in_place=True) + j = control_flow.increment(x=j, in_place=True) layers.array_write(result2, i=j, array=mem_array) paddle.assign(paddle.less_than(x=j, y=array_len2), cond2) sum_result = layers.array_read(array=mem_array, i=j) @@ -134,7 +135,7 @@ def test_error(self): def test_bad_x(): x = [1, 2, 3] - fluid.layers.increment(x) + control_flow.increment(x) self.assertRaises(TypeError, test_bad_x) diff --git a/python/paddle/fluid/tests/unittests/xpu/test_while_op_xpu.py b/python/paddle/fluid/tests/unittests/xpu/test_while_op_xpu.py index e52e8fdceb7ed..33056f8c9b832 100644 --- a/python/paddle/fluid/tests/unittests/xpu/test_while_op_xpu.py +++ b/python/paddle/fluid/tests/unittests/xpu/test_while_op_xpu.py @@ -19,6 +19,7 @@ import paddle import paddle.fluid as fluid import paddle.fluid.layers as layers +import paddle.static.nn.control_flow as control_flow from paddle.fluid.backward import append_backward from paddle.fluid.executor import Executor @@ -41,9 +42,9 @@ def simple_net(self): init = layers.zeros(shape=[10], dtype='float32') mem_array = layers.array_write(x=init, i=i) data_array = layers.array_write(x=d0, i=i) - i = layers.increment(i) + i = control_flow.increment(i) layers.array_write(d1, i, array=data_array) - i = layers.increment(i) + i = control_flow.increment(i) layers.array_write(d2, i, array=data_array) i = layers.zeros(shape=[1], dtype='int64') i.stop_gradient = True @@ -62,7 +63,7 @@ def simple_net(self): prev = layers.array_read(array=mem_array, i=i) result = layers.sums(input=[d, prev]) - i = layers.increment(x=i, in_place=True) + i = control_flow.increment(x=i, in_place=True) layers.array_write(result, i=i, array=mem_array) paddle.assign(paddle.less_than(x=i, y=array_len), cond) @@ -71,7 +72,7 @@ def simple_net(self): prev2 = layers.array_read(array=mem_array, i=j) result2 = layers.sums(input=[d2, prev2]) - j = layers.increment(x=j, in_place=True) + j = control_flow.increment(x=j, in_place=True) layers.array_write(result2, i=j, array=mem_array) paddle.assign(paddle.less_than(x=j, y=array_len2), cond2) sum_result = layers.array_read(array=mem_array, i=j) diff --git a/python/paddle/jit/dy2static/convert_operators.py b/python/paddle/jit/dy2static/convert_operators.py index 1d3e23a4b96b7..886aefa94e30a 100644 --- a/python/paddle/jit/dy2static/convert_operators.py +++ b/python/paddle/jit/dy2static/convert_operators.py @@ -14,12 +14,13 @@ import re import paddle +from paddle.static.nn.control_flow import Assert, increment from paddle.fluid.data_feeder import convert_dtype from paddle.jit.dy2static.variable_trans_func import ( to_static_variable, ) from paddle.fluid.framework import core, Variable -from paddle.fluid.layers import Assert, Print +from paddle.fluid.layers import Print from paddle.fluid.layers import ( array_read, array_write, @@ -35,7 +36,6 @@ from paddle.fluid.layers.control_flow import ( cond, while_loop, - increment, ) from .return_transformer import ( RETURN_NO_VALUE_VAR_NAME, From cf743858d6c026bc5bc8667f47708348d6fab5d6 Mon Sep 17 00:00:00 2001 From: wuzhanfei Date: Tue, 6 Dec 2022 03:32:54 +0000 Subject: [PATCH 02/16] add control_flow.py --- python/paddle/static/nn/control_flow.py | 143 ++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 python/paddle/static/nn/control_flow.py diff --git a/python/paddle/static/nn/control_flow.py b/python/paddle/static/nn/control_flow.py new file mode 100644 index 0000000000000..c2f69c69ec882 --- /dev/null +++ b/python/paddle/static/nn/control_flow.py @@ -0,0 +1,143 @@ +# Copyright (c) 2022 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 paddle import _C_ops +from paddle.fluid.data_feeder import check_type, check_variable_and_dtype +from paddle.fluid.layer_helper import LayerHelper +from paddle.framework import in_dygraph_mode + +__all__ = [ + 'Assert', + 'increment', +] + + +def Assert(cond, data=None, summarize=20, name=None): + ''' + This API creates an op that asserts the given condition is true. If the + condition is false, prints the tensors in data. ``summarize`` specifies the + number of the elements in the tensors to print. + + Args: + cond (Variable): The boolean condition tensor whose numel should be 1. + data (list|tuple, optional): list or tuple of tensors to print when + condition is not true. If it's ``None``, no tensor will be printed. + The default value is ``None``. + summarize (int, optional): Number of elements in the tensor to be + printed. If its value is -1, then all elements in the tensor will + be printed. The default value is 20. + name (str, optional): The default value is ``None`` . Normally users + don't have to set this parameter. For more information, please + refer to :ref:`api_guide_Name` . + + Returns: + Operator: the created operation. + + Raises: + TypeError: If ``cond`` is not boolean Variable. + TypeError: If ``data`` is not a list or tuple or ``None``. + TypeError: If ``summarize`` is not int. + TypeError: If ``name`` is not a string or ``None`` . + framework.core.EnforceNotMet: If the condition is False in running time. + + Examples: + .. code-block:: python + + import paddle + from paddle.static.nn.control_flow import Assert + + x = paddle.full(shape=[2, 3], dtype='float32', value=2.0) + condition = paddle.max(x) < 1.0 # False + Assert(condition, [x], 10, "example_assert_layer") + + exe = paddle.static.Executor() + try: + exe.run(paddle.static.default_main_program()) + # Print x and throws paddle.framework.core.EnforceNotMet exception + # Example printed message for x: + # + # Variable: fill_constant_0.tmp_0 + # - lod: {} + # - place: CPUPlace() + # - shape: [2, 3] + # - layout: NCHW + # - dtype: float + # - data: [2 2 2 2 2 2] + except paddle.framework.core.EnforceNotMet as e: + print("Assert Exception Example") + + ''' + check_variable_and_dtype( + cond, "cond", ["bool"], "static.nn.control_flow.Assert" + ) + check_type( + data, "data", (list, tuple, type(None)), "static.nn.control_flow.Assert" + ) + check_type(summarize, "summarize", int, "static.nn.control_flow.Assert") + check_type(name, "name", (str, type(None)), "static.nn.control_flow.Assert") + + layer_name = name if name else ('assert_' + cond.name) + helper = LayerHelper(layer_name, **locals()) + + op = helper.append_op( + type="assert", + inputs={"Cond": cond, "Data": [] if data is None else list(data)}, + attrs={"summarize": summarize}, + ) + + return op + + +def increment(x, value=1.0, in_place=True): + """ + The OP is usually used for control flow to increment the data of :attr:`x` by an amount :attr:`value`. + Notice that the number of elements in :attr:`x` must be equal to 1. + + Parameters: + x (Variable): A tensor that must always contain only one element, its data type supports + float32, float64, int32 and int64. + value (float, optional): The amount to increment the data of :attr:`x`. Default: 1.0. + in_place (bool, optional): Whether the OP should be performed in-place. Default: True. + + Returns: + Variable: The elementwise-incremented tensor with the same shape and data type as :attr:`x`. + + Examples: + .. code-block:: python + + import paddle + from paddle.static.nn.control_flow import increment + + counter = paddle.zeros(shape=[1], dtype='float32') # [0.] + increment(counter) # [1.] + """ + if in_dygraph_mode(): + return _C_ops.increment_(x, value) + + check_variable_and_dtype( + x, 'x', ['float32', 'float64', 'int32', 'int64'], 'increment' + ) + helper = LayerHelper("increment", **locals()) + if not in_place: + out = helper.create_variable_for_type_inference(dtype=x.dtype) + else: + out = x + helper.append_op( + type='increment', + inputs={'X': [x]}, + outputs={'Out': [out]}, + attrs={'step': float(value)}, + ) + return out From 3e917420c6bd995c56925532ca113d8de2246f92 Mon Sep 17 00:00:00 2001 From: wuzhanfei Date: Tue, 6 Dec 2022 07:47:11 +0000 Subject: [PATCH 03/16] fix circular dependency --- python/paddle/fluid/layers/rnn.py | 9 ++++++--- python/paddle/jit/dy2static/convert_operators.py | 5 ++++- python/paddle/static/nn/control_flow.py | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/python/paddle/fluid/layers/rnn.py b/python/paddle/fluid/layers/rnn.py index a1ea375a9be45..9df2820f02556 100644 --- a/python/paddle/fluid/layers/rnn.py +++ b/python/paddle/fluid/layers/rnn.py @@ -21,7 +21,7 @@ from paddle.utils import deprecated from . import nn from . import tensor -from paddle.static.nn import control_flow +from . import control_flow from . import utils from . import sequence_lod from .utils import * @@ -1535,8 +1535,9 @@ def _maybe_copy(state, new_state, step_mask): next_finished, next_sequence_lengths, ) + from paddle.static.nn.control_flow import increment - control_flow.increment(x=step_idx_tensor, value=1.0, in_place=True) + increment(x=step_idx_tensor, value=1.0, in_place=True) step_idx += 1 cond = paddle.logical_not(paddle.all(finished)) @@ -1695,7 +1696,9 @@ def _create_array_out_of_while(dtype): outputs, outputs_arrays, ) - control_flow.increment(x=step_idx, value=1.0, in_place=True) + from paddle.static.nn.control_flow import increment + + increment(x=step_idx, value=1.0, in_place=True) # update the global_finished first, since it might be also in states of # decoder, which otherwise would write a stale finished status to array tensor.assign(next_finished, global_finished) diff --git a/python/paddle/jit/dy2static/convert_operators.py b/python/paddle/jit/dy2static/convert_operators.py index 886aefa94e30a..a5d2ca14cd9b6 100644 --- a/python/paddle/jit/dy2static/convert_operators.py +++ b/python/paddle/jit/dy2static/convert_operators.py @@ -14,7 +14,6 @@ import re import paddle -from paddle.static.nn.control_flow import Assert, increment from paddle.fluid.data_feeder import convert_dtype from paddle.jit.dy2static.variable_trans_func import ( to_static_variable, @@ -731,6 +730,8 @@ def convert_assert(cond, message=""): if isinstance(cond, Variable): cond = cast(cond, "bool") # NOTE: message is not used because Paddle Assert has no corresponding parameter to use. + from paddle.static.nn.control_flow import Assert + return Assert(cond) else: assert cond, message @@ -783,6 +784,8 @@ def cond(i, new_array): def body(i, new_array): item = array_read(array=array, i=i) array_write(item, paddle.tensor.array_length(new_array), new_array) + from paddle.static.nn.control_flow import increment + i = increment(i) return i, new_array diff --git a/python/paddle/static/nn/control_flow.py b/python/paddle/static/nn/control_flow.py index c2f69c69ec882..1eecde1cb6c86 100644 --- a/python/paddle/static/nn/control_flow.py +++ b/python/paddle/static/nn/control_flow.py @@ -14,8 +14,8 @@ from paddle import _C_ops +from paddle.common_ops_import import LayerHelper from paddle.fluid.data_feeder import check_type, check_variable_and_dtype -from paddle.fluid.layer_helper import LayerHelper from paddle.framework import in_dygraph_mode __all__ = [ From 2080f9db3ab2bbc17372a62e3852e232c5ccc8f2 Mon Sep 17 00:00:00 2001 From: wuzhanfei Date: Tue, 6 Dec 2022 12:24:35 +0000 Subject: [PATCH 04/16] add interface to paddle.static.nn --- .../fleet/utils/hybrid_parallel_inference.py | 4 +-- python/paddle/fluid/layers/control_flow.py | 4 +-- python/paddle/fluid/layers/rnn.py | 6 ++-- python/paddle/fluid/optimizer.py | 8 ++--- .../auto_parallel/test_while_op_partition.py | 4 +-- .../fluid/tests/unittests/dist_transformer.py | 7 ++-- .../unittests/dygraph_to_static/test_loop.py | 10 +++--- .../unittests/npu/test_increment_op_npu.py | 2 +- .../tests/unittests/npu/test_while_op_npu.py | 10 +++--- .../unittests/test_array_read_write_op.py | 10 +++--- .../test_async_ssa_graph_executor_mnist.py | 2 +- .../test_dynamic_rnn_stop_gradient.py | 4 +-- .../unittests/test_eager_deletion_while_op.py | 10 +++--- .../tests/unittests/test_executor_and_mul.py | 6 ++-- .../unittests/test_fetch_lod_tensor_array.py | 6 ++-- .../fluid/tests/unittests/test_profiler.py | 4 +-- .../tests/unittests/test_while_loop_op.py | 32 +++++++++---------- .../fluid/tests/unittests/test_while_op.py | 12 +++---- .../tests/unittests/xpu/test_while_op_xpu.py | 10 +++--- .../paddle/jit/dy2static/convert_operators.py | 3 +- python/paddle/static/nn/__init__.py | 3 ++ 21 files changed, 75 insertions(+), 82 deletions(-) diff --git a/python/paddle/distributed/fleet/utils/hybrid_parallel_inference.py b/python/paddle/distributed/fleet/utils/hybrid_parallel_inference.py index 13688589383e1..3281884783cf0 100644 --- a/python/paddle/distributed/fleet/utils/hybrid_parallel_inference.py +++ b/python/paddle/distributed/fleet/utils/hybrid_parallel_inference.py @@ -62,7 +62,7 @@ class HybridParallelInferenceHelper: element_in_arr = layers.array_read(array=arr, i=step_idx) # write placehold data to global lod_tensor_array, # it need for send_v2 of lod_tensor_array - paddle.static.nn.control_flow.increment(x=step_idx, value=1.0, in_place=True) + paddle.static.nn.increment(x=step_idx, value=1.0, in_place=True) layers.array_write(element_in_arr, i=step_idx, array=arr) with paddle.fluid.device_guard(f'{device}:0'): @@ -135,7 +135,7 @@ class HybridParallelInferenceHelper: with while_op.block(): with paddle.fluid.device_guard(f'{device}:all'): input = layers.array_read(array=data, i=step_idx) - paddle.static.nn.control_flow.increment(x=step_idx, value=1.0, in_place=True) + paddle.static.nn.increment(x=step_idx, value=1.0, in_place=True) layers.array_write(input, i=step_idx, array=data) with paddle.fluid.device_guard(f'{device}:0'): diff --git a/python/paddle/fluid/layers/control_flow.py b/python/paddle/fluid/layers/control_flow.py index c2cc745de52c9..ef448f357b87a 100755 --- a/python/paddle/fluid/layers/control_flow.py +++ b/python/paddle/fluid/layers/control_flow.py @@ -1142,7 +1142,7 @@ class While: cond = paddle.less_than(x=i, y=loop_len) while_op = fluid.layers.While(cond=cond) with while_op.block(): - i = paddle.static.nn.control_flow.increment(x=i, value=1, in_place=True) + i = paddle.static.nn.increment(x=i, value=1, in_place=True) paddle.assign(paddle.less_than(x=i, y=loop_len), cond) exe = fluid.Executor(fluid.CPUPlace()) @@ -1170,7 +1170,7 @@ class While: with while_op.block(): sums_tensor = fluid.layers.elementwise_add(x=data, y=data) fluid.layers.assign(sums_tensor, sums) # Update the value of sums_tensor defined in While to the sums which defined outside of While through layers.assign - i = paddle.static.nn.control_flow.increment(x=i, value=1, in_place=True) + i = paddle.static.nn.increment(x=i, value=1, in_place=True) data = fluid.layers.elementwise_add(x=data, y=one) paddle.assign(paddle.less_than(x=i, y=loop_len), cond) diff --git a/python/paddle/fluid/layers/rnn.py b/python/paddle/fluid/layers/rnn.py index 9df2820f02556..0ec0ba68e997b 100644 --- a/python/paddle/fluid/layers/rnn.py +++ b/python/paddle/fluid/layers/rnn.py @@ -1535,9 +1535,8 @@ def _maybe_copy(state, new_state, step_mask): next_finished, next_sequence_lengths, ) - from paddle.static.nn.control_flow import increment - increment(x=step_idx_tensor, value=1.0, in_place=True) + paddle.static.nn.increment(x=step_idx_tensor, value=1.0, in_place=True) step_idx += 1 cond = paddle.logical_not(paddle.all(finished)) @@ -1696,9 +1695,8 @@ def _create_array_out_of_while(dtype): outputs, outputs_arrays, ) - from paddle.static.nn.control_flow import increment - increment(x=step_idx, value=1.0, in_place=True) + paddle.static.nn.increment(x=step_idx, value=1.0, in_place=True) # update the global_finished first, since it might be also in states of # decoder, which otherwise would write a stale finished status to array tensor.assign(next_finished, global_finished) diff --git a/python/paddle/fluid/optimizer.py b/python/paddle/fluid/optimizer.py index 7397db5bf8c23..d49fe0c70159d 100755 --- a/python/paddle/fluid/optimizer.py +++ b/python/paddle/fluid/optimizer.py @@ -7283,9 +7283,7 @@ def minimize(self, loss, startup_program=None): dtype='int32', persistable=True, ) - paddle.static.nn.control_flow.increment( - x=step, value=1.0, in_place=True - ) + paddle.static.nn.increment(x=step, value=1.0, in_place=True) # lookahead zero_var = layers.fill_constant( @@ -7519,9 +7517,7 @@ def _get_gm_cond_var(self, main_block): with device_guard("cpu"): # step_var = (step_var + 1) % k_step - paddle.static.nn.control_flow.increment( - x=step_var, value=1.0, in_place=True - ) + paddle.static.nn.increment(x=step_var, value=1.0, in_place=True) main_block.append_op( type='elementwise_mod', inputs={'X': step_var, 'Y': k_step_var}, diff --git a/python/paddle/fluid/tests/unittests/auto_parallel/test_while_op_partition.py b/python/paddle/fluid/tests/unittests/auto_parallel/test_while_op_partition.py index 92204cc7dd39a..b8d495d553068 100644 --- a/python/paddle/fluid/tests/unittests/auto_parallel/test_while_op_partition.py +++ b/python/paddle/fluid/tests/unittests/auto_parallel/test_while_op_partition.py @@ -189,9 +189,7 @@ def get_program(): cur_pred = mlp_while(pre_input) # 更新循环条件 - i = paddle.static.nn.control_flow.increment( - x=i, value=1, in_place=True - ) + i = paddle.static.nn.increment(x=i, value=1, in_place=True) fluid.layers.array_write(cur_pred, array=input_array, i=i) paddle.assign(paddle.less_than(x=i, y=loop_len), cond) diff --git a/python/paddle/fluid/tests/unittests/dist_transformer.py b/python/paddle/fluid/tests/unittests/dist_transformer.py index fad6c62cc3313..af402adbcfa6f 100644 --- a/python/paddle/fluid/tests/unittests/dist_transformer.py +++ b/python/paddle/fluid/tests/unittests/dist_transformer.py @@ -28,7 +28,6 @@ import paddle.fluid as fluid import paddle.fluid.layers as layers import paddle.nn.functional as F -import paddle.static.nn.control_flow as control_flow const_para_attr = fluid.ParamAttr(initializer=fluid.initializer.Constant(0.001)) const_bias_attr = const_para_attr @@ -1814,7 +1813,9 @@ def beam_search(): shape=[-1, 1, 1], dtype=pre_ids.dtype, ), - y=control_flow.increment(x=step_idx, value=1.0, in_place=False), + y=paddle.static.nn.increment( + x=step_idx, value=1.0, in_place=False + ), axis=0, ) logits = wrap_decoder( @@ -1853,7 +1854,7 @@ def beam_search(): end_id=eos_idx, ) - control_flow.increment(x=step_idx, value=1.0, in_place=True) + paddle.static.nn.increment(x=step_idx, value=1.0, in_place=True) # update states layers.array_write(selected_ids, i=step_idx, array=ids) layers.array_write(selected_scores, i=step_idx, array=scores) diff --git a/python/paddle/fluid/tests/unittests/dygraph_to_static/test_loop.py b/python/paddle/fluid/tests/unittests/dygraph_to_static/test_loop.py index 9da4598425d07..1efb3669d26e9 100644 --- a/python/paddle/fluid/tests/unittests/dygraph_to_static/test_loop.py +++ b/python/paddle/fluid/tests/unittests/dygraph_to_static/test_loop.py @@ -19,9 +19,9 @@ import paddle import paddle.fluid as fluid -import paddle.static.nn.control_flow as control_flow from paddle.jit.api import declarative from paddle.jit.dy2static.loop_transformer import NameVisitor +from paddle.static.nn import increment from paddle.utils import gast SEED = 2020 @@ -84,7 +84,7 @@ def while_loop_dyfunc_with_none(x): def for_loop_dyfunc(max_len): for i in range(max_len): ret = fluid.layers.zeros(shape=[1], dtype='float32') - control_flow.increment(ret, value=2.0, in_place=True) + increment(ret, value=2.0, in_place=True) return ret @@ -105,14 +105,14 @@ def for_loop_dyfunc2(max_len): def for_loop_dyfunc3(max_len): ret = fluid.layers.zeros(shape=[1], dtype='float32') for i in range(1, 10, 2): - control_flow.increment(ret, value=2.0, in_place=True) + increment(ret, value=2.0, in_place=True) return ret def for_loop_dyfunc4(max_len): ret = fluid.layers.zeros(shape=[1], dtype='float32') for i in range(10, 1, -2): - control_flow.increment(ret, value=2.0, in_place=True) + increment(ret, value=2.0, in_place=True) return ret @@ -120,7 +120,7 @@ def for_loop_dyfunc_not_support(max_len): ret = fluid.layers.zeros(shape=[1], dtype='float32') a = -2 for i in range(10, 1, a): - control_flow.increment(ret, value=2.0, in_place=True) + increment(ret, value=2.0, in_place=True) return ret diff --git a/python/paddle/fluid/tests/unittests/npu/test_increment_op_npu.py b/python/paddle/fluid/tests/unittests/npu/test_increment_op_npu.py index 568f4d7a5a768..542ced34256ae 100644 --- a/python/paddle/fluid/tests/unittests/npu/test_increment_op_npu.py +++ b/python/paddle/fluid/tests/unittests/npu/test_increment_op_npu.py @@ -121,7 +121,7 @@ def test_npu(self): with paddle.static.program_guard(main_prog, startup_prog): a = paddle.static.data(name="a", shape=[1], dtype='float32') - b = paddle.static.nn.control_flow.increment(a) + b = paddle.static.nn.increment(a) place = paddle.NPUPlace(NPUPlace) diff --git a/python/paddle/fluid/tests/unittests/npu/test_while_op_npu.py b/python/paddle/fluid/tests/unittests/npu/test_while_op_npu.py index 043903b6e5d6e..74c5c64800caa 100644 --- a/python/paddle/fluid/tests/unittests/npu/test_while_op_npu.py +++ b/python/paddle/fluid/tests/unittests/npu/test_while_op_npu.py @@ -21,7 +21,7 @@ from paddle.fluid.backward import append_backward import numpy from paddle.fluid import compiler, Program, program_guard -import paddle.static.nn.control_flow as control_flow +from paddle.static.nn import increment paddle.enable_static() @@ -44,9 +44,9 @@ def simple_net(self): init = layers.zeros(shape=[10], dtype='float32') mem_array = layers.array_write(x=init, i=i) data_array = layers.array_write(x=d0, i=i) - i = control_flow.increment(i) + i = increment(i) layers.array_write(d1, i, array=data_array) - i = control_flow.increment(i) + i = increment(i) layers.array_write(d2, i, array=data_array) i = layers.zeros(shape=[1], dtype='int32') i = layers.cast(i, 'int64') @@ -72,7 +72,7 @@ def simple_net(self): prev = layers.array_read(array=mem_array, i=i) result = layers.sums(input=[d, prev]) - i = control_flow.increment(x=i, in_place=True) + i = increment(x=i, in_place=True) layers.array_write(result, i=i, array=mem_array) paddle.assign(paddle.less_than(x=i, y=array_len), cond) @@ -81,7 +81,7 @@ def simple_net(self): prev2 = layers.array_read(array=mem_array, i=j) result2 = layers.sums(input=[d2, prev2]) - j = control_flow.increment(x=j, in_place=True) + j = increment(x=j, in_place=True) layers.array_write(result2, i=j, array=mem_array) paddle.assign(paddle.less_than(x=j, y=array_len2), cond2) sum_result = layers.array_read(array=mem_array, i=j) diff --git a/python/paddle/fluid/tests/unittests/test_array_read_write_op.py b/python/paddle/fluid/tests/unittests/test_array_read_write_op.py index 3cb9e7b33dc1e..8f6f3bd58dd49 100644 --- a/python/paddle/fluid/tests/unittests/test_array_read_write_op.py +++ b/python/paddle/fluid/tests/unittests/test_array_read_write_op.py @@ -20,28 +20,28 @@ import paddle.fluid as fluid import paddle.fluid.core as core import paddle.fluid.layers as layers -import paddle.static.nn.control_flow as control_flow from paddle.fluid import Program, program_guard from paddle.fluid.backward import append_backward from paddle.fluid.executor import Executor from paddle.fluid.framework import default_main_program +from paddle.static.nn import increment def _test_read_write(x): i = layers.zeros(shape=[1], dtype='int64') i.stop_gradient = False arr = layers.array_write(x=x[0], i=i) - i = control_flow.increment(x=i) + i = increment(x=i) arr = layers.array_write(x=x[1], i=i, array=arr) - i = control_flow.increment(x=i) + i = increment(x=i) arr = layers.array_write(x=x[2], i=i, array=arr) i = layers.zeros(shape=[1], dtype='int64') i.stop_gradient = False a0 = layers.array_read(array=arr, i=i) - i = control_flow.increment(x=i) + i = increment(x=i) a1 = layers.array_read(array=arr, i=i) - i = control_flow.increment(x=i) + i = increment(x=i) a2 = layers.array_read(array=arr, i=i) mean_a0 = paddle.mean(a0) diff --git a/python/paddle/fluid/tests/unittests/test_async_ssa_graph_executor_mnist.py b/python/paddle/fluid/tests/unittests/test_async_ssa_graph_executor_mnist.py index 27fb3e36bb007..b3b666aa27af6 100644 --- a/python/paddle/fluid/tests/unittests/test_async_ssa_graph_executor_mnist.py +++ b/python/paddle/fluid/tests/unittests/test_async_ssa_graph_executor_mnist.py @@ -62,7 +62,7 @@ def convolutional_neural_network(use_py_reader): acc = paddle.static.accuracy(input=prediction, label=label) i = fluid.layers.zeros(shape=[1], dtype='int64') array = fluid.layers.array_write(x=prediction, i=i) - paddle.static.nn.control_flow.increment(i) + paddle.static.nn.increment(i) fluid.layers.array_write(x=acc, i=i, array=array) return array, img, label, prediction, avg_loss, acc, py_reader diff --git a/python/paddle/fluid/tests/unittests/test_dynamic_rnn_stop_gradient.py b/python/paddle/fluid/tests/unittests/test_dynamic_rnn_stop_gradient.py index f839563344a86..ded90600ed804 100644 --- a/python/paddle/fluid/tests/unittests/test_dynamic_rnn_stop_gradient.py +++ b/python/paddle/fluid/tests/unittests/test_dynamic_rnn_stop_gradient.py @@ -51,9 +51,7 @@ def build_and_run_program(place, batch_size, beam_size, stop_gradient=False): topk_coordinates = paddle.stack([batch_pos, indices], axis=2) topk_coordinates.stop_gradient = stop_gradient score = paddle.gather_nd(x, topk_coordinates) - paddle.static.nn.control_flow.increment( - x=step_idx, value=1.0, in_place=True - ) + paddle.static.nn.increment(x=step_idx, value=1.0, in_place=True) layers.array_write(score, i=step_idx, array=scores) length_cond = paddle.less_than(x=step_idx, y=max_len) layers.assign(length_cond, cond) diff --git a/python/paddle/fluid/tests/unittests/test_eager_deletion_while_op.py b/python/paddle/fluid/tests/unittests/test_eager_deletion_while_op.py index bebb534319cb3..2b38eb8f7c68a 100644 --- a/python/paddle/fluid/tests/unittests/test_eager_deletion_while_op.py +++ b/python/paddle/fluid/tests/unittests/test_eager_deletion_while_op.py @@ -26,8 +26,8 @@ import paddle.fluid.compiler as compiler import paddle.fluid.core as core import paddle.fluid.layers as layers -import paddle.static.nn.control_flow as control_flow from paddle.fluid.executor import Executor +from paddle.static.nn import increment paddle.enable_static() fluid.core._set_eager_deletion_mode(0.0, 1.0, True) @@ -84,10 +84,10 @@ def run_main(self, place, with_data_parallel): mem_array = layers.array_write(x=init, i=i) data_array = layers.array_write(x=d0, i=i) - i = control_flow.increment(i) + i = increment(i) layers.array_write(d1, i, array=data_array) - i = control_flow.increment(i) + i = increment(i) layers.array_write(d2, i, array=data_array) i = layers.zeros(shape=[1], dtype='int64') @@ -113,7 +113,7 @@ def run_main(self, place, with_data_parallel): prev = paddle.reshape(prev, shape=[10]) result = layers.sums(input=[d, prev]) - i = control_flow.increment(x=i, in_place=True) + i = increment(x=i, in_place=True) layers.array_write(result, i=i, array=mem_array) paddle.assign(paddle.less_than(x=i, y=array_len), cond) with while_op2.block(): @@ -123,7 +123,7 @@ def run_main(self, place, with_data_parallel): prev2 = paddle.reshape(prev2, shape=[10]) result2 = layers.sums(input=[d2, prev2]) - j = control_flow.increment(x=j, in_place=True) + j = increment(x=j, in_place=True) layers.array_write(result2, i=j, array=mem_array) paddle.assign(paddle.less_than(x=j, y=array_len2), cond2) diff --git a/python/paddle/fluid/tests/unittests/test_executor_and_mul.py b/python/paddle/fluid/tests/unittests/test_executor_and_mul.py index 912d5a8490bfe..265e612a13a98 100644 --- a/python/paddle/fluid/tests/unittests/test_executor_and_mul.py +++ b/python/paddle/fluid/tests/unittests/test_executor_and_mul.py @@ -16,9 +16,9 @@ import numpy as np -import paddle.static.nn.control_flow as control_flow from paddle.fluid.executor import Executor from paddle.fluid.layers import array_write, data, mul, zeros +from paddle.static.nn import increment class TestExecutor(unittest.TestCase): @@ -27,13 +27,13 @@ def test_mul(self): a = data(name='a', shape=[784], dtype='float32') array = array_write(x=a, i=i) - i = control_flow.increment(i) + i = increment(i) b = data( name='b', shape=[784, 100], dtype='float32', append_batch_size=False ) array_write(x=b, i=i, array=array) - i = control_flow.increment(i) + i = increment(i) out = mul(x=a, y=b) array_write(x=out, i=i, array=array) diff --git a/python/paddle/fluid/tests/unittests/test_fetch_lod_tensor_array.py b/python/paddle/fluid/tests/unittests/test_fetch_lod_tensor_array.py index 9a127edce18f1..8ca1a4d118fda 100644 --- a/python/paddle/fluid/tests/unittests/test_fetch_lod_tensor_array.py +++ b/python/paddle/fluid/tests/unittests/test_fetch_lod_tensor_array.py @@ -20,7 +20,7 @@ import paddle.fluid as fluid import paddle.fluid.layers as layers -import paddle.static.nn.control_flow as control_flow +from paddle.static.nn import increment class TestFetchLoDTensorArray(unittest.TestCase): @@ -36,9 +36,9 @@ def build_program(self, main_program, startup_program): opt.minimize(loss) array = layers.array_write(x=img, i=i) - i = control_flow.increment(i) + i = increment(i) layers.array_write(x=label, i=i, array=array) - i = control_flow.increment(i) + i = increment(i) layers.array_write(x=loss, i=i, array=array) return loss, array diff --git a/python/paddle/fluid/tests/unittests/test_profiler.py b/python/paddle/fluid/tests/unittests/test_profiler.py index 0f7459dd96893..629dc72e3ae2b 100644 --- a/python/paddle/fluid/tests/unittests/test_profiler.py +++ b/python/paddle/fluid/tests/unittests/test_profiler.py @@ -50,9 +50,7 @@ def build_program(self, compile_program=True): with while_op.block(): hidden_n = fluid.layers.fc(input=hidden1, size=64, act='relu') layers.array_write(hidden_n, i, data_arr) - paddle.static.nn.control_flow.increment( - x=counter, value=1, in_place=True - ) + paddle.static.nn.increment(x=counter, value=1, in_place=True) paddle.assign(paddle.less_than(x=counter, y=until), cond) hidden_n = layers.array_read(data_arr, i) diff --git a/python/paddle/fluid/tests/unittests/test_while_loop_op.py b/python/paddle/fluid/tests/unittests/test_while_loop_op.py index 19193fb348399..fbcc6b568f325 100644 --- a/python/paddle/fluid/tests/unittests/test_while_loop_op.py +++ b/python/paddle/fluid/tests/unittests/test_while_loop_op.py @@ -20,9 +20,9 @@ import paddle.fluid as fluid import paddle.fluid.core as core import paddle.fluid.layers as layers -import paddle.static.nn.control_flow as control_flow from paddle.fluid.backward import append_backward from paddle.fluid.framework import Program, program_guard +from paddle.static.nn import increment paddle.enable_static() @@ -60,7 +60,7 @@ def cond(i, mem): def body(i, mem): mem = paddle.add(x=mem, y=one) - i = control_flow.increment(i) + i = increment(i) return [i, mem] main_program = Program() @@ -101,7 +101,7 @@ def body(i, ten, test_dict, test_list, test_list_dict): test_list_dict[0]["test_key"] ) - i = control_flow.increment(i) + i = increment(i) return [i, ten, test_dict, test_list, test_list_dict] main_program = Program() @@ -169,7 +169,7 @@ def internal_cond(j, init, sums): def internal_body(j, init, sums): init = paddle.add(x=init, y=ones) sums = paddle.add(x=init, y=sums) - j = control_flow.increment(j) + j = increment(j) return [j, init, sums] result = layers.while_loop( @@ -179,7 +179,7 @@ def internal_body(j, init, sums): init = result[1] sums = result[2] sums = paddle.add(x=init, y=sums) - i = control_flow.increment(i) + i = increment(i) return [i, j, init, sums] main_program = Program() @@ -224,7 +224,7 @@ def cond(i, x): def body(i, x): x = paddle.multiply(x=i, y=i) - i = control_flow.increment(i) + i = increment(i) return [i, x] main_program = Program() @@ -319,7 +319,7 @@ def internal_body(j, x, mem_array): inner_prev = layers.array_read(array=mem_array, i=j) inner_sum_0 = paddle.add(x=inner_data, y=inner_prev) inner_sum_1 = paddle.add(x=x, y=inner_sum_0) - j = control_flow.increment(x=j, in_place=True) + j = increment(x=j, in_place=True) layers.array_write(inner_sum_1, i=j, array=mem_array) return [j, x, mem_array] @@ -327,7 +327,7 @@ def internal_body(j, x, mem_array): outer_prev = layers.array_read(array=mem_array, i=i) outer_sum_0 = paddle.add(x=outer_data, y=outer_prev) outer_sum_1 = paddle.add(x=x, y=outer_sum_0) - i = control_flow.increment(x=i, in_place=True) + i = increment(x=i, in_place=True) layers.array_write(outer_sum_1, i=i, array=mem_array) j, x, mem_array = layers.while_loop( internal_cond, internal_body, [j, x, mem_array] @@ -347,9 +347,9 @@ def internal_body(j, x, mem_array): init = layers.zeros(shape=[10], dtype='float32') mem_array = layers.array_write(x=init, i=i) data_array = layers.array_write(x=d0, i=i) - i = control_flow.increment(i) + i = increment(i) layers.array_write(d1, i, array=data_array) - i = control_flow.increment(i) + i = increment(i) layers.array_write(d2, i, array=data_array) i = layers.zeros(shape=[1], dtype='int64') i.stop_gradient = True @@ -439,7 +439,7 @@ def cond_returns_constant(i): return 1 def cond_returns_not_bool_tensor(i): - return control_flow.increment(i) + return increment(i) def cond_returns_bool_tensor(i): return paddle.less_than(i, ten) @@ -451,14 +451,14 @@ def cond_receives_two_args(i, ten): return paddle.less_than(i, ten) def body(i): - return control_flow.increment(i) + return increment(i) def body_returns_error_length(i): - i = control_flow.increment(i) + i = increment(i) return [i, i] def body_returns_error_type(i, ten): - return control_flow.increment(i) + return increment(i) def cond_returns_with_mutable_dict(i, test_dict): return i > 0 @@ -467,7 +467,7 @@ def body_returns_with_mutable_dict(i, test_dict): test_dict['new_key'] = layers.fill_constant( shape=[1], dtype='int64', value=1 ) - return control_flow.increment(i), test_dict + return increment(i), test_dict def cond_returns_with_mutable_list(i, test_list): return i > 0 @@ -476,7 +476,7 @@ def body_returns_with_mutable_list(i, test_list): test_list.append( layers.fill_constant(shape=[1], dtype='int64', value=1) ) - return control_flow.increment(i), test_list + return increment(i), test_list main_program = Program() startup_program = Program() diff --git a/python/paddle/fluid/tests/unittests/test_while_op.py b/python/paddle/fluid/tests/unittests/test_while_op.py index b277cb334480b..3ecdb84821ac9 100644 --- a/python/paddle/fluid/tests/unittests/test_while_op.py +++ b/python/paddle/fluid/tests/unittests/test_while_op.py @@ -20,9 +20,9 @@ import paddle.fluid as fluid import paddle.fluid.core as core import paddle.fluid.layers as layers -import paddle.static.nn.control_flow as control_flow from paddle.fluid.backward import append_backward from paddle.fluid.executor import Executor +from paddle.static.nn import increment paddle.enable_static() @@ -43,9 +43,9 @@ def simple_net(self): init = layers.zeros(shape=[10], dtype='float32') mem_array = layers.array_write(x=init, i=i) data_array = layers.array_write(x=d0, i=i) - i = control_flow.increment(i) + i = increment(i) layers.array_write(d1, i, array=data_array) - i = control_flow.increment(i) + i = increment(i) layers.array_write(d2, i, array=data_array) i = layers.zeros(shape=[1], dtype='int64') i.stop_gradient = True @@ -64,7 +64,7 @@ def simple_net(self): prev = layers.array_read(array=mem_array, i=i) result = layers.sums(input=[d, prev]) - i = control_flow.increment(x=i, in_place=True) + i = increment(x=i, in_place=True) layers.array_write(result, i=i, array=mem_array) paddle.assign(paddle.less_than(x=i, y=array_len), cond) @@ -73,7 +73,7 @@ def simple_net(self): prev2 = layers.array_read(array=mem_array, i=j) result2 = layers.sums(input=[d2, prev2]) - j = control_flow.increment(x=j, in_place=True) + j = increment(x=j, in_place=True) layers.array_write(result2, i=j, array=mem_array) paddle.assign(paddle.less_than(x=j, y=array_len2), cond2) sum_result = layers.array_read(array=mem_array, i=j) @@ -135,7 +135,7 @@ def test_error(self): def test_bad_x(): x = [1, 2, 3] - control_flow.increment(x) + increment(x) self.assertRaises(TypeError, test_bad_x) diff --git a/python/paddle/fluid/tests/unittests/xpu/test_while_op_xpu.py b/python/paddle/fluid/tests/unittests/xpu/test_while_op_xpu.py index 33056f8c9b832..a869573160beb 100644 --- a/python/paddle/fluid/tests/unittests/xpu/test_while_op_xpu.py +++ b/python/paddle/fluid/tests/unittests/xpu/test_while_op_xpu.py @@ -19,9 +19,9 @@ import paddle import paddle.fluid as fluid import paddle.fluid.layers as layers -import paddle.static.nn.control_flow as control_flow from paddle.fluid.backward import append_backward from paddle.fluid.executor import Executor +from paddle.static.nn import increment paddle.enable_static() @@ -42,9 +42,9 @@ def simple_net(self): init = layers.zeros(shape=[10], dtype='float32') mem_array = layers.array_write(x=init, i=i) data_array = layers.array_write(x=d0, i=i) - i = control_flow.increment(i) + i = increment(i) layers.array_write(d1, i, array=data_array) - i = control_flow.increment(i) + i = increment(i) layers.array_write(d2, i, array=data_array) i = layers.zeros(shape=[1], dtype='int64') i.stop_gradient = True @@ -63,7 +63,7 @@ def simple_net(self): prev = layers.array_read(array=mem_array, i=i) result = layers.sums(input=[d, prev]) - i = control_flow.increment(x=i, in_place=True) + i = increment(x=i, in_place=True) layers.array_write(result, i=i, array=mem_array) paddle.assign(paddle.less_than(x=i, y=array_len), cond) @@ -72,7 +72,7 @@ def simple_net(self): prev2 = layers.array_read(array=mem_array, i=j) result2 = layers.sums(input=[d2, prev2]) - j = control_flow.increment(x=j, in_place=True) + j = increment(x=j, in_place=True) layers.array_write(result2, i=j, array=mem_array) paddle.assign(paddle.less_than(x=j, y=array_len2), cond2) sum_result = layers.array_read(array=mem_array, i=j) diff --git a/python/paddle/jit/dy2static/convert_operators.py b/python/paddle/jit/dy2static/convert_operators.py index a5d2ca14cd9b6..6db2bdafb4bf7 100644 --- a/python/paddle/jit/dy2static/convert_operators.py +++ b/python/paddle/jit/dy2static/convert_operators.py @@ -784,7 +784,8 @@ def cond(i, new_array): def body(i, new_array): item = array_read(array=array, i=i) array_write(item, paddle.tensor.array_length(new_array), new_array) - from paddle.static.nn.control_flow import increment + + from paddle.static.nn import increment i = increment(i) return i, new_array diff --git a/python/paddle/static/nn/__init__.py b/python/paddle/static/nn/__init__.py index 9635811f6a818..b005c6f556097 100755 --- a/python/paddle/static/nn/__init__.py +++ b/python/paddle/static/nn/__init__.py @@ -33,6 +33,7 @@ from ...fluid.layers import multi_box_head # noqa: F401 from .loss import nce # noqa: F401 from .common import prelu # noqa: F401 +from .control_flow import Assert, increment # noqa: F401 from ...fluid.layers import row_conv # noqa: F401 from ...fluid.layers import spectral_norm # noqa: F401 from ...fluid.layers import switch_case # noqa: F401 @@ -100,4 +101,6 @@ 'sequence_reverse', 'StaticRNN', 'prelu', + 'Assert', + 'increment', ] From 1823bcf2352539136b168284cb851e8dea547366 Mon Sep 17 00:00:00 2001 From: wuzhanfei Date: Tue, 6 Dec 2022 12:37:24 +0000 Subject: [PATCH 05/16] fixed import statments --- .../collective/fleet/hybrid_parallel_inference_helper.py | 2 +- python/paddle/fluid/tests/unittests/test_assert_op.py | 2 +- python/paddle/jit/dy2static/convert_operators.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/python/paddle/fluid/tests/unittests/collective/fleet/hybrid_parallel_inference_helper.py b/python/paddle/fluid/tests/unittests/collective/fleet/hybrid_parallel_inference_helper.py index c903359f68239..1edb4bdfccbd8 100644 --- a/python/paddle/fluid/tests/unittests/collective/fleet/hybrid_parallel_inference_helper.py +++ b/python/paddle/fluid/tests/unittests/collective/fleet/hybrid_parallel_inference_helper.py @@ -89,7 +89,7 @@ def test_hybrid_parallel_inference_helper_mp1pp2(self): with while_op.block(): with paddle.fluid.device_guard(f'{device}:all'): input = layers.array_read(array=data, i=step_idx) - paddle.static.nn.control_flow.increment( + paddle.static.nn.increment( x=step_idx, value=1.0, in_place=True ) layers.array_write(input, i=step_idx, array=data) diff --git a/python/paddle/fluid/tests/unittests/test_assert_op.py b/python/paddle/fluid/tests/unittests/test_assert_op.py index f62ad38d459d1..a6ce260fb9435 100644 --- a/python/paddle/fluid/tests/unittests/test_assert_op.py +++ b/python/paddle/fluid/tests/unittests/test_assert_op.py @@ -17,7 +17,7 @@ import paddle import paddle.fluid as fluid import paddle.fluid.layers as layers -from paddle.static.nn.control_flow import Assert +from paddle.static.nn import Assert class TestAssertOp(unittest.TestCase): diff --git a/python/paddle/jit/dy2static/convert_operators.py b/python/paddle/jit/dy2static/convert_operators.py index 6db2bdafb4bf7..8d99b534cb721 100644 --- a/python/paddle/jit/dy2static/convert_operators.py +++ b/python/paddle/jit/dy2static/convert_operators.py @@ -730,7 +730,7 @@ def convert_assert(cond, message=""): if isinstance(cond, Variable): cond = cast(cond, "bool") # NOTE: message is not used because Paddle Assert has no corresponding parameter to use. - from paddle.static.nn.control_flow import Assert + from paddle.static.nn import Assert return Assert(cond) else: From 39287d774ab74d4f2c99fce3caf4189b41c98869 Mon Sep 17 00:00:00 2001 From: wuzhanfei Date: Wed, 7 Dec 2022 03:00:02 +0000 Subject: [PATCH 06/16] fix static err --- python/paddle/static/nn/control_flow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/paddle/static/nn/control_flow.py b/python/paddle/static/nn/control_flow.py index 1eecde1cb6c86..edf90babea525 100644 --- a/python/paddle/static/nn/control_flow.py +++ b/python/paddle/static/nn/control_flow.py @@ -58,7 +58,7 @@ def Assert(cond, data=None, summarize=20, name=None): import paddle from paddle.static.nn.control_flow import Assert - x = paddle.full(shape=[2, 3], dtype='float32', value=2.0) + x = paddle.full([2, 3], 2.0, 'float32') condition = paddle.max(x) < 1.0 # False Assert(condition, [x], 10, "example_assert_layer") From 75e1b0ea26a390017ee930eb5282479c1cf268d1 Mon Sep 17 00:00:00 2001 From: wuzhanfei Date: Wed, 7 Dec 2022 06:09:30 +0000 Subject: [PATCH 07/16] migrate cond api --- .../passes/auto_parallel_gradient_merge.py | 2 +- .../contrib/slim/quantization/adaround.py | 2 +- python/paddle/fluid/layers/control_flow.py | 501 +----------------- python/paddle/fluid/optimizer.py | 2 +- .../dygraph_to_static/ifelse_simple_func.py | 2 +- .../unittests/dygraph_to_static/test_dict.py | 2 +- .../dygraph_to_static/test_ifelse.py | 4 +- .../dygraph_to_static/test_warning.py | 2 +- .../ir/test_ir_subgraph_python_interface.py | 2 +- .../test_standalone_controlflow.py | 2 +- .../paddle/fluid/tests/unittests/test_cond.py | 58 +- .../fluid/tests/unittests/test_desc_clone.py | 4 +- .../fluid/tests/unittests/test_layers.py | 18 +- .../tests/unittests/test_math_op_patch.py | 2 +- .../tests/unittests/test_optimizer_grad.py | 2 +- .../tests/unittests/test_program_code.py | 2 +- python/paddle/fluid/variable_index.py | 4 +- python/paddle/static/nn/__init__.py | 9 +- python/paddle/static/nn/control_flow.py | 478 ++++++++++++++++- 19 files changed, 557 insertions(+), 541 deletions(-) diff --git a/python/paddle/distributed/passes/auto_parallel_gradient_merge.py b/python/paddle/distributed/passes/auto_parallel_gradient_merge.py index 8ac3492c2b14d..592db6767c0fa 100644 --- a/python/paddle/distributed/passes/auto_parallel_gradient_merge.py +++ b/python/paddle/distributed/passes/auto_parallel_gradient_merge.py @@ -286,7 +286,7 @@ def true_apply_gradient(): ) new_grad.op._set_attr(OP_ROLE_KEY, op_maker.OpRole.Optimize) - layers.cond(cond_var, true_fn=true_apply_gradient, false_fn=None) + paddle.static.nn.cond(cond_var, true_fn=true_apply_gradient, false_fn=None) cond_op = main_program.global_block().ops[-1] cond_op._set_attr(OP_ROLE_KEY, OpRole.Optimize) diff --git a/python/paddle/fluid/contrib/slim/quantization/adaround.py b/python/paddle/fluid/contrib/slim/quantization/adaround.py index b024c0d773996..f4bbccd7f1d86 100644 --- a/python/paddle/fluid/contrib/slim/quantization/adaround.py +++ b/python/paddle/fluid/contrib/slim/quantization/adaround.py @@ -83,7 +83,7 @@ def round_loss_fn(): return round_loss - round_loss = fluid.layers.cond( + round_loss = paddle.static.nn.cond( warm_start, lambda: fluid.layers.fill_constant( shape=[1], dtype='float32', value=0.0 diff --git a/python/paddle/fluid/layers/control_flow.py b/python/paddle/fluid/layers/control_flow.py index ef448f357b87a..0d7770773a0d8 100755 --- a/python/paddle/fluid/layers/control_flow.py +++ b/python/paddle/fluid/layers/control_flow.py @@ -56,7 +56,6 @@ 'Switch', 'array_write', 'array_read', - 'cond', 'IfElse', 'StaticRNN', 'reorder_lod_tensor_by_rank', @@ -97,26 +96,6 @@ def select_output(input, outputs, mask): return outputs -def _select_input_infer_shape(first_shape, second_shape): - """ - This function infer the output shape by following algorithm: - 1. if the dims is different, raise a error. - 2. compare axis one by one: - if a == b: we set axis to a - if a != b: we set axis to -1 - for compatibility,non declarative mode, we just return second_shape. - """ - if len(first_shape) != len(second_shape): - warnings.warn( - f"the input shapes of select_input should have the same rank, but get {first_shape}, {second_shape}" - ) - return second_shape - out_shape = list( - map(lambda a, b: a if a == b else -1, first_shape, second_shape) - ) - return out_shape - - def select_input(inputs, mask): """ **select_input** @@ -138,6 +117,25 @@ def select_input(inputs, mask): # Select input should expand the shape. If it is - 1 and valid number, use - 1 first. If the dim is different, an error will be reported directly # assert inputs[0].dtype == inputs[1].dtype, f"Expect the inputs should have the same dtype, but get {inputs[0].dtype} and {inputs[1].dtype}" + def _select_input_infer_shape(first_shape, second_shape): + """ + This function infer the output shape by following algorithm: + 1. if the dims is different, raise a error. + 2. compare axis one by one: + if a == b: we set axis to a + if a != b: we set axis to -1 + for compatibility,non declarative mode, we just return second_shape. + """ + if len(first_shape) != len(second_shape): + warnings.warn( + f"the input shapes of select_input should have the same rank, but get {first_shape}, {second_shape}" + ) + return second_shape + out_shape = list( + map(lambda a, b: a if a == b else -1, first_shape, second_shape) + ) + return out_shape + output_shape = _select_input_infer_shape(inputs[0].shape, inputs[1].shape) output_dtype = inputs[1].dtype output_type = inputs[1].type @@ -153,84 +151,6 @@ def select_input(inputs, mask): return out -def select_input_with_buildin_type(inputs, mask, name): - from paddle.jit.dy2static.variable_trans_func import ( - to_static_variable, - ) - from paddle.jit.dy2static.utils import UndefinedVar - - false_var, true_var = inputs - - if isinstance(false_var, UndefinedVar) and isinstance( - true_var, UndefinedVar - ): - """None -> UndefinedVar, so the real value is a [None, UndefinedVar] or [None, None], we just return None.""" - return None - - if isinstance(false_var, Variable) and isinstance(true_var, Variable): - try: - return select_input(inputs, mask) - except Exception as e: - raise RuntimeError( - f"Exceptions throwed while doing select_input on {name}:\n{e}" - ) - - elif isinstance(false_var, support_ret_buildin_type) and isinstance( - false_var, type(true_var) - ): - if false_var == true_var: - return false_var - else: - inputs = [ - to_static_variable(false_var), - to_static_variable(true_var), - ] - # Deal with the situations like this: false_var is int and true_var is Variable - elif ( - isinstance(false_var, support_ret_buildin_type) - and isinstance(true_var, Variable) - ) or ( - isinstance(true_var, support_ret_buildin_type) - and isinstance(false_var, Variable) - ): - inputs = [to_static_variable(false_var), to_static_variable(true_var)] - warnings.warn( - "Return results from different branches in cond are not same type: " - "false_var returned by false_fn is '{}' and true_var of true_fn is " - "'{}'".format(type(false_var), type(true_var)) - ) - elif ( - isinstance(false_var, UndefinedVar) - and isinstance(true_var, (Variable,) + support_ret_buildin_type) - ) or ( - isinstance(true_var, UndefinedVar) - and isinstance(false_var, (Variable,) + support_ret_buildin_type) - ): - - def create_var_if_not_undefined_var(a): - if isinstance(a, UndefinedVar): - return a - return to_static_variable(a) - - true_var, false_var = to_static_variable(true_var), to_static_variable( - false_var - ) - inputs = [false_var, true_var] - else: - raise TypeError( - "Unsupported return type of true_fn and false_fn in cond: false_var " - "returned by false_fn is '{}' and true_var of true_fn is '{}'".format( - type(false_var), type(true_var) - ) - ) - try: - return select_input(inputs, mask) - except Exception as e: - raise RuntimeError( - f"Exceptions throwed while doing select_input on {name}:\n{e}" - ) - - def split_lod_tensor(input, mask, level=0): """ This function takes in an input that contains the complete lod information, @@ -1915,315 +1835,6 @@ def append_conditional_block_grad( self.helper.main_program._sync_with_cpp() -def copy_var_to_parent_block(var, layer_helper): - if not isinstance(var, Variable): - return var - prog = layer_helper.main_program - parent_idx = prog.current_block().parent_idx - assert ( - parent_idx >= 0 - ), "Got wrong parent block index when assigning var to parent scope in control_flow" - parent_block = prog.block(parent_idx) - - if ( - var.type == core.VarDesc.VarType.LOD_TENSOR_ARRAY - and parent_block._find_var_recursive(var.name) - ): - parent_block_var = var - else: - parent_block_var = parent_block.create_var( - dtype=var.dtype, shape=var.shape, type=var.type - ) - assign(var, parent_block_var) - return parent_block_var - - -def cond(pred, true_fn=None, false_fn=None, name=None, return_names=None): - """ - This API returns ``true_fn()`` if the predicate ``pred`` is true else - ``false_fn()`` . Users could also set ``true_fn`` or ``false_fn`` to - ``None`` if do nothing and this API will treat the callable simply returns - ``None`` in this case. - - ``true_fn`` and ``false_fn`` should return same nest structure of tensors - or both return ``None`` if user doens't like to return anything. A nest - structure of tensors in PaddlePaddle is tensor(s), or tuple of tensors, or - list of tensors. - - Note: - 1. The tuples or lists returned by ``true_fn`` and ``false_fn`` must have - the same shape because of dataflow model of PaddlePaddle while the - tensors in the tuples or the lists can have different shapes. - - 2. This API could be used under both static mode or dygraph mode. If it - is in dygraph mode, the API only runs one branch based on condition. - - 3. If it is in static mode, any tensors or operations created outside - or inside of ``true_fn`` and ``false_fn`` will be in net building - regardless of which branch is selected at runtime. This has frequently - surprised users who expected a lazy semantics. For example: - - .. code-block:: python - - import paddle - - a = paddle.zeros((1, 1)) - b = paddle.zeros((1, 1)) - c = a * b - out = paddle.static.nn.cond(a < b, lambda: a + c, lambda: b * b) - - No matter whether ``a < b`` , ``c = a * b`` will be in net building and - run. ``a + c`` and ``b * b`` will be in net building, but only one - branch will be executed during runtime. - - Args: - pred(Tensor): A boolean tensor whose numel should be 1. The boolean - value determines whether to return the result of ``true_fn`` or - ``false_fn`` . - true_fn(callable, optional): A callable to be performed if ``pred`` is - true. The default value is ``None`` . - false_fn(callable, optional): A callable to be performed if ``pred`` is - false. The default value is ``None`` . - name(str, optional): The default value is ``None`` . Normally users - don't have to set this parameter. For more information, please - refer to :ref:`api_guide_Name` . - return_names(sequence of string, optional): The default value is ``None`` . - Normally users don't have to set this parameters. A sequence of strings - to represents the name of returned vars. The structure of sequence must - be same with return values of true_fn and false_fn. - - Returns: - Tensor|list(Tensor)|tuple(Tensor): returns ``true_fn()`` if the - predicate ``pred`` is true else ``false_fn()`` . - - Raises: - TypeError: if ``true_fn`` or ``false_fn`` is not callable. - ValueError: if ``true_fn`` and ``false_fn`` don't return the same nest - structure of tensors. - - Examples: - .. code-block:: python - - import paddle - - # - # pseudocode: - # if 0.1 < 0.23: - # return 1, True - # else: - # return 3, 2 - # - - def true_func(): - return paddle.full(shape=[1, 2], dtype='int32', - fill_value=1), paddle.full(shape=[2, 3], - dtype='bool', - fill_value=True) - - - def false_func(): - return paddle.full(shape=[3, 4], dtype='float32', - fill_value=3), paddle.full(shape=[4, 5], - dtype='int64', - fill_value=2) - - - x = paddle.full(shape=[1], dtype='float32', fill_value=0.1) - y = paddle.full(shape=[1], dtype='float32', fill_value=0.23) - pred = paddle.less_than(x=x, y=y, name=None) - ret = paddle.static.nn.cond(pred, true_func, false_func) - # ret is a tuple containing 2 tensors - # ret[0] = [[1 1]] - # ret[1] = [[ True True True] - # [ True True True]] - - """ - if _non_static_mode(): - assert isinstance(pred, Variable), "The pred in cond must be Variable" - assert pred.size == 1, "condition input's numel should be 1" - pred = pred.numpy()[0] - if pred: - if true_fn is not None: - if not callable(true_fn): - raise TypeError( - "The true_fn in cond must be callable, but received {}".format( - type(true_fn).__name__ - ) - ) - return true_fn() - else: - if false_fn is not None: - if not callable(false_fn): - raise TypeError( - "The false_fn in cond must be callable, but received {}".format( - type(false_fn).__name__ - ) - ) - return false_fn() - return None - - check_variable_and_dtype(pred, "pred", ['bool'], "fluid.layers.cond") - check_type(name, "name", (str, type(None)), "fluid.layers.cond") - helper = LayerHelper('cond', **locals()) - true_output = None - false_output = None - copy_to_parent_func = lambda var: copy_var_to_parent_block(var, helper) - if true_fn is not None: - if not callable(true_fn): - raise TypeError( - "The true_fn in cond must be callable, but received {}".format( - type(true_fn).__name__ - ) - ) - true_cond_block = ConditionalBlock([pred], is_scalar_condition=True) - with true_cond_block.block(): - origin_true_output = true_fn() - if origin_true_output is not None: - true_output = map_structure( - copy_to_parent_func, origin_true_output - ) - if false_fn is not None: - if not callable(false_fn): - raise TypeError( - "The false_fn in cond must be callable, but received {}".format( - type(false_fn).__name__ - ) - ) - false_cond_block = ConditionalBlock( - [paddle.logical_not(pred)], is_scalar_condition=True - ) - with false_cond_block.block(): - origin_false_output = false_fn() - if origin_false_output is not None: - false_output = map_structure( - copy_to_parent_func, origin_false_output - ) - - if true_output is None and false_output is None: - return None - - if true_output is None: - raise ValueError( - "Incompatible return values of true_fn and false_fn in cond: " - "true_fn returns None while false_fn returns non-None" - ) - if false_output is None: - raise ValueError( - "Incompatible return values of true_fn and false_fn in cond: " - "true_fn returns non-None while false_fn returns None" - ) - - # Merge true and false output if they are not None - if return_names is None: - is_dy2staic = False - return_names = ["no name"] * len(_to_sequence_except_dict(true_output)) - else: - """ - dy2static will set the return_names and expand the return values to UndefinedVar. - """ - is_dy2staic = True - - # TODO: expand_undefined_var will replace None to Undefinedvar(), to fix cases like: - # a = None - # if condition: - # a = 1 - # Because we can not use variable to express 'None' - true_output, false_output = expand_undefined_var( - true_output, false_output, return_names - ) - - if len(_to_sequence_except_dict(true_output)) != len( - _to_sequence_except_dict(false_output) - ): - raise ValueError( - "true fn returns {} vars, but false fn returns {} vars, which is not equals".format( - len(_to_sequence_except_dict(true_output)), - len(_to_sequence_except_dict(false_output)), - ) - ) - for true_out, false_out, return_name in zip( - _to_sequence_except_dict(true_output), - _to_sequence_except_dict(false_output), - _to_sequence_except_dict(return_names), - ): - try: - assert_same_structure(true_out, false_out, check_types=False) - except ValueError as e: - raise ValueError( - "Incompatible return values of `{}` in true_fn and false_fn in cond: {}".format( - return_name, e - ) - ) - - def check_ret_none(seq_true, seq_false, seq_names): - for f_true, f_false, f_name in zip(seq_true, seq_false, seq_names): - f_true = flatten(f_true) - f_false = flatten(f_false) - for idx in range(len(f_true)): - if ( - f_true[idx] is None - and f_false[idx] is not None - or f_false[idx] is None - and f_true[idx] is not None - ): - warnings.warn( - "In cond : Var '{}' or part of it is set differently in ifelse branchs, " - "<{}, {}> in true branch and <{}, {}> in false branch. Set var to " - "'None' in ifelse block might lead to error.".format( - f_name, - type(f_true[idx]), - f_true[idx], - type(f_false[idx]), - f_false[idx], - ) - ) - - check_ret_none( - _to_sequence_except_dict(true_output), - _to_sequence_except_dict(false_output), - _to_sequence_except_dict(return_names), - ) - - if is_dy2staic: - true_output, false_output = change_none_to_undefinedvar( - true_output, false_output - ) - - mask = cast(pred, dtype='int32') - merge_func = ( - lambda name, false_var, true_var: select_input_with_buildin_type( - [false_var, true_var], mask, name - ) - ) - - def merge_every_var_list(false_vars, true_vars, name): - return map_structure(partial(merge_func, name), false_vars, true_vars) - - merged_output = list( - map( - merge_every_var_list, - _to_sequence_except_dict(false_output), - _to_sequence_except_dict(true_output), - _to_sequence_except_dict(return_names), - ) - ) - merged_output = pack_sequence_as(false_output, flatten(merged_output)) - return merged_output - - -def change_none_to_undefinedvar(nest1, nest2): - from paddle.jit.dy2static.utils import UndefinedVar - - def map_fn(x): - if x is None: - return UndefinedVar("padding") - return x - - nest1_out = pack_sequence_as(nest1, list(map(map_fn, flatten(nest1)))) - nest2_out = pack_sequence_as(nest2, list(map(map_fn, flatten(nest2)))) - return nest1_out, nest2_out - - def _to_sequence_except_dict(x): """ In this function, dict is not viewed as sequence. @@ -2233,80 +1844,6 @@ def _to_sequence_except_dict(x): return to_sequence(x) -def _is_sequence_except_dict(x): - """ - In this function, dict is not viewed as sequence. - """ - if isinstance(x, dict): - return False - return is_sequence(x) - - -def expand_undefined_var(nest1, nest2, names): - """TODO: make this function recursively. - nest1: Var1, (UndefinedVar, [1,2,3]) - nest2: Var2, ([1,2,3,4], UndefinedVar) - In this case, we should not expand recursively. - """ - from paddle.jit.dy2static.utils import UndefinedVar - from paddle.jit.dy2static.return_transformer import ( - RETURN_VALUE_PREFIX, - ) - - def pack_undefined_var_as(seq): - return pack_sequence_as( - seq, [UndefinedVar("padding") for i in flatten(seq)] - ) - - def map_fn(n1, n2, name, order): - if not name.startswith(RETURN_VALUE_PREFIX) and ( - isinstance(n1, UndefinedVar) or n1 is None - ): - if n1 is None and n2 is not None: - if order == 0: - warnings.warn( - "In cond : Var '{}' or part of it is set differently in ifelse branchs, " - "<{}, {}> in true branch and <{}, {}> in false branch. Set var to " - "'None' in ifelse block might lead to error.".format( - name, type(n1), n1, type(n2), n2 - ) - ) - else: - warnings.warn( - "In cond : Var '{}' or part of it is set differently in ifelse branchs, " - "<{}, {}> in true branch and <{}, {}> in false branch. Set var to " - "'None' in ifelse block might lead to error.".format( - name, type(n2), n2, type(n1), n1 - ) - ) - return pack_undefined_var_as(n2) - return n1 - - nest1_out = list( - map( - map_fn, - _to_sequence_except_dict(nest1), - _to_sequence_except_dict(nest2), - _to_sequence_except_dict(names), - [0 for i in _to_sequence_except_dict(names)], - ) - ) - nest2_out = list( - map( - map_fn, - _to_sequence_except_dict(nest2), - _to_sequence_except_dict(nest1), - _to_sequence_except_dict(names), - [1 for i in _to_sequence_except_dict(names)], - ) - ) - if not _is_sequence_except_dict(nest1): - nest1_out = nest1_out[0] - if not _is_sequence_except_dict(nest2): - nest2_out = nest2_out[0] - return nest1_out, nest2_out - - def _error_message(what, arg_name, op_name, right_value, error_value): error_message = ( "{what} of '{arg_name}' in {op_name} must be " diff --git a/python/paddle/fluid/optimizer.py b/python/paddle/fluid/optimizer.py index d49fe0c70159d..444658ac35aa0 100755 --- a/python/paddle/fluid/optimizer.py +++ b/python/paddle/fluid/optimizer.py @@ -7647,7 +7647,7 @@ def true_apply_gradient(): ) # step3. apply gradient - layers.cond(cond, true_fn=true_apply_gradient, false_fn=None) + paddle.static.nn.cond(cond, true_fn=true_apply_gradient, false_fn=None) return self._optimize_ops diff --git a/python/paddle/fluid/tests/unittests/dygraph_to_static/ifelse_simple_func.py b/python/paddle/fluid/tests/unittests/dygraph_to_static/ifelse_simple_func.py index 985d091d6b9c4..a4584e6ad5a0d 100644 --- a/python/paddle/fluid/tests/unittests/dygraph_to_static/ifelse_simple_func.py +++ b/python/paddle/fluid/tests/unittests/dygraph_to_static/ifelse_simple_func.py @@ -85,7 +85,7 @@ def false_fn_0(q, x, y): m = x + 2 n = x + 3 return q, x, y, z - q, x, y, z = fluid.layers.cond(paddle.mean(x)[0] < 5, lambda : + q, x, y, z = paddle.static.nn.cond(paddle.mean(x)[0] < 5, lambda : paddle.jit.dy2static.convert_call(true_fn_0)(q, x, y), lambda : paddle.jit.dy2static.convert_call(false_fn_0)(q, x, y)) diff --git a/python/paddle/fluid/tests/unittests/dygraph_to_static/test_dict.py b/python/paddle/fluid/tests/unittests/dygraph_to_static/test_dict.py index 597580eedc765..3c60ef52bb87f 100644 --- a/python/paddle/fluid/tests/unittests/dygraph_to_static/test_dict.py +++ b/python/paddle/fluid/tests/unittests/dygraph_to_static/test_dict.py @@ -97,7 +97,7 @@ def forward(self, input, max_len=4): ), } # TODO(Aurelius84): The following code will be converted into: - # max_len = layers.cond(paddle.shape(input)[0] != max_len, + # max_len = paddle.static.nn.cond(paddle.shape(input)[0] != max_len, # lambda: paddle.shape(input)[0], lambda: max_len) # But max_len should be wrapped into tensor, which is not supported. diff --git a/python/paddle/fluid/tests/unittests/dygraph_to_static/test_ifelse.py b/python/paddle/fluid/tests/unittests/dygraph_to_static/test_ifelse.py index 8cc543a19f94d..72c648e675b3f 100644 --- a/python/paddle/fluid/tests/unittests/dygraph_to_static/test_ifelse.py +++ b/python/paddle/fluid/tests/unittests/dygraph_to_static/test_ifelse.py @@ -154,7 +154,7 @@ def map_func(func, tensor_list): def body(i, ten, y): # It will be converted into `layers.cond` as followed. - # map_func(lambda x: fluid.layers.cond(i==0, lambda: x, lambda: add_fn(x), y) + # map_func(lambda x: paddle.static.nn.cond(i==0, lambda: x, lambda: add_fn(x), y) y = map_func(lambda x: x if (i == 0) is not None else add_fn(x), y) i += 1 return [i, ten, y] @@ -183,7 +183,7 @@ def map_func(func, tensor_list): i = fluid.layers.fill_constant(shape=[1], dtype='int64', value=0) # It will be converted into `layers.cond` as followed. - # map_func(lambda x: fluid.layers.cond(i==1, lambda: x, lambda: add_fn(x), y) + # map_func(lambda x: paddle.static.nn.cond(i==1, lambda: x, lambda: add_fn(x), y) # `if (Tensor) == 1` is supported in dygraph. y = map_func(lambda x: x if i == 1 else add_fn(x), y) return y[0] diff --git a/python/paddle/fluid/tests/unittests/dygraph_to_static/test_warning.py b/python/paddle/fluid/tests/unittests/dygraph_to_static/test_warning.py index e74e06f8f9b68..3ba8caea85099 100644 --- a/python/paddle/fluid/tests/unittests/dygraph_to_static/test_warning.py +++ b/python/paddle/fluid/tests/unittests/dygraph_to_static/test_warning.py @@ -16,7 +16,7 @@ import warnings import paddle -from paddle.fluid.layers.control_flow import cond +from paddle.static.nn import cond @paddle.jit.to_static diff --git a/python/paddle/fluid/tests/unittests/ir/test_ir_subgraph_python_interface.py b/python/paddle/fluid/tests/unittests/ir/test_ir_subgraph_python_interface.py index 2a7ebae071073..33efd9b7c54c2 100644 --- a/python/paddle/fluid/tests/unittests/ir/test_ir_subgraph_python_interface.py +++ b/python/paddle/fluid/tests/unittests/ir/test_ir_subgraph_python_interface.py @@ -52,7 +52,7 @@ def false_func(): x = layers.fill_constant(shape=[1], dtype='float32', value=0.1) y = layers.fill_constant(shape=[1], dtype='float32', value=0.23) pred = paddle.less_than(y, x) - out = layers.cond(pred, true_func, false_func) + out = paddle.static.nn.cond(pred, true_func, false_func) core_graph = core.Graph(main_program.desc) # We should create graph for test, otherwise it will throw a diff --git a/python/paddle/fluid/tests/unittests/standalone_executor/test_standalone_controlflow.py b/python/paddle/fluid/tests/unittests/standalone_executor/test_standalone_controlflow.py index c989ff866e8c0..000f1b7d4b856 100644 --- a/python/paddle/fluid/tests/unittests/standalone_executor/test_standalone_controlflow.py +++ b/python/paddle/fluid/tests/unittests/standalone_executor/test_standalone_controlflow.py @@ -57,7 +57,7 @@ def false_func(): x = layers.fill_constant(shape=[1], dtype='float32', value=0.1) y = layers.fill_constant(shape=[1], dtype='float32', value=0.23) pred = paddle.less_than(x, y) - out = layers.cond(pred, true_func, false_func) + out = paddle.static.nn.cond(pred, true_func, false_func) # out is a tuple containing 2 tensors return main_program, startup_program, out diff --git a/python/paddle/fluid/tests/unittests/test_cond.py b/python/paddle/fluid/tests/unittests/test_cond.py index bc5a73d048dfa..c96cece765b24 100644 --- a/python/paddle/fluid/tests/unittests/test_cond.py +++ b/python/paddle/fluid/tests/unittests/test_cond.py @@ -54,7 +54,7 @@ def false_func(): x = layers.fill_constant(shape=[1], dtype='float32', value=0.1) y = layers.fill_constant(shape=[1], dtype='float32', value=0.23) pred = paddle.less_than(y, x) - out = layers.cond(pred, true_func, false_func) + out = paddle.static.nn.cond(pred, true_func, false_func) # out is one tensor place = ( @@ -94,7 +94,7 @@ def false_func(): startup_program = Program() with program_guard(main_program, startup_program): pred = layers.fill_constant(shape=[1], dtype='bool', value=True) - out = layers.cond(pred, true_func, false_func) + out = paddle.static.nn.cond(pred, true_func, false_func) # out is a tuple containing 2 tensors place = ( @@ -138,7 +138,7 @@ def false_func(a, i): a = layers.fill_constant(shape=[3, 2, 1], dtype='int32', value=7) i = fluid.data(name="i", shape=[1], dtype='int32') pred = (i % 2) == 0 - a = layers.cond( + a = paddle.static.nn.cond( pred, lambda: true_func(a, i), lambda: false_func(a, i) ) place = ( @@ -183,9 +183,9 @@ def false_func(): with program_guard(main_program, startup_program): i = fluid.data(name="i", shape=[1], dtype='int32') pred = (i % 2) == 0 - out1 = layers.cond(pred, true_func, false_func) - out2 = layers.cond(pred, None, false_func) - out3 = layers.cond(pred, true_func, None) + out1 = paddle.static.nn.cond(pred, true_func, false_func) + out2 = paddle.static.nn.cond(pred, None, false_func) + out3 = paddle.static.nn.cond(pred, true_func, None) place = ( fluid.CUDAPlace(0) if core.is_compiled_with_cuda() @@ -223,13 +223,15 @@ def func_return_two_tensors(): i = fluid.data(name="i", shape=[1], dtype='int32') pred = (i % 2) == 0 with self.assertRaises(TypeError): - out = layers.cond(pred, i, func_return_one_tensor) + out = paddle.static.nn.cond(pred, i, func_return_one_tensor) with self.assertRaises(TypeError): - out = layers.cond(pred, func_return_one_tensor, np.asarray([3])) + out = paddle.static.nn.cond( + pred, func_return_one_tensor, np.asarray([3]) + ) with self.assertRaises(Exception) as e: - out = layers.cond( + out = paddle.static.nn.cond( pred, func_return_none, func_return_one_tensor ) self.assertTrue( @@ -238,7 +240,7 @@ def func_return_two_tensors(): ) with self.assertRaises(Exception) as e: - out = layers.cond( + out = paddle.static.nn.cond( pred, func_return_two_tensors, func_return_none ) self.assertTrue( @@ -247,7 +249,7 @@ def func_return_two_tensors(): ) with self.assertRaises(Exception) as e: - out = layers.cond( + out = paddle.static.nn.cond( pred, func_return_one_tensor, func_return_two_tensors ) self.assertTrue( @@ -268,7 +270,7 @@ def test_extremely_simple_net_with_op_in_condition(self): shape=[1], dtype='float32', value=1.25 ) b.stop_gradient = False - out = layers.cond(a - b < -1.0, lambda: a, lambda: b) + out = paddle.static.nn.cond(a - b < -1.0, lambda: a, lambda: b) append_backward(out) place = ( @@ -308,14 +310,14 @@ def test_cond_inside_cond(self): paddle.enable_static() def less_than_branch(i, a): - return layers.cond( + return paddle.static.nn.cond( i >= 3.0, lambda: paddle.add(a, a), lambda: paddle.subtract(a, a), ) def greater_equal_branch(i, a): - return layers.cond( + return paddle.static.nn.cond( i < 8.0, lambda: paddle.multiply(a, a), lambda: paddle.divide(a, a), @@ -326,7 +328,7 @@ def greater_equal_branch(i, a): with program_guard(main_program, startup_program): i = fluid.data(name="i", shape=[1], dtype='float32') a = 2.0 * i - out = layers.cond( + out = paddle.static.nn.cond( i < 5.0, lambda: less_than_branch(i, a), lambda: greater_equal_branch(i, a), @@ -370,14 +372,14 @@ def test_cond_op_in_condition(self): shape=[1], dtype='float32', value=1.24 ) b.stop_gradient = False - out = fluid.layers.cond( + out = fluid.paddle.static.nn.cond( a < b, - lambda: fluid.layers.cond( + lambda: fluid.paddle.static.nn.cond( a - b < -1.0, lambda: paddle.add(a, b), lambda: paddle.multiply(a, b), ), - lambda: fluid.layers.cond( + lambda: fluid.paddle.static.nn.cond( a == b, lambda: paddle.subtract(a, b), lambda: paddle.pow(a, b), @@ -550,7 +552,7 @@ def test_cond_backward(self): def cond_func(i, img, label): predicate = (i % 2) == 0 - return layers.cond( + return paddle.static.nn.cond( predicate, lambda: simple_fc_net_with_inputs(img, label, class_num=10), lambda: batchnorm_fc_with_inputs(img, label, class_num=10), @@ -574,19 +576,19 @@ def test_half_nested_cond_backward(self): paddle.enable_static() def branch(i, img, label): - return layers.cond( + return paddle.static.nn.cond( (i % 2) == 0, lambda: simple_fc_net_with_inputs(img, label, class_num=10), lambda: batchnorm_fc_with_inputs(img, label, class_num=10), ) def cond_func_simple_net_at_true(i, img, label): - return layers.cond( + return paddle.static.nn.cond( i < 5, lambda: branch(i, img, label), lambda: paddle.mean(img) ) def cond_func_simple_net_at_false(i, img, label): - return layers.cond( + return paddle.static.nn.cond( i < 5, lambda: paddle.mean(img), lambda: branch(i, img, label) ) @@ -626,14 +628,14 @@ def branch(i, img, label, mod_two): predicate = (i % 2) == 0 else: predicate = (i % 2) != 0 - return layers.cond( + return paddle.static.nn.cond( predicate, lambda: simple_fc_net_with_inputs(img, label, class_num=10), lambda: batchnorm_fc_with_inputs(img, label, class_num=10), ) def cond_func(i, img, label): - return layers.cond( + return paddle.static.nn.cond( i < 5, lambda: branch(i, img, label, True), lambda: branch(i, img, label, False), @@ -665,16 +667,16 @@ def func(): return pred with self.assertRaises(TypeError): - layers.cond(None, func, func) + paddle.static.nn.cond(None, func, func) with self.assertRaises(TypeError): - layers.cond(pred, func, set()) + paddle.static.nn.cond(pred, func, set()) with self.assertRaises(TypeError): - layers.cond(pred, set(), func) + paddle.static.nn.cond(pred, set(), func) with self.assertRaises(TypeError): - layers.cond(pred, func, func, set()) + paddle.static.nn.cond(pred, func, func, set()) class TestCondWithDict(unittest.TestCase): diff --git a/python/paddle/fluid/tests/unittests/test_desc_clone.py b/python/paddle/fluid/tests/unittests/test_desc_clone.py index 477910f53d59d..0e8ee6b90a288 100644 --- a/python/paddle/fluid/tests/unittests/test_desc_clone.py +++ b/python/paddle/fluid/tests/unittests/test_desc_clone.py @@ -224,7 +224,7 @@ def false_fn(): hidden2 = fluid.layers.dropout(hidden1, dropout_prob=0.6) return hidden2 - hidden2 = fluid.layers.cond(cond, true_fn, false_fn) + hidden2 = paddle.static.nn.cond(cond, true_fn, false_fn) loss = fluid.layers.cross_entropy( input=fluid.layers.fc(hidden2, size=10, act='softmax'), @@ -265,7 +265,7 @@ def false_fn(): hidden2 = fluid.layers.dropout(hidden1, dropout_prob=0.6) return hidden2 - hidden2 = fluid.layers.cond(cond, true_fn, false_fn) + hidden2 = paddle.static.nn.cond(cond, true_fn, false_fn) loss = fluid.layers.cross_entropy( input=fluid.layers.fc(hidden2, size=10, act='softmax'), label=fluid.layers.data(name='label', shape=[1], dtype='int64'), diff --git a/python/paddle/fluid/tests/unittests/test_layers.py b/python/paddle/fluid/tests/unittests/test_layers.py index dcf442200d178..2bdd871013a5a 100644 --- a/python/paddle/fluid/tests/unittests/test_layers.py +++ b/python/paddle/fluid/tests/unittests/test_layers.py @@ -2473,7 +2473,7 @@ def greater_equal_branch(a, b): b = fluid.layers.fill_constant( shape=[1], dtype='float32', value=0.23 ) - out = fluid.layers.cond( + out = fluid.paddle.static.nn.cond( a >= b, lambda: greater_equal_branch(a, b), lambda: less_than_branch(a, b), @@ -2493,12 +2493,12 @@ def greater_equal_branch(a, b): b = fluid.dygraph.to_variable( np.array([0.23]).astype('float32') ) - out = layers.cond( + out = paddle.static.nn.cond( a < b, lambda: less_than_branch(a, b), lambda: greater_equal_branch(a, b), ) - out2 = layers.cond( + out2 = paddle.static.nn.cond( a >= b, lambda: greater_equal_branch(a, b), lambda: less_than_branch(a, b), @@ -2509,18 +2509,18 @@ def greater_equal_branch(a, b): eager_dynamic_res, eager_dynamic_res2 ) with self.assertRaises(TypeError): - layers.cond(a < b, 'str', 'str') + paddle.static.nn.cond(a < b, 'str', 'str') with self.assertRaises(TypeError): - layers.cond(a >= b, 'str', 'str') + paddle.static.nn.cond(a >= b, 'str', 'str') a = fluid.dygraph.to_variable(np.array([0.1]).astype('float32')) b = fluid.dygraph.to_variable(np.array([0.23]).astype('float32')) - out = layers.cond( + out = paddle.static.nn.cond( a < b, lambda: less_than_branch(a, b), lambda: greater_equal_branch(a, b), ) - out2 = layers.cond( + out2 = paddle.static.nn.cond( a >= b, lambda: greater_equal_branch(a, b), lambda: less_than_branch(a, b), @@ -2529,9 +2529,9 @@ def greater_equal_branch(a, b): dynamic_res2 = out2.numpy() np.testing.assert_array_equal(dynamic_res, dynamic_res2) with self.assertRaises(TypeError): - layers.cond(a < b, 'str', 'str') + paddle.static.nn.cond(a < b, 'str', 'str') with self.assertRaises(TypeError): - layers.cond(a >= b, 'str', 'str') + paddle.static.nn.cond(a >= b, 'str', 'str') np.testing.assert_array_equal(static_res, dynamic_res) np.testing.assert_array_equal(static_res, eager_dynamic_res) diff --git a/python/paddle/fluid/tests/unittests/test_math_op_patch.py b/python/paddle/fluid/tests/unittests/test_math_op_patch.py index a582b4951b117..298b6d4ed0af7 100644 --- a/python/paddle/fluid/tests/unittests/test_math_op_patch.py +++ b/python/paddle/fluid/tests/unittests/test_math_op_patch.py @@ -237,7 +237,7 @@ def test_equal_and_cond(self): one = paddle.ones(shape=[1], dtype='int32') zero = fluid.layers.zeros(shape=[1], dtype='int32') cond = one == zero - c = fluid.layers.cond(cond, lambda: a + b, lambda: a - b) + c = paddle.static.nn.cond(cond, lambda: a + b, lambda: a - b) place = fluid.CPUPlace() exe = fluid.Executor(place) diff --git a/python/paddle/fluid/tests/unittests/test_optimizer_grad.py b/python/paddle/fluid/tests/unittests/test_optimizer_grad.py index e20d563ebdc03..99c4d79bb3168 100644 --- a/python/paddle/fluid/tests/unittests/test_optimizer_grad.py +++ b/python/paddle/fluid/tests/unittests/test_optimizer_grad.py @@ -115,7 +115,7 @@ def cond_false(): return cond_res cond_i = fluid.layers.assign(np.array([cond_i], dtype='float32')) - sum_cond = fluid.layers.cond(cond_i > 1.0, cond_true, cond_false) + sum_cond = paddle.static.nn.cond(cond_i > 1.0, cond_true, cond_false) sum_all = paddle.add_n([sum_xy, sub_yz, sum_cond]) mean_out = paddle.mean(sum_all) if use_bf16: diff --git a/python/paddle/fluid/tests/unittests/test_program_code.py b/python/paddle/fluid/tests/unittests/test_program_code.py index e60706794f5b1..3ecd2619c15fc 100644 --- a/python/paddle/fluid/tests/unittests/test_program_code.py +++ b/python/paddle/fluid/tests/unittests/test_program_code.py @@ -46,7 +46,7 @@ def false_func(): x = layers.fill_constant(shape=[1], dtype='float32', value=0.1) y = layers.fill_constant(shape=[1], dtype='float32', value=0.23) pred = paddle.less_than(y, x) - out = layers.cond(pred, true_func, false_func) + out = paddle.static.nn.cond(pred, true_func, false_func) def test_program_code(self): self.var._to_readable_code() diff --git a/python/paddle/fluid/variable_index.py b/python/paddle/fluid/variable_index.py index 31d587269db71..6081f3d9a3e57 100644 --- a/python/paddle/fluid/variable_index.py +++ b/python/paddle/fluid/variable_index.py @@ -341,7 +341,7 @@ def idx_empty(var): var_shape[0] = 0 return paddle.empty(var_shape, dtype=var.dtype) - from .layers.control_flow import cond + from paddle.static.nn import cond return cond( item.any(), lambda: idx_not_empty(var, item), lambda: idx_empty(var) @@ -874,7 +874,7 @@ def idx_not_empty(var, item, value): out = scatter_nd_add(var, idx, gather_val_new) var[:] = out - from .layers.control_flow import cond + from paddle.static.nn import cond # If all the bool index is False, just do nothing cond(item.any(), lambda: idx_not_empty(var, item, value)) diff --git a/python/paddle/static/nn/__init__.py b/python/paddle/static/nn/__init__.py index b005c6f556097..772ffdcc61454 100755 --- a/python/paddle/static/nn/__init__.py +++ b/python/paddle/static/nn/__init__.py @@ -22,18 +22,19 @@ from .common import conv3d_transpose # noqa: F401 from .common import bilinear_tensor_product # noqa: F401 from .common import py_func # noqa: F401 +from .common import prelu # noqa: F401 +from .control_flow import Assert # noqa: F401 +from .control_flow import increment # noqa: F401 +from .control_flow import cond # noqa: F401 +from .loss import nce # noqa: F401 from ...tensor.creation import create_parameter # noqa: F401 from ...fluid.layers import batch_norm # noqa: F401 from ...fluid.layers import case # noqa: F401 -from ...fluid.layers import cond # noqa: F401 from ...fluid.layers import conv2d # noqa: F401 from ...fluid.layers import crf_decoding # noqa: F401 from ...fluid.layers import layer_norm # noqa: F401 from ...fluid.layers import multi_box_head # noqa: F401 -from .loss import nce # noqa: F401 -from .common import prelu # noqa: F401 -from .control_flow import Assert, increment # noqa: F401 from ...fluid.layers import row_conv # noqa: F401 from ...fluid.layers import spectral_norm # noqa: F401 from ...fluid.layers import switch_case # noqa: F401 diff --git a/python/paddle/static/nn/control_flow.py b/python/paddle/static/nn/control_flow.py index edf90babea525..0753d9a504e1a 100644 --- a/python/paddle/static/nn/control_flow.py +++ b/python/paddle/static/nn/control_flow.py @@ -13,14 +13,33 @@ # limitations under the License. +import warnings +from functools import partial + +import paddle from paddle import _C_ops from paddle.common_ops_import import LayerHelper +from paddle.fluid.control_flow import ( + ConditionalBlock, + _to_sequence_except_dict, + select_input, + support_ret_buildin_type, +) from paddle.fluid.data_feeder import check_type, check_variable_and_dtype -from paddle.framework import in_dygraph_mode +from paddle.fluid.tensor import assign +from paddle.fluid.utils import ( + assert_same_structure, + flatten, + is_sequence, + map_structure, + pack_sequence_as, +) +from paddle.framework import Variable, _non_static_mode, core, in_dygraph_mode __all__ = [ 'Assert', 'increment', + 'cond', ] @@ -141,3 +160,460 @@ def increment(x, value=1.0, in_place=True): attrs={'step': float(value)}, ) return out + + +def copy_var_to_parent_block(var, layer_helper): + if not isinstance(var, Variable): + return var + prog = layer_helper.main_program + parent_idx = prog.current_block().parent_idx + assert ( + parent_idx >= 0 + ), "Got wrong parent block index when assigning var to parent scope in control_flow" + parent_block = prog.block(parent_idx) + + if ( + var.type == core.VarDesc.VarType.LOD_TENSOR_ARRAY + and parent_block._find_var_recursive(var.name) + ): + parent_block_var = var + else: + parent_block_var = parent_block.create_var( + dtype=var.dtype, shape=var.shape, type=var.type + ) + assign(var, parent_block_var) + return parent_block_var + + +def expand_undefined_var(nest1, nest2, names): + """TODO: make this function recursively. + nest1: Var1, (UndefinedVar, [1,2,3]) + nest2: Var2, ([1,2,3,4], UndefinedVar) + In this case, we should not expand recursively. + """ + from paddle.jit.dy2static.return_transformer import RETURN_VALUE_PREFIX + from paddle.jit.dy2static.utils import UndefinedVar + + def pack_undefined_var_as(seq): + return pack_sequence_as( + seq, [UndefinedVar("padding") for i in flatten(seq)] + ) + + def map_fn(n1, n2, name, order): + if not name.startswith(RETURN_VALUE_PREFIX) and ( + isinstance(n1, UndefinedVar) or n1 is None + ): + if n1 is None and n2 is not None: + if order == 0: + warnings.warn( + "In cond : Var '{}' or part of it is set differently in ifelse branchs, " + "<{}, {}> in true branch and <{}, {}> in false branch. Set var to " + "'None' in ifelse block might lead to error.".format( + name, type(n1), n1, type(n2), n2 + ) + ) + else: + warnings.warn( + "In cond : Var '{}' or part of it is set differently in ifelse branchs, " + "<{}, {}> in true branch and <{}, {}> in false branch. Set var to " + "'None' in ifelse block might lead to error.".format( + name, type(n2), n2, type(n1), n1 + ) + ) + return pack_undefined_var_as(n2) + return n1 + + nest1_out = list( + map( + map_fn, + _to_sequence_except_dict(nest1), + _to_sequence_except_dict(nest2), + _to_sequence_except_dict(names), + [0 for i in _to_sequence_except_dict(names)], + ) + ) + nest2_out = list( + map( + map_fn, + _to_sequence_except_dict(nest2), + _to_sequence_except_dict(nest1), + _to_sequence_except_dict(names), + [1 for i in _to_sequence_except_dict(names)], + ) + ) + + def _is_sequence_except_dict(x): + """ + In this function, dict is not viewed as sequence. + """ + if isinstance(x, dict): + return False + return is_sequence(x) + + if not _is_sequence_except_dict(nest1): + nest1_out = nest1_out[0] + if not _is_sequence_except_dict(nest2): + nest2_out = nest2_out[0] + return nest1_out, nest2_out + + +def change_none_to_undefinedvar(nest1, nest2): + from paddle.jit.dy2static.utils import UndefinedVar + + def map_fn(x): + if x is None: + return UndefinedVar("padding") + return x + + nest1_out = pack_sequence_as(nest1, list(map(map_fn, flatten(nest1)))) + nest2_out = pack_sequence_as(nest2, list(map(map_fn, flatten(nest2)))) + return nest1_out, nest2_out + + +def select_input_with_buildin_type(inputs, mask, name): + from paddle.jit.dy2static.utils import UndefinedVar + from paddle.jit.dy2static.variable_trans_func import to_static_variable + + false_var, true_var = inputs + + if isinstance(false_var, UndefinedVar) and isinstance( + true_var, UndefinedVar + ): + """None -> UndefinedVar, so the real value is a [None, UndefinedVar] or [None, None], we just return None.""" + return None + + if isinstance(false_var, Variable) and isinstance(true_var, Variable): + try: + return select_input(inputs, mask) + except Exception as e: + raise RuntimeError( + f"Exceptions throwed while doing select_input on {name}:\n{e}" + ) + + elif isinstance(false_var, support_ret_buildin_type) and isinstance( + false_var, type(true_var) + ): + if false_var == true_var: + return false_var + else: + inputs = [ + to_static_variable(false_var), + to_static_variable(true_var), + ] + # Deal with the situations like this: false_var is int and true_var is Variable + elif ( + isinstance(false_var, support_ret_buildin_type) + and isinstance(true_var, Variable) + ) or ( + isinstance(true_var, support_ret_buildin_type) + and isinstance(false_var, Variable) + ): + inputs = [to_static_variable(false_var), to_static_variable(true_var)] + warnings.warn( + "Return results from different branches in cond are not same type: " + "false_var returned by false_fn is '{}' and true_var of true_fn is " + "'{}'".format(type(false_var), type(true_var)) + ) + elif ( + isinstance(false_var, UndefinedVar) + and isinstance(true_var, (Variable,) + support_ret_buildin_type) + ) or ( + isinstance(true_var, UndefinedVar) + and isinstance(false_var, (Variable,) + support_ret_buildin_type) + ): + + def create_var_if_not_undefined_var(a): + if isinstance(a, UndefinedVar): + return a + return to_static_variable(a) + + true_var, false_var = to_static_variable(true_var), to_static_variable( + false_var + ) + inputs = [false_var, true_var] + else: + raise TypeError( + "Unsupported return type of true_fn and false_fn in cond: false_var " + "returned by false_fn is '{}' and true_var of true_fn is '{}'".format( + type(false_var), type(true_var) + ) + ) + try: + return select_input(inputs, mask) + except Exception as e: + raise RuntimeError( + f"Exceptions throwed while doing select_input on {name}:\n{e}" + ) + + +def cond(pred, true_fn=None, false_fn=None, name=None, return_names=None): + """ + This API returns ``true_fn()`` if the predicate ``pred`` is true else + ``false_fn()`` . Users could also set ``true_fn`` or ``false_fn`` to + ``None`` if do nothing and this API will treat the callable simply returns + ``None`` in this case. + + ``true_fn`` and ``false_fn`` should return same nest structure of tensors + or both return ``None`` if user doens't like to return anything. A nest + structure of tensors in PaddlePaddle is tensor(s), or tuple of tensors, or + list of tensors. + + Note: + 1. The tuples or lists returned by ``true_fn`` and ``false_fn`` must have + the same shape because of dataflow model of PaddlePaddle while the + tensors in the tuples or the lists can have different shapes. + + 2. This API could be used under both static mode or dygraph mode. If it + is in dygraph mode, the API only runs one branch based on condition. + + 3. If it is in static mode, any tensors or operations created outside + or inside of ``true_fn`` and ``false_fn`` will be in net building + regardless of which branch is selected at runtime. This has frequently + surprised users who expected a lazy semantics. For example: + + .. code-block:: python + + import paddle + + a = paddle.zeros((1, 1)) + b = paddle.zeros((1, 1)) + c = a * b + out = paddle.static.nn.cond(a < b, lambda: a + c, lambda: b * b) + + No matter whether ``a < b`` , ``c = a * b`` will be in net building and + run. ``a + c`` and ``b * b`` will be in net building, but only one + branch will be executed during runtime. + + Args: + pred(Tensor): A boolean tensor whose numel should be 1. The boolean + value determines whether to return the result of ``true_fn`` or + ``false_fn`` . + true_fn(callable, optional): A callable to be performed if ``pred`` is + true. The default value is ``None`` . + false_fn(callable, optional): A callable to be performed if ``pred`` is + false. The default value is ``None`` . + name(str, optional): The default value is ``None`` . Normally users + don't have to set this parameter. For more information, please + refer to :ref:`api_guide_Name` . + return_names(sequence of string, optional): The default value is ``None`` . + Normally users don't have to set this parameters. A sequence of strings + to represents the name of returned vars. The structure of sequence must + be same with return values of true_fn and false_fn. + + Returns: + Tensor|list(Tensor)|tuple(Tensor): returns ``true_fn()`` if the + predicate ``pred`` is true else ``false_fn()`` . + + Raises: + TypeError: if ``true_fn`` or ``false_fn`` is not callable. + ValueError: if ``true_fn`` and ``false_fn`` don't return the same nest + structure of tensors. + + Examples: + .. code-block:: python + + import paddle + + # + # pseudocode: + # if 0.1 < 0.23: + # return 1, True + # else: + # return 3, 2 + # + + def true_func(): + return paddle.full(shape=[1, 2], dtype='int32', + fill_value=1), paddle.full(shape=[2, 3], + dtype='bool', + fill_value=True) + + + def false_func(): + return paddle.full(shape=[3, 4], dtype='float32', + fill_value=3), paddle.full(shape=[4, 5], + dtype='int64', + fill_value=2) + + + x = paddle.full(shape=[1], dtype='float32', fill_value=0.1) + y = paddle.full(shape=[1], dtype='float32', fill_value=0.23) + pred = paddle.less_than(x=x, y=y, name=None) + ret = paddle.static.nn.cond(pred, true_func, false_func) + # ret is a tuple containing 2 tensors + # ret[0] = [[1 1]] + # ret[1] = [[ True True True] + # [ True True True]] + + """ + if _non_static_mode(): + assert isinstance(pred, Variable), "The pred in cond must be Variable" + assert pred.size == 1, "condition input's numel should be 1" + pred = pred.numpy()[0] + if pred: + if true_fn is not None: + if not callable(true_fn): + raise TypeError( + "The true_fn in cond must be callable, but received {}".format( + type(true_fn).__name__ + ) + ) + return true_fn() + else: + if false_fn is not None: + if not callable(false_fn): + raise TypeError( + "The false_fn in cond must be callable, but received {}".format( + type(false_fn).__name__ + ) + ) + return false_fn() + return None + + check_variable_and_dtype(pred, "pred", ['bool'], "fluid.layers.cond") + check_type(name, "name", (str, type(None)), "fluid.layers.cond") + helper = LayerHelper('cond', **locals()) + true_output = None + false_output = None + copy_to_parent_func = lambda var: copy_var_to_parent_block(var, helper) + if true_fn is not None: + if not callable(true_fn): + raise TypeError( + "The true_fn in cond must be callable, but received {}".format( + type(true_fn).__name__ + ) + ) + true_cond_block = ConditionalBlock([pred], is_scalar_condition=True) + with true_cond_block.block(): + origin_true_output = true_fn() + if origin_true_output is not None: + true_output = map_structure( + copy_to_parent_func, origin_true_output + ) + if false_fn is not None: + if not callable(false_fn): + raise TypeError( + "The false_fn in cond must be callable, but received {}".format( + type(false_fn).__name__ + ) + ) + false_cond_block = ConditionalBlock( + [paddle.logical_not(pred)], is_scalar_condition=True + ) + with false_cond_block.block(): + origin_false_output = false_fn() + if origin_false_output is not None: + false_output = map_structure( + copy_to_parent_func, origin_false_output + ) + + if true_output is None and false_output is None: + return None + + if true_output is None: + raise ValueError( + "Incompatible return values of true_fn and false_fn in cond: " + "true_fn returns None while false_fn returns non-None" + ) + if false_output is None: + raise ValueError( + "Incompatible return values of true_fn and false_fn in cond: " + "true_fn returns non-None while false_fn returns None" + ) + + # Merge true and false output if they are not None + if return_names is None: + is_dy2staic = False + return_names = ["no name"] * len(_to_sequence_except_dict(true_output)) + else: + """ + dy2static will set the return_names and expand the return values to UndefinedVar. + """ + is_dy2staic = True + + # TODO: expand_undefined_var will replace None to Undefinedvar(), to fix cases like: + # a = None + # if condition: + # a = 1 + # Because we can not use variable to express 'None' + true_output, false_output = expand_undefined_var( + true_output, false_output, return_names + ) + + if len(_to_sequence_except_dict(true_output)) != len( + _to_sequence_except_dict(false_output) + ): + raise ValueError( + "true fn returns {} vars, but false fn returns {} vars, which is not equals".format( + len(_to_sequence_except_dict(true_output)), + len(_to_sequence_except_dict(false_output)), + ) + ) + for true_out, false_out, return_name in zip( + _to_sequence_except_dict(true_output), + _to_sequence_except_dict(false_output), + _to_sequence_except_dict(return_names), + ): + try: + assert_same_structure(true_out, false_out, check_types=False) + except ValueError as e: + raise ValueError( + "Incompatible return values of `{}` in true_fn and false_fn in cond: {}".format( + return_name, e + ) + ) + + def check_ret_none(seq_true, seq_false, seq_names): + for f_true, f_false, f_name in zip(seq_true, seq_false, seq_names): + f_true = flatten(f_true) + f_false = flatten(f_false) + for idx in range(len(f_true)): + if ( + f_true[idx] is None + and f_false[idx] is not None + or f_false[idx] is None + and f_true[idx] is not None + ): + warnings.warn( + "In cond : Var '{}' or part of it is set differently in ifelse branchs, " + "<{}, {}> in true branch and <{}, {}> in false branch. Set var to " + "'None' in ifelse block might lead to error.".format( + f_name, + type(f_true[idx]), + f_true[idx], + type(f_false[idx]), + f_false[idx], + ) + ) + + check_ret_none( + _to_sequence_except_dict(true_output), + _to_sequence_except_dict(false_output), + _to_sequence_except_dict(return_names), + ) + + if is_dy2staic: + true_output, false_output = change_none_to_undefinedvar( + true_output, false_output + ) + + mask = paddle.cast(pred, dtype='int32') + merge_func = ( + lambda name, false_var, true_var: select_input_with_buildin_type( + [false_var, true_var], mask, name + ) + ) + + def merge_every_var_list(false_vars, true_vars, name): + return map_structure(partial(merge_func, name), false_vars, true_vars) + + merged_output = list( + map( + merge_every_var_list, + _to_sequence_except_dict(false_output), + _to_sequence_except_dict(true_output), + _to_sequence_except_dict(return_names), + ) + ) + merged_output = pack_sequence_as(false_output, flatten(merged_output)) + return merged_output From 85548f8476e73a0caf9a1ccae1ba28a25fde4230 Mon Sep 17 00:00:00 2001 From: wuzhanfei Date: Wed, 7 Dec 2022 06:33:40 +0000 Subject: [PATCH 08/16] fix example codes --- python/paddle/fluid/layers/control_flow.py | 1 + python/paddle/static/nn/control_flow.py | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/python/paddle/fluid/layers/control_flow.py b/python/paddle/fluid/layers/control_flow.py index ef448f357b87a..2d3d8ea5d3407 100755 --- a/python/paddle/fluid/layers/control_flow.py +++ b/python/paddle/fluid/layers/control_flow.py @@ -1159,6 +1159,7 @@ class While: import paddle.fluid as fluid import numpy as np + paddle.enable_static() i = fluid.layers.fill_constant(shape=[1], dtype='int64', value=0) loop_len = fluid.layers.fill_constant(shape=[1], dtype='int64', value=10) one = fluid.layers.fill_constant(shape=[1], dtype='float32', value=1) diff --git a/python/paddle/static/nn/control_flow.py b/python/paddle/static/nn/control_flow.py index edf90babea525..2d17acb100dca 100644 --- a/python/paddle/static/nn/control_flow.py +++ b/python/paddle/static/nn/control_flow.py @@ -56,8 +56,9 @@ def Assert(cond, data=None, summarize=20, name=None): .. code-block:: python import paddle - from paddle.static.nn.control_flow import Assert + from paddle.static.nn import Assert + paddle.enable_static() x = paddle.full([2, 3], 2.0, 'float32') condition = paddle.max(x) < 1.0 # False Assert(condition, [x], 10, "example_assert_layer") @@ -65,7 +66,7 @@ def Assert(cond, data=None, summarize=20, name=None): exe = paddle.static.Executor() try: exe.run(paddle.static.default_main_program()) - # Print x and throws paddle.framework.core.EnforceNotMet exception + # Print x and throws ValueError # Example printed message for x: # # Variable: fill_constant_0.tmp_0 @@ -75,7 +76,7 @@ def Assert(cond, data=None, summarize=20, name=None): # - layout: NCHW # - dtype: float # - data: [2 2 2 2 2 2] - except paddle.framework.core.EnforceNotMet as e: + except ValueError as e: print("Assert Exception Example") ''' From 3401e6fc55a782326b15c295156eec30fc65d139 Mon Sep 17 00:00:00 2001 From: feifei-111 <2364819892@qq.com> Date: Thu, 8 Dec 2022 10:09:14 +0000 Subject: [PATCH 09/16] fix api path --- python/paddle/fluid/layers/control_flow.py | 1 - python/paddle/static/nn/control_flow.py | 481 ++++++++++++++++++++- 2 files changed, 472 insertions(+), 10 deletions(-) diff --git a/python/paddle/fluid/layers/control_flow.py b/python/paddle/fluid/layers/control_flow.py index 3dad7cf268d93..a2dcdc642942a 100755 --- a/python/paddle/fluid/layers/control_flow.py +++ b/python/paddle/fluid/layers/control_flow.py @@ -55,7 +55,6 @@ 'Switch', 'array_write', 'array_read', - 'cond', 'StaticRNN', 'Print', 'while_loop', diff --git a/python/paddle/static/nn/control_flow.py b/python/paddle/static/nn/control_flow.py index 32bb548bfef4d..f5896db4ea140 100644 --- a/python/paddle/static/nn/control_flow.py +++ b/python/paddle/static/nn/control_flow.py @@ -28,13 +28,17 @@ from paddle.fluid.framework import Operator, Program, Variable # Temporary solution, it will be deleted later -from paddle.fluid.layers.control_flow import cond +from paddle.fluid.layers.control_flow import ConditionalBlock, select_input +from paddle.fluid.layers.tensor import assign, cast from paddle.fluid.layers.utils import ( assert_same_structure, copy_mutable_vars, + flatten, hold_mutable_vars, is_sequence, map_structure, + pack_sequence_as, + to_sequence, ) from paddle.framework import in_dygraph_mode @@ -66,13 +70,6 @@ def Assert(cond, data=None, summarize=20, name=None): Returns: Operator: the created operation. - Raises: - TypeError: If ``cond`` is not boolean Variable. - TypeError: If ``data`` is not a list or tuple or ``None``. - TypeError: If ``summarize`` is not int. - TypeError: If ``name`` is not a string or ``None`` . - framework.core.EnforceNotMet: If the condition is False in running time. - Examples: .. code-block:: python @@ -124,7 +121,7 @@ def Assert(cond, data=None, summarize=20, name=None): def increment(x, value=1.0, in_place=True): """ - The OP is usually used for control flow to increment the data of :attr:`x` by an amount :attr:`value`. + This API is usually used for control flow to increment the data of :attr:`x` by an amount :attr:`value`. Notice that the number of elements in :attr:`x` must be equal to 1. Parameters: @@ -923,3 +920,469 @@ def _check_args(branch_index, branch_fns, default): final_fn = false_fn return final_fn() + + +def cond(pred, true_fn=None, false_fn=None, name=None, return_names=None): + """ + This API returns ``true_fn()`` if the predicate ``pred`` is true else + ``false_fn()`` . Users could also set ``true_fn`` or ``false_fn`` to + ``None`` if do nothing and this API will treat the callable simply returns + ``None`` in this case. + + ``true_fn`` and ``false_fn`` should return same nest structure of tensors + or both return ``None`` if user doens't like to return anything. A nest + structure of tensors in PaddlePaddle is tensor(s), or tuple of tensors, or + list of tensors. + + Note: + 1. The tuples or lists returned by ``true_fn`` and ``false_fn`` must have + the same shape because of dataflow model of PaddlePaddle while the + tensors in the tuples or the lists can have different shapes. + + 2. This API could be used under both static mode or dygraph mode. If it + is in dygraph mode, the API only runs one branch based on condition. + + 3. If it is in static mode, any tensors or operations created outside + or inside of ``true_fn`` and ``false_fn`` will be in net building + regardless of which branch is selected at runtime. This has frequently + surprised users who expected a lazy semantics. For example: + + .. code-block:: python + + import paddle + + a = paddle.zeros((1, 1)) + b = paddle.zeros((1, 1)) + c = a * b + out = paddle.static.nn.cond(a < b, lambda: a + c, lambda: b * b) + + No matter whether ``a < b`` , ``c = a * b`` will be in net building and + run. ``a + c`` and ``b * b`` will be in net building, but only one + branch will be executed during runtime. + + Args: + pred(Tensor): A boolean tensor whose numel should be 1. The boolean + value determines whether to return the result of ``true_fn`` or + ``false_fn`` . + true_fn(callable, optional): A callable to be performed if ``pred`` is + true. The default value is ``None`` . + false_fn(callable, optional): A callable to be performed if ``pred`` is + false. The default value is ``None`` . + name(str, optional): The default value is ``None`` . Normally users + don't have to set this parameter. For more information, please + refer to :ref:`api_guide_Name` . + return_names(sequence of string, optional): The default value is ``None`` . + Normally users don't have to set this parameters. A sequence of strings + to represents the name of returned vars. The structure of sequence must + be same with return values of true_fn and false_fn. + + Returns: + Tensor|list(Tensor)|tuple(Tensor): returns ``true_fn()`` if the + predicate ``pred`` is true else ``false_fn()`` . + + Raises: + TypeError: if ``true_fn`` or ``false_fn`` is not callable. + ValueError: if ``true_fn`` and ``false_fn`` don't return the same nest + structure of tensors. + + Examples: + .. code-block:: python + + import paddle + + # + # pseudocode: + # if 0.1 < 0.23: + # return 1, True + # else: + # return 3, 2 + # + + def true_func(): + return paddle.full(shape=[1, 2], dtype='int32', + fill_value=1), paddle.full(shape=[2, 3], + dtype='bool', + fill_value=True) + + + def false_func(): + return paddle.full(shape=[3, 4], dtype='float32', + fill_value=3), paddle.full(shape=[4, 5], + dtype='int64', + fill_value=2) + + + x = paddle.full(shape=[1], dtype='float32', fill_value=0.1) + y = paddle.full(shape=[1], dtype='float32', fill_value=0.23) + pred = paddle.less_than(x=x, y=y, name=None) + ret = paddle.static.nn.cond(pred, true_func, false_func) + # ret is a tuple containing 2 tensors + # ret[0] = [[1 1]] + # ret[1] = [[ True True True] + # [ True True True]] + + """ + if _non_static_mode(): + assert isinstance(pred, Variable), "The pred in cond must be Variable" + assert pred.size == 1, "condition input's numel should be 1" + pred = pred.numpy()[0] + if pred: + if true_fn is not None: + if not callable(true_fn): + raise TypeError( + "The true_fn in cond must be callable, but received {}".format( + type(true_fn).__name__ + ) + ) + return true_fn() + else: + if false_fn is not None: + if not callable(false_fn): + raise TypeError( + "The false_fn in cond must be callable, but received {}".format( + type(false_fn).__name__ + ) + ) + return false_fn() + return None + + check_variable_and_dtype(pred, "pred", ['bool'], "fluid.layers.cond") + check_type(name, "name", (str, type(None)), "fluid.layers.cond") + helper = LayerHelper('cond', **locals()) + true_output = None + false_output = None + copy_to_parent_func = lambda var: copy_var_to_parent_block(var, helper) + if true_fn is not None: + if not callable(true_fn): + raise TypeError( + "The true_fn in cond must be callable, but received {}".format( + type(true_fn).__name__ + ) + ) + true_cond_block = ConditionalBlock([pred], is_scalar_condition=True) + with true_cond_block.block(): + origin_true_output = true_fn() + if origin_true_output is not None: + true_output = map_structure( + copy_to_parent_func, origin_true_output + ) + if false_fn is not None: + if not callable(false_fn): + raise TypeError( + "The false_fn in cond must be callable, but received {}".format( + type(false_fn).__name__ + ) + ) + false_cond_block = ConditionalBlock( + [paddle.logical_not(pred)], is_scalar_condition=True + ) + with false_cond_block.block(): + origin_false_output = false_fn() + if origin_false_output is not None: + false_output = map_structure( + copy_to_parent_func, origin_false_output + ) + + if true_output is None and false_output is None: + return None + + if true_output is None: + raise ValueError( + "Incompatible return values of true_fn and false_fn in cond: " + "true_fn returns None while false_fn returns non-None" + ) + if false_output is None: + raise ValueError( + "Incompatible return values of true_fn and false_fn in cond: " + "true_fn returns non-None while false_fn returns None" + ) + + # Merge true and false output if they are not None + if return_names is None: + is_dy2staic = False + return_names = ["no name"] * len(_to_sequence_except_dict(true_output)) + else: + """ + dy2static will set the return_names and expand the return values to UndefinedVar. + """ + is_dy2staic = True + + # TODO: expand_undefined_var will replace None to Undefinedvar(), to fix cases like: + # a = None + # if condition: + # a = 1 + # Because we can not use variable to express 'None' + true_output, false_output = expand_undefined_var( + true_output, false_output, return_names + ) + + if len(_to_sequence_except_dict(true_output)) != len( + _to_sequence_except_dict(false_output) + ): + raise ValueError( + "true fn returns {} vars, but false fn returns {} vars, which is not equals".format( + len(_to_sequence_except_dict(true_output)), + len(_to_sequence_except_dict(false_output)), + ) + ) + for true_out, false_out, return_name in zip( + _to_sequence_except_dict(true_output), + _to_sequence_except_dict(false_output), + _to_sequence_except_dict(return_names), + ): + try: + assert_same_structure(true_out, false_out, check_types=False) + except ValueError as e: + raise ValueError( + "Incompatible return values of `{}` in true_fn and false_fn in cond: {}".format( + return_name, e + ) + ) + + def check_ret_none(seq_true, seq_false, seq_names): + for f_true, f_false, f_name in zip(seq_true, seq_false, seq_names): + f_true = flatten(f_true) + f_false = flatten(f_false) + for idx in range(len(f_true)): + if ( + f_true[idx] is None + and f_false[idx] is not None + or f_false[idx] is None + and f_true[idx] is not None + ): + warnings.warn( + "In cond : Var '{}' or part of it is set differently in ifelse branchs, " + "<{}, {}> in true branch and <{}, {}> in false branch. Set var to " + "'None' in ifelse block might lead to error.".format( + f_name, + type(f_true[idx]), + f_true[idx], + type(f_false[idx]), + f_false[idx], + ) + ) + + check_ret_none( + _to_sequence_except_dict(true_output), + _to_sequence_except_dict(false_output), + _to_sequence_except_dict(return_names), + ) + + if is_dy2staic: + true_output, false_output = change_none_to_undefinedvar( + true_output, false_output + ) + + mask = cast(pred, dtype='int32') + merge_func = ( + lambda name, false_var, true_var: select_input_with_buildin_type( + [false_var, true_var], mask, name + ) + ) + + def merge_every_var_list(false_vars, true_vars, name): + return map_structure(partial(merge_func, name), false_vars, true_vars) + + merged_output = list( + map( + merge_every_var_list, + _to_sequence_except_dict(false_output), + _to_sequence_except_dict(true_output), + _to_sequence_except_dict(return_names), + ) + ) + merged_output = pack_sequence_as(false_output, flatten(merged_output)) + return merged_output + + +def copy_var_to_parent_block(var, layer_helper): + if not isinstance(var, Variable): + return var + prog = layer_helper.main_program + parent_idx = prog.current_block().parent_idx + assert ( + parent_idx >= 0 + ), "Got wrong parent block index when assigning var to parent scope in control_flow" + parent_block = prog.block(parent_idx) + + if ( + var.type == core.VarDesc.VarType.LOD_TENSOR_ARRAY + and parent_block._find_var_recursive(var.name) + ): + parent_block_var = var + else: + parent_block_var = parent_block.create_var( + dtype=var.dtype, shape=var.shape, type=var.type + ) + assign(var, parent_block_var) + return parent_block_var + + +def select_input_with_buildin_type(inputs, mask, name): + from paddle.jit.dy2static.utils import UndefinedVar + from paddle.jit.dy2static.variable_trans_func import to_static_variable + + false_var, true_var = inputs + + if isinstance(false_var, UndefinedVar) and isinstance( + true_var, UndefinedVar + ): + """None -> UndefinedVar, so the real value is a [None, UndefinedVar] or [None, None], we just return None.""" + return None + + if isinstance(false_var, Variable) and isinstance(true_var, Variable): + try: + return select_input(inputs, mask) + except Exception as e: + raise RuntimeError( + f"Exceptions throwed while doing select_input on {name}:\n{e}" + ) + + elif isinstance(false_var, support_ret_buildin_type) and isinstance( + false_var, type(true_var) + ): + if false_var == true_var: + return false_var + else: + inputs = [ + to_static_variable(false_var), + to_static_variable(true_var), + ] + # Deal with the situations like this: false_var is int and true_var is Variable + elif ( + isinstance(false_var, support_ret_buildin_type) + and isinstance(true_var, Variable) + ) or ( + isinstance(true_var, support_ret_buildin_type) + and isinstance(false_var, Variable) + ): + inputs = [to_static_variable(false_var), to_static_variable(true_var)] + warnings.warn( + "Return results from different branches in cond are not same type: " + "false_var returned by false_fn is '{}' and true_var of true_fn is " + "'{}'".format(type(false_var), type(true_var)) + ) + elif ( + isinstance(false_var, UndefinedVar) + and isinstance(true_var, (Variable,) + support_ret_buildin_type) + ) or ( + isinstance(true_var, UndefinedVar) + and isinstance(false_var, (Variable,) + support_ret_buildin_type) + ): + + def create_var_if_not_undefined_var(a): + if isinstance(a, UndefinedVar): + return a + return to_static_variable(a) + + true_var, false_var = to_static_variable(true_var), to_static_variable( + false_var + ) + inputs = [false_var, true_var] + else: + raise TypeError( + "Unsupported return type of true_fn and false_fn in cond: false_var " + "returned by false_fn is '{}' and true_var of true_fn is '{}'".format( + type(false_var), type(true_var) + ) + ) + try: + return select_input(inputs, mask) + except Exception as e: + raise RuntimeError( + f"Exceptions throwed while doing select_input on {name}:\n{e}" + ) + + +def _is_sequence_except_dict(x): + """ + In this function, dict is not viewed as sequence. + """ + if isinstance(x, dict): + return False + return is_sequence(x) + + +def _to_sequence_except_dict(x): + """ + In this function, dict is not viewed as sequence. + """ + if isinstance(x, dict): + return [x] + return to_sequence(x) + + +def expand_undefined_var(nest1, nest2, names): + """TODO: make this function recursively. + nest1: Var1, (UndefinedVar, [1,2,3]) + nest2: Var2, ([1,2,3,4], UndefinedVar) + In this case, we should not expand recursively. + """ + from paddle.jit.dy2static.return_transformer import RETURN_VALUE_PREFIX + from paddle.jit.dy2static.utils import UndefinedVar + + def pack_undefined_var_as(seq): + return pack_sequence_as( + seq, [UndefinedVar("padding") for i in flatten(seq)] + ) + + def map_fn(n1, n2, name, order): + if not name.startswith(RETURN_VALUE_PREFIX) and ( + isinstance(n1, UndefinedVar) or n1 is None + ): + if n1 is None and n2 is not None: + if order == 0: + warnings.warn( + "In cond : Var '{}' or part of it is set differently in ifelse branchs, " + "<{}, {}> in true branch and <{}, {}> in false branch. Set var to " + "'None' in ifelse block might lead to error.".format( + name, type(n1), n1, type(n2), n2 + ) + ) + else: + warnings.warn( + "In cond : Var '{}' or part of it is set differently in ifelse branchs, " + "<{}, {}> in true branch and <{}, {}> in false branch. Set var to " + "'None' in ifelse block might lead to error.".format( + name, type(n2), n2, type(n1), n1 + ) + ) + return pack_undefined_var_as(n2) + return n1 + + nest1_out = list( + map( + map_fn, + _to_sequence_except_dict(nest1), + _to_sequence_except_dict(nest2), + _to_sequence_except_dict(names), + [0 for i in _to_sequence_except_dict(names)], + ) + ) + nest2_out = list( + map( + map_fn, + _to_sequence_except_dict(nest2), + _to_sequence_except_dict(nest1), + _to_sequence_except_dict(names), + [1 for i in _to_sequence_except_dict(names)], + ) + ) + if not _is_sequence_except_dict(nest1): + nest1_out = nest1_out[0] + if not _is_sequence_except_dict(nest2): + nest2_out = nest2_out[0] + return nest1_out, nest2_out + + +def change_none_to_undefinedvar(nest1, nest2): + from paddle.jit.dy2static.utils import UndefinedVar + + def map_fn(x): + if x is None: + return UndefinedVar("padding") + return x + + nest1_out = pack_sequence_as(nest1, list(map(map_fn, flatten(nest1)))) + nest2_out = pack_sequence_as(nest2, list(map(map_fn, flatten(nest2)))) + return nest1_out, nest2_out From cd5329732aa9400dbddcf27497d9a62b396988b8 Mon Sep 17 00:00:00 2001 From: feifei-111 <2364819892@qq.com> Date: Thu, 8 Dec 2022 11:09:52 +0000 Subject: [PATCH 10/16] fix fix circular import --- python/paddle/fluid/layers/control_flow.py | 1 + python/paddle/jit/dy2static/convert_operators.py | 7 ++++--- python/paddle/static/nn/control_flow.py | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/python/paddle/fluid/layers/control_flow.py b/python/paddle/fluid/layers/control_flow.py index a2dcdc642942a..34b009df67e18 100755 --- a/python/paddle/fluid/layers/control_flow.py +++ b/python/paddle/fluid/layers/control_flow.py @@ -387,6 +387,7 @@ def Print( return output +# (TODO: Mine) There exists dependency. It will be removed later. class BlockGuard: """ BlockGuard class. diff --git a/python/paddle/jit/dy2static/convert_operators.py b/python/paddle/jit/dy2static/convert_operators.py index c3e3163588bdc..fe9cd827d728c 100644 --- a/python/paddle/jit/dy2static/convert_operators.py +++ b/python/paddle/jit/dy2static/convert_operators.py @@ -33,7 +33,6 @@ control_flow, ) from paddle.fluid.layers.control_flow import ( - cond, while_loop, ) from .return_transformer import ( @@ -394,7 +393,7 @@ def new_false_fn(): return ret try: - cond_outs = control_flow.cond( + cond_outs = paddle.static.nn.cond( pred, new_true_fn, new_false_fn, None, return_name_ids ) except Exception as e: @@ -820,7 +819,9 @@ def false_fn(array, start, end): new_array = paddle.slice(array, starts=[start], ends=[end], axes=[0]) return new_array - new_array = cond(start == end, true_fn, lambda: false_fn(array, start, end)) + new_array = paddle.static.nn.cond( + start == end, true_fn, lambda: false_fn(array, start, end) + ) return new_array diff --git a/python/paddle/static/nn/control_flow.py b/python/paddle/static/nn/control_flow.py index f5896db4ea140..705f4eea2967f 100644 --- a/python/paddle/static/nn/control_flow.py +++ b/python/paddle/static/nn/control_flow.py @@ -24,6 +24,7 @@ check_type, check_variable_and_dtype, convert_dtype, + in_dygraph_mode, ) from paddle.fluid.framework import Operator, Program, Variable @@ -40,7 +41,6 @@ pack_sequence_as, to_sequence, ) -from paddle.framework import in_dygraph_mode __all__ = [ 'Assert', From 14629e5b110acf2e00a6a1b60dd7985bffcc7f9f Mon Sep 17 00:00:00 2001 From: feifei-111 <2364819892@qq.com> Date: Thu, 8 Dec 2022 11:18:38 +0000 Subject: [PATCH 11/16] del unused function --- python/paddle/fluid/layers/control_flow.py | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/python/paddle/fluid/layers/control_flow.py b/python/paddle/fluid/layers/control_flow.py index 34b009df67e18..7152116131644 100755 --- a/python/paddle/fluid/layers/control_flow.py +++ b/python/paddle/fluid/layers/control_flow.py @@ -90,26 +90,6 @@ def select_output(input, outputs, mask): return outputs -def _select_input_infer_shape(first_shape, second_shape): - """ - This function infer the output shape by following algorithm: - 1. if the dims is different, raise a error. - 2. compare axis one by one: - if a == b: we set axis to a - if a != b: we set axis to -1 - for compatibility, non declarative mode, we just return second_shape. - """ - if len(first_shape) != len(second_shape): - warnings.warn( - f"the input shapes of select_input should have the same rank, but get {first_shape}, {second_shape}" - ) - return second_shape - out_shape = list( - map(lambda a, b: a if a == b else -1, first_shape, second_shape) - ) - return out_shape - - def select_input(inputs, mask): """ **select_input** From 9f7f6cfb556177e479a82bdabbd4c1308c445c4a Mon Sep 17 00:00:00 2001 From: feifei-111 <2364819892@qq.com> Date: Thu, 8 Dec 2022 11:20:59 +0000 Subject: [PATCH 12/16] remove unused function --- python/paddle/fluid/layers/control_flow.py | 38 ++++++++++++---------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/python/paddle/fluid/layers/control_flow.py b/python/paddle/fluid/layers/control_flow.py index 7152116131644..b19a077307a14 100755 --- a/python/paddle/fluid/layers/control_flow.py +++ b/python/paddle/fluid/layers/control_flow.py @@ -90,6 +90,26 @@ def select_output(input, outputs, mask): return outputs +def _select_input_infer_shape(first_shape, second_shape): + """ + This function infer the output shape by following algorithm: + 1. if the dims is different, raise a error. + 2. compare axis one by one: + if a == b: we set axis to a + if a != b: we set axis to -1 + for compatibility,non declarative mode, we just return second_shape. + """ + if len(first_shape) != len(second_shape): + warnings.warn( + f"the input shapes of select_input should have the same rank, but get {first_shape}, {second_shape}" + ) + return second_shape + out_shape = list( + map(lambda a, b: a if a == b else -1, first_shape, second_shape) + ) + return out_shape + + def select_input(inputs, mask): """ **select_input** @@ -111,24 +131,6 @@ def select_input(inputs, mask): # Select input should expand the shape. If it is - 1 and valid number, use - 1 first. If the dim is different, an error will be reported directly # assert inputs[0].dtype == inputs[1].dtype, f"Expect the inputs should have the same dtype, but get {inputs[0].dtype} and {inputs[1].dtype}" - def _select_input_infer_shape(first_shape, second_shape): - """ - This function infer the output shape by following algorithm: - 1. if the dims is different, raise a error. - 2. compare axis one by one: - if a == b: we set axis to a - if a != b: we set axis to -1 - for compatibility,non declarative mode, we just return second_shape. - """ - if len(first_shape) != len(second_shape): - warnings.warn( - f"the input shapes of select_input should have the same rank, but get {first_shape}, {second_shape}" - ) - return second_shape - out_shape = list( - map(lambda a, b: a if a == b else -1, first_shape, second_shape) - ) - return out_shape output_shape = _select_input_infer_shape(inputs[0].shape, inputs[1].shape) output_dtype = inputs[1].dtype From 3ca8284de33558de41f20ef5a4a785131848ccbf Mon Sep 17 00:00:00 2001 From: feifei-111 <2364819892@qq.com> Date: Thu, 8 Dec 2022 11:29:32 +0000 Subject: [PATCH 13/16] update doc --- python/paddle/static/nn/control_flow.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/python/paddle/static/nn/control_flow.py b/python/paddle/static/nn/control_flow.py index 705f4eea2967f..e7f1903ccf0aa 100644 --- a/python/paddle/static/nn/control_flow.py +++ b/python/paddle/static/nn/control_flow.py @@ -980,11 +980,6 @@ def cond(pred, true_fn=None, false_fn=None, name=None, return_names=None): Tensor|list(Tensor)|tuple(Tensor): returns ``true_fn()`` if the predicate ``pred`` is true else ``false_fn()`` . - Raises: - TypeError: if ``true_fn`` or ``false_fn`` is not callable. - ValueError: if ``true_fn`` and ``false_fn`` don't return the same nest - structure of tensors. - Examples: .. code-block:: python From c93df21ba8b460a29c21b1bcf03fb6c2a30cb5ce Mon Sep 17 00:00:00 2001 From: feifei-111 <2364819892@qq.com> Date: Thu, 8 Dec 2022 15:41:18 +0000 Subject: [PATCH 14/16] fix type err --- python/paddle/fluid/tests/unittests/test_cond.py | 6 +++--- python/paddle/fluid/tests/unittests/test_layers.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/python/paddle/fluid/tests/unittests/test_cond.py b/python/paddle/fluid/tests/unittests/test_cond.py index c96cece765b24..3176ace0a3813 100644 --- a/python/paddle/fluid/tests/unittests/test_cond.py +++ b/python/paddle/fluid/tests/unittests/test_cond.py @@ -372,14 +372,14 @@ def test_cond_op_in_condition(self): shape=[1], dtype='float32', value=1.24 ) b.stop_gradient = False - out = fluid.paddle.static.nn.cond( + out = paddle.static.nn.cond( a < b, - lambda: fluid.paddle.static.nn.cond( + lambda: paddle.static.nn.cond( a - b < -1.0, lambda: paddle.add(a, b), lambda: paddle.multiply(a, b), ), - lambda: fluid.paddle.static.nn.cond( + lambda: paddle.static.nn.cond( a == b, lambda: paddle.subtract(a, b), lambda: paddle.pow(a, b), diff --git a/python/paddle/fluid/tests/unittests/test_layers.py b/python/paddle/fluid/tests/unittests/test_layers.py index 868b6bc217b63..8074a5de52a8b 100644 --- a/python/paddle/fluid/tests/unittests/test_layers.py +++ b/python/paddle/fluid/tests/unittests/test_layers.py @@ -1577,7 +1577,7 @@ def greater_equal_branch(a, b): b = fluid.layers.fill_constant( shape=[1], dtype='float32', value=0.23 ) - out = fluid.paddle.static.nn.cond( + out = paddle.static.nn.cond( a >= b, lambda: greater_equal_branch(a, b), lambda: less_than_branch(a, b), From b503a427f870d83c2d20c76ef025ea734a27714a Mon Sep 17 00:00:00 2001 From: feifei-111 <2364819892@qq.com> Date: Fri, 9 Dec 2022 03:41:19 +0000 Subject: [PATCH 15/16] rm __all__ to hide api interface --- .../fleet/utils/hybrid_parallel_inference.py | 4 +- python/paddle/fluid/layers/control_flow.py | 47 ++--------------- python/paddle/fluid/layers/rnn.py | 4 +- python/paddle/fluid/optimizer.py | 4 +- .../auto_parallel/test_while_op_partition.py | 2 +- .../fleet/hybrid_parallel_inference_helper.py | 4 +- .../fluid/tests/unittests/dist_transformer.py | 6 +-- .../unittests/dygraph_to_static/test_loop.py | 9 ++-- .../unittests/npu/test_increment_op_npu.py | 2 +- .../tests/unittests/npu/test_while_op_npu.py | 9 ++-- .../unittests/test_array_read_write_op.py | 9 ++-- .../test_async_ssa_graph_executor_mnist.py | 2 +- .../test_dynamic_rnn_stop_gradient.py | 2 +- .../unittests/test_eager_deletion_while_op.py | 9 ++-- .../tests/unittests/test_executor_and_mul.py | 6 +-- .../unittests/test_fetch_lod_tensor_array.py | 6 +-- .../fluid/tests/unittests/test_profiler.py | 2 +- .../tests/unittests/test_while_loop_op.py | 31 ++++++----- .../fluid/tests/unittests/test_while_op.py | 11 ++-- .../tests/unittests/xpu/test_while_op_xpu.py | 9 ++-- .../paddle/jit/dy2static/convert_operators.py | 4 +- python/paddle/static/nn/__init__.py | 4 +- python/paddle/static/nn/control_flow.py | 51 ------------------- 23 files changed, 65 insertions(+), 172 deletions(-) diff --git a/python/paddle/distributed/fleet/utils/hybrid_parallel_inference.py b/python/paddle/distributed/fleet/utils/hybrid_parallel_inference.py index 3cccbd782ecc9..f5010e815c37b 100644 --- a/python/paddle/distributed/fleet/utils/hybrid_parallel_inference.py +++ b/python/paddle/distributed/fleet/utils/hybrid_parallel_inference.py @@ -64,7 +64,7 @@ class HybridParallelInferenceHelper: element_in_arr = layers.array_read(array=arr, i=step_idx) # write placehold data to global lod_tensor_array, # it need for send_v2 of lod_tensor_array - paddle.static.nn.increment(x=step_idx, value=1.0, in_place=True) + paddle.increment(x=step_idx, value=1.0, in_place=True) layers.array_write(element_in_arr, i=step_idx, array=arr) with paddle.fluid.device_guard(f'{device}:0'): @@ -137,7 +137,7 @@ class HybridParallelInferenceHelper: with while_op.block(): with paddle.fluid.device_guard(f'{device}:all'): input = layers.array_read(array=data, i=step_idx) - paddle.static.nn.increment(x=step_idx, value=1.0, in_place=True) + paddle.increment(x=step_idx, value=1.0, in_place=True) layers.array_write(input, i=step_idx, array=data) with paddle.fluid.device_guard(f'{device}:0'): diff --git a/python/paddle/fluid/layers/control_flow.py b/python/paddle/fluid/layers/control_flow.py index b19a077307a14..1bf5de42e7e95 100755 --- a/python/paddle/fluid/layers/control_flow.py +++ b/python/paddle/fluid/layers/control_flow.py @@ -97,7 +97,7 @@ def _select_input_infer_shape(first_shape, second_shape): 2. compare axis one by one: if a == b: we set axis to a if a != b: we set axis to -1 - for compatibility,non declarative mode, we just return second_shape. + for compatibility, non declarative mode, we just return second_shape. """ if len(first_shape) != len(second_shape): warnings.warn( @@ -1063,7 +1063,7 @@ class While: cond = paddle.less_than(x=i, y=loop_len) while_op = fluid.layers.While(cond=cond) with while_op.block(): - i = paddle.static.nn.increment(x=i, value=1, in_place=True) + i = paddle.increment(x=i, value=1, in_place=True) paddle.assign(paddle.less_than(x=i, y=loop_len), cond) exe = fluid.Executor(fluid.CPUPlace()) @@ -1092,7 +1092,7 @@ class While: with while_op.block(): sums_tensor = fluid.layers.elementwise_add(x=data, y=data) fluid.layers.assign(sums_tensor, sums) # Update the value of sums_tensor defined in While to the sums which defined outside of While through layers.assign - i = paddle.static.nn.increment(x=i, value=1, in_place=True) + i = paddle.increment(x=i, value=1, in_place=True) data = fluid.layers.elementwise_add(x=data, y=one) paddle.assign(paddle.less_than(x=i, y=loop_len), cond) @@ -1362,47 +1362,6 @@ def create_var_like(o_var): return results -def increment(x, value=1.0, in_place=True): - """ - The OP is usually used for control flow to increment the data of :attr:`x` by an amount :attr:`value`. - Notice that the number of elements in :attr:`x` must be equal to 1. - - Parameters: - x (Variable): A tensor that must always contain only one element, its data type supports - float32, float64, int32 and int64. - value (float, optional): The amount to increment the data of :attr:`x`. Default: 1.0. - in_place (bool, optional): Whether the OP should be performed in-place. Default: True. - - Returns: - Variable: The elementwise-incremented tensor with the same shape and data type as :attr:`x`. - - Examples: - .. code-block:: python - - import paddle.fluid as fluid - counter = fluid.layers.zeros(shape=[1], dtype='float32') # [0.] - fluid.layers.increment(counter) # [1.] - """ - if in_dygraph_mode(): - return _C_ops.increment_(x, value) - - check_variable_and_dtype( - x, 'x', ['float32', 'float64', 'int32', 'int64'], 'increment' - ) - helper = LayerHelper("increment", **locals()) - if not in_place: - out = helper.create_variable_for_type_inference(dtype=x.dtype) - else: - out = x - helper.append_op( - type='increment', - inputs={'X': [x]}, - outputs={'Out': [out]}, - attrs={'step': float(value)}, - ) - return out - - def array_write(x, i, array=None): """ This OP writes the input ``x`` into the i-th position of the ``array`` diff --git a/python/paddle/fluid/layers/rnn.py b/python/paddle/fluid/layers/rnn.py index 97dedf2b4681c..2fd45e9f084d2 100644 --- a/python/paddle/fluid/layers/rnn.py +++ b/python/paddle/fluid/layers/rnn.py @@ -1536,7 +1536,7 @@ def _maybe_copy(state, new_state, step_mask): next_sequence_lengths, ) - paddle.static.nn.increment(x=step_idx_tensor, value=1.0, in_place=True) + paddle.increment(x=step_idx_tensor, value=1.0, in_place=True) step_idx += 1 cond = paddle.logical_not(paddle.all(finished)) @@ -1696,7 +1696,7 @@ def _create_array_out_of_while(dtype): outputs_arrays, ) - paddle.static.nn.increment(x=step_idx, value=1.0, in_place=True) + paddle.increment(x=step_idx, value=1.0, in_place=True) # update the global_finished first, since it might be also in states of # decoder, which otherwise would write a stale finished status to array tensor.assign(next_finished, global_finished) diff --git a/python/paddle/fluid/optimizer.py b/python/paddle/fluid/optimizer.py index 444658ac35aa0..a61913e8c2e18 100755 --- a/python/paddle/fluid/optimizer.py +++ b/python/paddle/fluid/optimizer.py @@ -7283,7 +7283,7 @@ def minimize(self, loss, startup_program=None): dtype='int32', persistable=True, ) - paddle.static.nn.increment(x=step, value=1.0, in_place=True) + paddle.increment(x=step, value=1.0, in_place=True) # lookahead zero_var = layers.fill_constant( @@ -7517,7 +7517,7 @@ def _get_gm_cond_var(self, main_block): with device_guard("cpu"): # step_var = (step_var + 1) % k_step - paddle.static.nn.increment(x=step_var, value=1.0, in_place=True) + paddle.increment(x=step_var, value=1.0, in_place=True) main_block.append_op( type='elementwise_mod', inputs={'X': step_var, 'Y': k_step_var}, diff --git a/python/paddle/fluid/tests/unittests/auto_parallel/test_while_op_partition.py b/python/paddle/fluid/tests/unittests/auto_parallel/test_while_op_partition.py index 6384684a8c24d..6e59cf16eafe8 100644 --- a/python/paddle/fluid/tests/unittests/auto_parallel/test_while_op_partition.py +++ b/python/paddle/fluid/tests/unittests/auto_parallel/test_while_op_partition.py @@ -189,7 +189,7 @@ def get_program(): cur_pred = mlp_while(pre_input) # 更新循环条件 - i = paddle.static.nn.increment(x=i, value=1, in_place=True) + i = paddle.increment(x=i, value=1, in_place=True) fluid.layers.array_write(cur_pred, array=input_array, i=i) paddle.assign(paddle.less_than(x=i, y=loop_len), cond) diff --git a/python/paddle/fluid/tests/unittests/collective/fleet/hybrid_parallel_inference_helper.py b/python/paddle/fluid/tests/unittests/collective/fleet/hybrid_parallel_inference_helper.py index 921bed35bd756..75e7e708ef4a9 100644 --- a/python/paddle/fluid/tests/unittests/collective/fleet/hybrid_parallel_inference_helper.py +++ b/python/paddle/fluid/tests/unittests/collective/fleet/hybrid_parallel_inference_helper.py @@ -91,9 +91,7 @@ def test_hybrid_parallel_inference_helper_mp1pp2(self): with while_op.block(): with paddle.fluid.device_guard(f'{device}:all'): input = layers.array_read(array=data, i=step_idx) - paddle.static.nn.increment( - x=step_idx, value=1.0, in_place=True - ) + paddle.increment(x=step_idx, value=1.0, in_place=True) layers.array_write(input, i=step_idx, array=data) with paddle.fluid.device_guard(f'{device}:0'): diff --git a/python/paddle/fluid/tests/unittests/dist_transformer.py b/python/paddle/fluid/tests/unittests/dist_transformer.py index db95b2062816c..a24319fca8a01 100644 --- a/python/paddle/fluid/tests/unittests/dist_transformer.py +++ b/python/paddle/fluid/tests/unittests/dist_transformer.py @@ -1813,9 +1813,7 @@ def beam_search(): shape=[-1, 1, 1], dtype=pre_ids.dtype, ), - y=paddle.static.nn.increment( - x=step_idx, value=1.0, in_place=False - ), + y=paddle.increment(x=step_idx, value=1.0, in_place=False), axis=0, ) logits = wrap_decoder( @@ -1854,7 +1852,7 @@ def beam_search(): end_id=eos_idx, ) - paddle.static.nn.increment(x=step_idx, value=1.0, in_place=True) + paddle.increment(x=step_idx, value=1.0, in_place=True) # update states layers.array_write(selected_ids, i=step_idx, array=ids) layers.array_write(selected_scores, i=step_idx, array=scores) diff --git a/python/paddle/fluid/tests/unittests/dygraph_to_static/test_loop.py b/python/paddle/fluid/tests/unittests/dygraph_to_static/test_loop.py index 1efb3669d26e9..1f74b508d911a 100644 --- a/python/paddle/fluid/tests/unittests/dygraph_to_static/test_loop.py +++ b/python/paddle/fluid/tests/unittests/dygraph_to_static/test_loop.py @@ -21,7 +21,6 @@ import paddle.fluid as fluid from paddle.jit.api import declarative from paddle.jit.dy2static.loop_transformer import NameVisitor -from paddle.static.nn import increment from paddle.utils import gast SEED = 2020 @@ -84,7 +83,7 @@ def while_loop_dyfunc_with_none(x): def for_loop_dyfunc(max_len): for i in range(max_len): ret = fluid.layers.zeros(shape=[1], dtype='float32') - increment(ret, value=2.0, in_place=True) + paddle.increment(ret, value=2.0, in_place=True) return ret @@ -105,14 +104,14 @@ def for_loop_dyfunc2(max_len): def for_loop_dyfunc3(max_len): ret = fluid.layers.zeros(shape=[1], dtype='float32') for i in range(1, 10, 2): - increment(ret, value=2.0, in_place=True) + paddle.increment(ret, value=2.0, in_place=True) return ret def for_loop_dyfunc4(max_len): ret = fluid.layers.zeros(shape=[1], dtype='float32') for i in range(10, 1, -2): - increment(ret, value=2.0, in_place=True) + paddle.increment(ret, value=2.0, in_place=True) return ret @@ -120,7 +119,7 @@ def for_loop_dyfunc_not_support(max_len): ret = fluid.layers.zeros(shape=[1], dtype='float32') a = -2 for i in range(10, 1, a): - increment(ret, value=2.0, in_place=True) + paddle.increment(ret, value=2.0, in_place=True) return ret diff --git a/python/paddle/fluid/tests/unittests/npu/test_increment_op_npu.py b/python/paddle/fluid/tests/unittests/npu/test_increment_op_npu.py index 542ced34256ae..2467860bd93a7 100644 --- a/python/paddle/fluid/tests/unittests/npu/test_increment_op_npu.py +++ b/python/paddle/fluid/tests/unittests/npu/test_increment_op_npu.py @@ -121,7 +121,7 @@ def test_npu(self): with paddle.static.program_guard(main_prog, startup_prog): a = paddle.static.data(name="a", shape=[1], dtype='float32') - b = paddle.static.nn.increment(a) + b = paddle.increment(a) place = paddle.NPUPlace(NPUPlace) diff --git a/python/paddle/fluid/tests/unittests/npu/test_while_op_npu.py b/python/paddle/fluid/tests/unittests/npu/test_while_op_npu.py index 09186b24e5482..3cbed5d5d683f 100644 --- a/python/paddle/fluid/tests/unittests/npu/test_while_op_npu.py +++ b/python/paddle/fluid/tests/unittests/npu/test_while_op_npu.py @@ -21,7 +21,6 @@ from paddle.fluid.backward import append_backward import numpy from paddle.fluid import compiler, Program, program_guard -from paddle.static.nn import increment paddle.enable_static() @@ -44,9 +43,9 @@ def simple_net(self): init = layers.zeros(shape=[10], dtype='float32') mem_array = layers.array_write(x=init, i=i) data_array = layers.array_write(x=d0, i=i) - i = increment(i) + i = paddle.increment(i) layers.array_write(d1, i, array=data_array) - i = increment(i) + i = paddle.increment(i) layers.array_write(d2, i, array=data_array) i = layers.zeros(shape=[1], dtype='int32') i = layers.cast(i, 'int64') @@ -72,7 +71,7 @@ def simple_net(self): prev = layers.array_read(array=mem_array, i=i) result = layers.sums(input=[d, prev]) - i = increment(x=i, in_place=True) + i = paddle.increment(x=i, in_place=True) layers.array_write(result, i=i, array=mem_array) paddle.assign(paddle.less_than(x=i, y=array_len), cond) @@ -81,7 +80,7 @@ def simple_net(self): prev2 = layers.array_read(array=mem_array, i=j) result2 = layers.sums(input=[d2, prev2]) - j = increment(x=j, in_place=True) + j = paddle.increment(x=j, in_place=True) layers.array_write(result2, i=j, array=mem_array) paddle.assign(paddle.less_than(x=j, y=array_len2), cond2) sum_result = layers.array_read(array=mem_array, i=j) diff --git a/python/paddle/fluid/tests/unittests/test_array_read_write_op.py b/python/paddle/fluid/tests/unittests/test_array_read_write_op.py index 8f6f3bd58dd49..d60239a8ad169 100644 --- a/python/paddle/fluid/tests/unittests/test_array_read_write_op.py +++ b/python/paddle/fluid/tests/unittests/test_array_read_write_op.py @@ -24,24 +24,23 @@ from paddle.fluid.backward import append_backward from paddle.fluid.executor import Executor from paddle.fluid.framework import default_main_program -from paddle.static.nn import increment def _test_read_write(x): i = layers.zeros(shape=[1], dtype='int64') i.stop_gradient = False arr = layers.array_write(x=x[0], i=i) - i = increment(x=i) + i = paddle.increment(x=i) arr = layers.array_write(x=x[1], i=i, array=arr) - i = increment(x=i) + i = paddle.increment(x=i) arr = layers.array_write(x=x[2], i=i, array=arr) i = layers.zeros(shape=[1], dtype='int64') i.stop_gradient = False a0 = layers.array_read(array=arr, i=i) - i = increment(x=i) + i = paddle.increment(x=i) a1 = layers.array_read(array=arr, i=i) - i = increment(x=i) + i = paddle.increment(x=i) a2 = layers.array_read(array=arr, i=i) mean_a0 = paddle.mean(a0) diff --git a/python/paddle/fluid/tests/unittests/test_async_ssa_graph_executor_mnist.py b/python/paddle/fluid/tests/unittests/test_async_ssa_graph_executor_mnist.py index 45a743ed7e44d..4ccff076149df 100644 --- a/python/paddle/fluid/tests/unittests/test_async_ssa_graph_executor_mnist.py +++ b/python/paddle/fluid/tests/unittests/test_async_ssa_graph_executor_mnist.py @@ -62,7 +62,7 @@ def convolutional_neural_network(use_py_reader): acc = paddle.static.accuracy(input=prediction, label=label) i = fluid.layers.zeros(shape=[1], dtype='int64') array = fluid.layers.array_write(x=prediction, i=i) - paddle.static.nn.increment(i) + paddle.increment(i) fluid.layers.array_write(x=acc, i=i, array=array) return array, img, label, prediction, avg_loss, acc, py_reader diff --git a/python/paddle/fluid/tests/unittests/test_dynamic_rnn_stop_gradient.py b/python/paddle/fluid/tests/unittests/test_dynamic_rnn_stop_gradient.py index 1fb0ffe7015a0..89b7a2d73f294 100644 --- a/python/paddle/fluid/tests/unittests/test_dynamic_rnn_stop_gradient.py +++ b/python/paddle/fluid/tests/unittests/test_dynamic_rnn_stop_gradient.py @@ -53,7 +53,7 @@ def build_and_run_program(place, batch_size, beam_size, stop_gradient=False): topk_coordinates = paddle.stack([batch_pos, indices], axis=2) topk_coordinates.stop_gradient = stop_gradient score = paddle.gather_nd(x, topk_coordinates) - paddle.static.nn.increment(x=step_idx, value=1.0, in_place=True) + paddle.increment(x=step_idx, value=1.0, in_place=True) layers.array_write(score, i=step_idx, array=scores) length_cond = paddle.less_than(x=step_idx, y=max_len) layers.assign(length_cond, cond) diff --git a/python/paddle/fluid/tests/unittests/test_eager_deletion_while_op.py b/python/paddle/fluid/tests/unittests/test_eager_deletion_while_op.py index 5f304acc733fb..385f61388db94 100644 --- a/python/paddle/fluid/tests/unittests/test_eager_deletion_while_op.py +++ b/python/paddle/fluid/tests/unittests/test_eager_deletion_while_op.py @@ -27,7 +27,6 @@ import paddle.fluid.core as core import paddle.fluid.layers as layers from paddle.fluid.executor import Executor -from paddle.static.nn import increment paddle.enable_static() fluid.core._set_eager_deletion_mode(0.0, 1.0, True) @@ -84,10 +83,10 @@ def run_main(self, place, with_data_parallel): mem_array = layers.array_write(x=init, i=i) data_array = layers.array_write(x=d0, i=i) - i = increment(i) + i = paddle.increment(i) layers.array_write(d1, i, array=data_array) - i = increment(i) + i = paddle.increment(i) layers.array_write(d2, i, array=data_array) i = layers.zeros(shape=[1], dtype='int64') @@ -113,7 +112,7 @@ def run_main(self, place, with_data_parallel): prev = paddle.reshape(prev, shape=[10]) result = layers.sums(input=[d, prev]) - i = increment(x=i, in_place=True) + i = paddle.increment(x=i, in_place=True) layers.array_write(result, i=i, array=mem_array) paddle.assign(paddle.less_than(x=i, y=array_len), cond) with while_op2.block(): @@ -123,7 +122,7 @@ def run_main(self, place, with_data_parallel): prev2 = paddle.reshape(prev2, shape=[10]) result2 = layers.sums(input=[d2, prev2]) - j = increment(x=j, in_place=True) + j = paddle.increment(x=j, in_place=True) layers.array_write(result2, i=j, array=mem_array) paddle.assign(paddle.less_than(x=j, y=array_len2), cond2) diff --git a/python/paddle/fluid/tests/unittests/test_executor_and_mul.py b/python/paddle/fluid/tests/unittests/test_executor_and_mul.py index 265e612a13a98..bf54cef74b988 100644 --- a/python/paddle/fluid/tests/unittests/test_executor_and_mul.py +++ b/python/paddle/fluid/tests/unittests/test_executor_and_mul.py @@ -16,9 +16,9 @@ import numpy as np +import paddle from paddle.fluid.executor import Executor from paddle.fluid.layers import array_write, data, mul, zeros -from paddle.static.nn import increment class TestExecutor(unittest.TestCase): @@ -27,13 +27,13 @@ def test_mul(self): a = data(name='a', shape=[784], dtype='float32') array = array_write(x=a, i=i) - i = increment(i) + i = paddle.increment(i) b = data( name='b', shape=[784, 100], dtype='float32', append_batch_size=False ) array_write(x=b, i=i, array=array) - i = increment(i) + i = paddle.increment(i) out = mul(x=a, y=b) array_write(x=out, i=i, array=array) diff --git a/python/paddle/fluid/tests/unittests/test_fetch_lod_tensor_array.py b/python/paddle/fluid/tests/unittests/test_fetch_lod_tensor_array.py index 8ca1a4d118fda..a55ecbad35b40 100644 --- a/python/paddle/fluid/tests/unittests/test_fetch_lod_tensor_array.py +++ b/python/paddle/fluid/tests/unittests/test_fetch_lod_tensor_array.py @@ -18,9 +18,9 @@ import numpy as np from simple_nets import simple_fc_net, simple_fc_net_with_inputs +import paddle import paddle.fluid as fluid import paddle.fluid.layers as layers -from paddle.static.nn import increment class TestFetchLoDTensorArray(unittest.TestCase): @@ -36,9 +36,9 @@ def build_program(self, main_program, startup_program): opt.minimize(loss) array = layers.array_write(x=img, i=i) - i = increment(i) + i = paddle.increment(i) layers.array_write(x=label, i=i, array=array) - i = increment(i) + i = paddle.increment(i) layers.array_write(x=loss, i=i, array=array) return loss, array diff --git a/python/paddle/fluid/tests/unittests/test_profiler.py b/python/paddle/fluid/tests/unittests/test_profiler.py index d0bf4180e798a..3413b6b3d1def 100644 --- a/python/paddle/fluid/tests/unittests/test_profiler.py +++ b/python/paddle/fluid/tests/unittests/test_profiler.py @@ -50,7 +50,7 @@ def build_program(self, compile_program=True): with while_op.block(): hidden_n = fluid.layers.fc(input=hidden1, size=64, act='relu') layers.array_write(hidden_n, i, data_arr) - paddle.static.nn.increment(x=counter, value=1, in_place=True) + paddle.increment(x=counter, value=1, in_place=True) paddle.assign(paddle.less_than(x=counter, y=until), cond) hidden_n = layers.array_read(data_arr, i) diff --git a/python/paddle/fluid/tests/unittests/test_while_loop_op.py b/python/paddle/fluid/tests/unittests/test_while_loop_op.py index b36e595526c83..792387c76fd53 100644 --- a/python/paddle/fluid/tests/unittests/test_while_loop_op.py +++ b/python/paddle/fluid/tests/unittests/test_while_loop_op.py @@ -22,7 +22,6 @@ import paddle.fluid.layers as layers from paddle.fluid.backward import append_backward from paddle.fluid.framework import Program, program_guard -from paddle.static.nn import increment paddle.enable_static() @@ -60,7 +59,7 @@ def cond(i, mem): def body(i, mem): mem = paddle.add(x=mem, y=one) - i = increment(i) + i = paddle.increment(i) return [i, mem] main_program = Program() @@ -101,7 +100,7 @@ def body(i, ten, test_dict, test_list, test_list_dict): test_list_dict[0]["test_key"] ) - i = increment(i) + i = paddle.increment(i) return [i, ten, test_dict, test_list, test_list_dict] main_program = Program() @@ -175,7 +174,7 @@ def internal_cond(j, init, sums): def internal_body(j, init, sums): init = paddle.add(x=init, y=ones) sums = paddle.add(x=init, y=sums) - j = increment(j) + j = paddle.increment(j) return [j, init, sums] result = paddle.static.nn.while_loop( @@ -185,7 +184,7 @@ def internal_body(j, init, sums): init = result[1] sums = result[2] sums = paddle.add(x=init, y=sums) - i = increment(i) + i = paddle.increment(i) return [i, j, init, sums] main_program = Program() @@ -230,7 +229,7 @@ def cond(i, x): def body(i, x): x = paddle.multiply(x=i, y=i) - i = increment(i) + i = paddle.increment(i) return [i, x] main_program = Program() @@ -325,7 +324,7 @@ def internal_body(j, x, mem_array): inner_prev = layers.array_read(array=mem_array, i=j) inner_sum_0 = paddle.add(x=inner_data, y=inner_prev) inner_sum_1 = paddle.add(x=x, y=inner_sum_0) - j = increment(x=j, in_place=True) + j = paddle.increment(x=j, in_place=True) layers.array_write(inner_sum_1, i=j, array=mem_array) return [j, x, mem_array] @@ -333,7 +332,7 @@ def internal_body(j, x, mem_array): outer_prev = layers.array_read(array=mem_array, i=i) outer_sum_0 = paddle.add(x=outer_data, y=outer_prev) outer_sum_1 = paddle.add(x=x, y=outer_sum_0) - i = increment(x=i, in_place=True) + i = paddle.increment(x=i, in_place=True) layers.array_write(outer_sum_1, i=i, array=mem_array) j, x, mem_array = paddle.static.nn.while_loop( internal_cond, internal_body, [j, x, mem_array] @@ -353,9 +352,9 @@ def internal_body(j, x, mem_array): init = layers.zeros(shape=[10], dtype='float32') mem_array = layers.array_write(x=init, i=i) data_array = layers.array_write(x=d0, i=i) - i = increment(i) + i = paddle.increment(i) layers.array_write(d1, i, array=data_array) - i = increment(i) + i = paddle.increment(i) layers.array_write(d2, i, array=data_array) i = layers.zeros(shape=[1], dtype='int64') i.stop_gradient = True @@ -445,7 +444,7 @@ def cond_returns_constant(i): return 1 def cond_returns_not_bool_tensor(i): - return increment(i) + return paddle.increment(i) def cond_returns_bool_tensor(i): return paddle.less_than(i, ten) @@ -457,14 +456,14 @@ def cond_receives_two_args(i, ten): return paddle.less_than(i, ten) def body(i): - return increment(i) + return paddle.increment(i) def body_returns_error_length(i): - i = increment(i) + i = paddle.increment(i) return [i, i] def body_returns_error_type(i, ten): - return increment(i) + return paddle.increment(i) def cond_returns_with_mutable_dict(i, test_dict): return i > 0 @@ -473,7 +472,7 @@ def body_returns_with_mutable_dict(i, test_dict): test_dict['new_key'] = layers.fill_constant( shape=[1], dtype='int64', value=1 ) - return increment(i), test_dict + return paddle.increment(i), test_dict def cond_returns_with_mutable_list(i, test_list): return i > 0 @@ -482,7 +481,7 @@ def body_returns_with_mutable_list(i, test_list): test_list.append( layers.fill_constant(shape=[1], dtype='int64', value=1) ) - return increment(i), test_list + return paddle.increment(i), test_list main_program = Program() startup_program = Program() diff --git a/python/paddle/fluid/tests/unittests/test_while_op.py b/python/paddle/fluid/tests/unittests/test_while_op.py index 638a89ef79d76..79e9ffbc2ffd8 100644 --- a/python/paddle/fluid/tests/unittests/test_while_op.py +++ b/python/paddle/fluid/tests/unittests/test_while_op.py @@ -22,7 +22,6 @@ import paddle.fluid.layers as layers from paddle.fluid.backward import append_backward from paddle.fluid.executor import Executor -from paddle.static.nn import increment paddle.enable_static() @@ -43,9 +42,9 @@ def simple_net(self): init = layers.zeros(shape=[10], dtype='float32') mem_array = layers.array_write(x=init, i=i) data_array = layers.array_write(x=d0, i=i) - i = increment(i) + i = paddle.increment(i) layers.array_write(d1, i, array=data_array) - i = increment(i) + i = paddle.increment(i) layers.array_write(d2, i, array=data_array) i = layers.zeros(shape=[1], dtype='int64') i.stop_gradient = True @@ -64,7 +63,7 @@ def simple_net(self): prev = layers.array_read(array=mem_array, i=i) result = layers.sums(input=[d, prev]) - i = increment(x=i, in_place=True) + i = paddle.increment(x=i, in_place=True) layers.array_write(result, i=i, array=mem_array) paddle.assign(paddle.less_than(x=i, y=array_len), cond) @@ -73,7 +72,7 @@ def simple_net(self): prev2 = layers.array_read(array=mem_array, i=j) result2 = layers.sums(input=[d2, prev2]) - j = increment(x=j, in_place=True) + j = paddle.increment(x=j, in_place=True) layers.array_write(result2, i=j, array=mem_array) paddle.assign(paddle.less_than(x=j, y=array_len2), cond2) sum_result = layers.array_read(array=mem_array, i=j) @@ -135,7 +134,7 @@ def test_error(self): def test_bad_x(): x = [1, 2, 3] - increment(x) + paddle.increment(x) self.assertRaises(TypeError, test_bad_x) diff --git a/python/paddle/fluid/tests/unittests/xpu/test_while_op_xpu.py b/python/paddle/fluid/tests/unittests/xpu/test_while_op_xpu.py index 1f8c759d46b8c..2d3253295d0e7 100644 --- a/python/paddle/fluid/tests/unittests/xpu/test_while_op_xpu.py +++ b/python/paddle/fluid/tests/unittests/xpu/test_while_op_xpu.py @@ -21,7 +21,6 @@ import paddle.fluid.layers as layers from paddle.fluid.backward import append_backward from paddle.fluid.executor import Executor -from paddle.static.nn import increment paddle.enable_static() @@ -42,9 +41,9 @@ def simple_net(self): init = layers.zeros(shape=[10], dtype='float32') mem_array = layers.array_write(x=init, i=i) data_array = layers.array_write(x=d0, i=i) - i = increment(i) + i = paddle.increment(i) layers.array_write(d1, i, array=data_array) - i = increment(i) + i = paddle.increment(i) layers.array_write(d2, i, array=data_array) i = layers.zeros(shape=[1], dtype='int64') i.stop_gradient = True @@ -63,7 +62,7 @@ def simple_net(self): prev = layers.array_read(array=mem_array, i=i) result = layers.sums(input=[d, prev]) - i = increment(x=i, in_place=True) + i = paddle.increment(x=i, in_place=True) layers.array_write(result, i=i, array=mem_array) paddle.assign(paddle.less_than(x=i, y=array_len), cond) @@ -72,7 +71,7 @@ def simple_net(self): prev2 = layers.array_read(array=mem_array, i=j) result2 = layers.sums(input=[d2, prev2]) - j = increment(x=j, in_place=True) + j = paddle.increment(x=j, in_place=True) layers.array_write(result2, i=j, array=mem_array) paddle.assign(paddle.less_than(x=j, y=array_len2), cond2) sum_result = layers.array_read(array=mem_array, i=j) diff --git a/python/paddle/jit/dy2static/convert_operators.py b/python/paddle/jit/dy2static/convert_operators.py index fe9cd827d728c..1a814086f5790 100644 --- a/python/paddle/jit/dy2static/convert_operators.py +++ b/python/paddle/jit/dy2static/convert_operators.py @@ -787,9 +787,7 @@ def body(i, new_array): item = array_read(array=array, i=i) array_write(item, paddle.tensor.array_length(new_array), new_array) - from paddle.static.nn import increment - - i = increment(i) + i = paddle.increment(i) return i, new_array arr_len = paddle.tensor.array_length(array) diff --git a/python/paddle/static/nn/__init__.py b/python/paddle/static/nn/__init__.py index 7cefb7f5a5132..f446769837eb6 100755 --- a/python/paddle/static/nn/__init__.py +++ b/python/paddle/static/nn/__init__.py @@ -58,7 +58,7 @@ from ...fluid.layers.sequence_lod import sequence_enumerate # noqa: F401 from ...fluid.layers.sequence_lod import sequence_reverse # noqa: F401 -from .control_flow import Assert, increment, cond +from .control_flow import cond __all__ = [ # noqa 'fc', @@ -102,6 +102,4 @@ 'sequence_reverse', 'StaticRNN', 'prelu', - 'Assert', - 'increment', ] diff --git a/python/paddle/static/nn/control_flow.py b/python/paddle/static/nn/control_flow.py index e7f1903ccf0aa..d331dd419fada 100644 --- a/python/paddle/static/nn/control_flow.py +++ b/python/paddle/static/nn/control_flow.py @@ -17,14 +17,12 @@ import paddle import paddle.fluid.core as core -from paddle import _C_ops from paddle.common_ops_import import ( LayerHelper, _non_static_mode, check_type, check_variable_and_dtype, convert_dtype, - in_dygraph_mode, ) from paddle.fluid.framework import Operator, Program, Variable @@ -42,12 +40,6 @@ to_sequence, ) -__all__ = [ - 'Assert', - 'increment', - 'cond', -] - def Assert(cond, data=None, summarize=20, name=None): ''' @@ -119,49 +111,6 @@ def Assert(cond, data=None, summarize=20, name=None): return op -def increment(x, value=1.0, in_place=True): - """ - This API is usually used for control flow to increment the data of :attr:`x` by an amount :attr:`value`. - Notice that the number of elements in :attr:`x` must be equal to 1. - - Parameters: - x (Variable): A tensor that must always contain only one element, its data type supports - float32, float64, int32 and int64. - value (float, optional): The amount to increment the data of :attr:`x`. Default: 1.0. - in_place (bool, optional): Whether the OP should be performed in-place. Default: True. - - Returns: - Variable: The elementwise-incremented tensor with the same shape and data type as :attr:`x`. - - Examples: - .. code-block:: python - - import paddle - from paddle.static.nn.control_flow import increment - - counter = paddle.zeros(shape=[1], dtype='float32') # [0.] - increment(counter) # [1.] - """ - if in_dygraph_mode(): - return _C_ops.increment_(x, value) - - check_variable_and_dtype( - x, 'x', ['float32', 'float64', 'int32', 'int64'], 'increment' - ) - helper = LayerHelper("increment", **locals()) - if not in_place: - out = helper.create_variable_for_type_inference(dtype=x.dtype) - else: - out = x - helper.append_op( - type='increment', - inputs={'X': [x]}, - outputs={'Out': [out]}, - attrs={'step': float(value)}, - ) - return out - - class BlockGuard: """ BlockGuard class. From afb67469f00e0209a64b3e20f3b6fcf721498b9d Mon Sep 17 00:00:00 2001 From: feifei-111 <2364819892@qq.com> Date: Fri, 9 Dec 2022 08:30:15 +0000 Subject: [PATCH 16/16] fix conflict --- .../distributed/fleet/utils/hybrid_parallel_inference.py | 4 ++-- python/paddle/fluid/layers/control_flow.py | 4 ++-- python/paddle/fluid/layers/rnn.py | 4 ++-- python/paddle/fluid/optimizer.py | 4 ++-- .../unittests/auto_parallel/test_while_op_partition.py | 2 +- .../collective/fleet/hybrid_parallel_inference_helper.py | 2 +- python/paddle/fluid/tests/unittests/dist_transformer.py | 4 ++-- .../fluid/tests/unittests/dygraph_to_static/test_loop.py | 8 ++++---- .../paddle/fluid/tests/unittests/npu/test_while_op_npu.py | 4 ++-- python/paddle/fluid/tests/unittests/test_assert_op.py | 2 +- .../tests/unittests/test_dynamic_rnn_stop_gradient.py | 2 +- .../fluid/tests/unittests/test_eager_deletion_while_op.py | 4 ++-- python/paddle/fluid/tests/unittests/test_profiler.py | 2 +- python/paddle/fluid/tests/unittests/test_while_loop_op.py | 4 ++-- python/paddle/fluid/tests/unittests/test_while_op.py | 4 ++-- .../paddle/fluid/tests/unittests/xpu/test_while_op_xpu.py | 4 ++-- python/paddle/jit/dy2static/convert_operators.py | 2 +- python/paddle/static/nn/control_flow.py | 2 +- 18 files changed, 31 insertions(+), 31 deletions(-) diff --git a/python/paddle/distributed/fleet/utils/hybrid_parallel_inference.py b/python/paddle/distributed/fleet/utils/hybrid_parallel_inference.py index f5010e815c37b..8085ac077c311 100644 --- a/python/paddle/distributed/fleet/utils/hybrid_parallel_inference.py +++ b/python/paddle/distributed/fleet/utils/hybrid_parallel_inference.py @@ -64,7 +64,7 @@ class HybridParallelInferenceHelper: element_in_arr = layers.array_read(array=arr, i=step_idx) # write placehold data to global lod_tensor_array, # it need for send_v2 of lod_tensor_array - paddle.increment(x=step_idx, value=1.0, in_place=True) + paddle.increment(x=step_idx, value=1.0) layers.array_write(element_in_arr, i=step_idx, array=arr) with paddle.fluid.device_guard(f'{device}:0'): @@ -137,7 +137,7 @@ class HybridParallelInferenceHelper: with while_op.block(): with paddle.fluid.device_guard(f'{device}:all'): input = layers.array_read(array=data, i=step_idx) - paddle.increment(x=step_idx, value=1.0, in_place=True) + paddle.increment(x=step_idx, value=1.0) layers.array_write(input, i=step_idx, array=data) with paddle.fluid.device_guard(f'{device}:0'): diff --git a/python/paddle/fluid/layers/control_flow.py b/python/paddle/fluid/layers/control_flow.py index 7ad3407db4330..ed15416fd35e3 100755 --- a/python/paddle/fluid/layers/control_flow.py +++ b/python/paddle/fluid/layers/control_flow.py @@ -1063,7 +1063,7 @@ class While: cond = paddle.less_than(x=i, y=loop_len) while_op = fluid.layers.While(cond=cond) with while_op.block(): - i = paddle.increment(x=i, value=1, in_place=True) + i = paddle.increment(x=i, value=1) paddle.assign(paddle.less_than(x=i, y=loop_len), cond) exe = fluid.Executor(fluid.CPUPlace()) @@ -1092,7 +1092,7 @@ class While: with while_op.block(): sums_tensor = fluid.layers.elementwise_add(x=data, y=data) fluid.layers.assign(sums_tensor, sums) # Update the value of sums_tensor defined in While to the sums which defined outside of While through layers.assign - i = paddle.increment(x=i, value=1, in_place=True) + i = paddle.increment(x=i, value=1) data = fluid.layers.elementwise_add(x=data, y=one) paddle.assign(paddle.less_than(x=i, y=loop_len), cond) diff --git a/python/paddle/fluid/layers/rnn.py b/python/paddle/fluid/layers/rnn.py index 0b03fb97183d9..f03ceb4b1bbf4 100644 --- a/python/paddle/fluid/layers/rnn.py +++ b/python/paddle/fluid/layers/rnn.py @@ -907,7 +907,7 @@ def _maybe_copy(state, new_state, step_mask): next_sequence_lengths, ) - paddle.increment(x=step_idx_tensor, value=1.0, in_place=True) + paddle.increment(x=step_idx_tensor, value=1.0) step_idx += 1 cond = paddle.logical_not(paddle.all(finished)) @@ -1067,7 +1067,7 @@ def _create_array_out_of_while(dtype): outputs_arrays, ) - paddle.increment(x=step_idx, value=1.0, in_place=True) + paddle.increment(x=step_idx, value=1.0) # update the global_finished first, since it might be also in states of # decoder, which otherwise would write a stale finished status to array tensor.assign(next_finished, global_finished) diff --git a/python/paddle/fluid/optimizer.py b/python/paddle/fluid/optimizer.py index 2a2141a2e1ca1..550ea608c0465 100755 --- a/python/paddle/fluid/optimizer.py +++ b/python/paddle/fluid/optimizer.py @@ -7299,7 +7299,7 @@ def minimize(self, loss, startup_program=None): dtype='int32', persistable=True, ) - paddle.increment(x=step, value=1.0, in_place=True) + paddle.increment(x=step, value=1.0) # lookahead zero_var = layers.fill_constant( @@ -7533,7 +7533,7 @@ def _get_gm_cond_var(self, main_block): with device_guard("cpu"): # step_var = (step_var + 1) % k_step - paddle.increment(x=step_var, value=1.0, in_place=True) + paddle.increment(x=step_var, value=1.0) main_block.append_op( type='elementwise_mod', inputs={'X': step_var, 'Y': k_step_var}, diff --git a/python/paddle/fluid/tests/unittests/auto_parallel/test_while_op_partition.py b/python/paddle/fluid/tests/unittests/auto_parallel/test_while_op_partition.py index 6e59cf16eafe8..8b0f746aa6576 100644 --- a/python/paddle/fluid/tests/unittests/auto_parallel/test_while_op_partition.py +++ b/python/paddle/fluid/tests/unittests/auto_parallel/test_while_op_partition.py @@ -189,7 +189,7 @@ def get_program(): cur_pred = mlp_while(pre_input) # 更新循环条件 - i = paddle.increment(x=i, value=1, in_place=True) + i = paddle.increment(x=i, value=1) fluid.layers.array_write(cur_pred, array=input_array, i=i) paddle.assign(paddle.less_than(x=i, y=loop_len), cond) diff --git a/python/paddle/fluid/tests/unittests/collective/fleet/hybrid_parallel_inference_helper.py b/python/paddle/fluid/tests/unittests/collective/fleet/hybrid_parallel_inference_helper.py index 75e7e708ef4a9..44bcbb6e70908 100644 --- a/python/paddle/fluid/tests/unittests/collective/fleet/hybrid_parallel_inference_helper.py +++ b/python/paddle/fluid/tests/unittests/collective/fleet/hybrid_parallel_inference_helper.py @@ -91,7 +91,7 @@ def test_hybrid_parallel_inference_helper_mp1pp2(self): with while_op.block(): with paddle.fluid.device_guard(f'{device}:all'): input = layers.array_read(array=data, i=step_idx) - paddle.increment(x=step_idx, value=1.0, in_place=True) + paddle.increment(x=step_idx, value=1.0) layers.array_write(input, i=step_idx, array=data) with paddle.fluid.device_guard(f'{device}:0'): diff --git a/python/paddle/fluid/tests/unittests/dist_transformer.py b/python/paddle/fluid/tests/unittests/dist_transformer.py index d282ea7858c93..cb986dfabbbfd 100644 --- a/python/paddle/fluid/tests/unittests/dist_transformer.py +++ b/python/paddle/fluid/tests/unittests/dist_transformer.py @@ -1813,7 +1813,7 @@ def beam_search(): shape=[-1, 1, 1], dtype=pre_ids.dtype, ), - y=paddle.increment(x=step_idx, value=1.0, in_place=False), + y=paddle.increment(x=step_idx, value=1.0), axis=0, ) logits = wrap_decoder( @@ -1852,7 +1852,7 @@ def beam_search(): end_id=eos_idx, ) - paddle.increment(x=step_idx, value=1.0, in_place=True) + paddle.increment(x=step_idx, value=1.0) # update states layers.array_write(selected_ids, i=step_idx, array=ids) layers.array_write(selected_scores, i=step_idx, array=scores) diff --git a/python/paddle/fluid/tests/unittests/dygraph_to_static/test_loop.py b/python/paddle/fluid/tests/unittests/dygraph_to_static/test_loop.py index bde9aea72509d..4d2a70ee1cf4b 100644 --- a/python/paddle/fluid/tests/unittests/dygraph_to_static/test_loop.py +++ b/python/paddle/fluid/tests/unittests/dygraph_to_static/test_loop.py @@ -83,7 +83,7 @@ def while_loop_dyfunc_with_none(x): def for_loop_dyfunc(max_len): for i in range(max_len): ret = fluid.layers.zeros(shape=[1], dtype='float32') - paddle.increment(ret, value=2.0, in_place=True) + paddle.increment(ret, value=2.0) return ret @@ -104,14 +104,14 @@ def for_loop_dyfunc2(max_len): def for_loop_dyfunc3(max_len): ret = fluid.layers.zeros(shape=[1], dtype='float32') for i in range(1, 10, 2): - paddle.increment(ret, value=2.0, in_place=True) + paddle.increment(ret, value=2.0) return ret def for_loop_dyfunc4(max_len): ret = fluid.layers.zeros(shape=[1], dtype='float32') for i in range(10, 1, -2): - paddle.increment(ret, value=2.0, in_place=True) + paddle.increment(ret, value=2.0) return ret @@ -119,7 +119,7 @@ def for_loop_dyfunc_not_support(max_len): ret = fluid.layers.zeros(shape=[1], dtype='float32') a = -2 for i in range(10, 1, a): - paddle.increment(ret, value=2.0, in_place=True) + paddle.increment(ret, value=2.0) return ret diff --git a/python/paddle/fluid/tests/unittests/npu/test_while_op_npu.py b/python/paddle/fluid/tests/unittests/npu/test_while_op_npu.py index 3cbed5d5d683f..c2b5d73b76d95 100644 --- a/python/paddle/fluid/tests/unittests/npu/test_while_op_npu.py +++ b/python/paddle/fluid/tests/unittests/npu/test_while_op_npu.py @@ -71,7 +71,7 @@ def simple_net(self): prev = layers.array_read(array=mem_array, i=i) result = layers.sums(input=[d, prev]) - i = paddle.increment(x=i, in_place=True) + i = paddle.increment(x=i) layers.array_write(result, i=i, array=mem_array) paddle.assign(paddle.less_than(x=i, y=array_len), cond) @@ -80,7 +80,7 @@ def simple_net(self): prev2 = layers.array_read(array=mem_array, i=j) result2 = layers.sums(input=[d2, prev2]) - j = paddle.increment(x=j, in_place=True) + j = paddle.increment(x=j) layers.array_write(result2, i=j, array=mem_array) paddle.assign(paddle.less_than(x=j, y=array_len2), cond2) sum_result = layers.array_read(array=mem_array, i=j) diff --git a/python/paddle/fluid/tests/unittests/test_assert_op.py b/python/paddle/fluid/tests/unittests/test_assert_op.py index a6ce260fb9435..f62ad38d459d1 100644 --- a/python/paddle/fluid/tests/unittests/test_assert_op.py +++ b/python/paddle/fluid/tests/unittests/test_assert_op.py @@ -17,7 +17,7 @@ import paddle import paddle.fluid as fluid import paddle.fluid.layers as layers -from paddle.static.nn import Assert +from paddle.static.nn.control_flow import Assert class TestAssertOp(unittest.TestCase): diff --git a/python/paddle/fluid/tests/unittests/test_dynamic_rnn_stop_gradient.py b/python/paddle/fluid/tests/unittests/test_dynamic_rnn_stop_gradient.py index 89b7a2d73f294..0fae895098083 100644 --- a/python/paddle/fluid/tests/unittests/test_dynamic_rnn_stop_gradient.py +++ b/python/paddle/fluid/tests/unittests/test_dynamic_rnn_stop_gradient.py @@ -53,7 +53,7 @@ def build_and_run_program(place, batch_size, beam_size, stop_gradient=False): topk_coordinates = paddle.stack([batch_pos, indices], axis=2) topk_coordinates.stop_gradient = stop_gradient score = paddle.gather_nd(x, topk_coordinates) - paddle.increment(x=step_idx, value=1.0, in_place=True) + paddle.increment(x=step_idx, value=1.0) layers.array_write(score, i=step_idx, array=scores) length_cond = paddle.less_than(x=step_idx, y=max_len) layers.assign(length_cond, cond) diff --git a/python/paddle/fluid/tests/unittests/test_eager_deletion_while_op.py b/python/paddle/fluid/tests/unittests/test_eager_deletion_while_op.py index 385f61388db94..ce23dcb54e5b0 100644 --- a/python/paddle/fluid/tests/unittests/test_eager_deletion_while_op.py +++ b/python/paddle/fluid/tests/unittests/test_eager_deletion_while_op.py @@ -112,7 +112,7 @@ def run_main(self, place, with_data_parallel): prev = paddle.reshape(prev, shape=[10]) result = layers.sums(input=[d, prev]) - i = paddle.increment(x=i, in_place=True) + i = paddle.increment(x=i) layers.array_write(result, i=i, array=mem_array) paddle.assign(paddle.less_than(x=i, y=array_len), cond) with while_op2.block(): @@ -122,7 +122,7 @@ def run_main(self, place, with_data_parallel): prev2 = paddle.reshape(prev2, shape=[10]) result2 = layers.sums(input=[d2, prev2]) - j = paddle.increment(x=j, in_place=True) + j = paddle.increment(x=j) layers.array_write(result2, i=j, array=mem_array) paddle.assign(paddle.less_than(x=j, y=array_len2), cond2) diff --git a/python/paddle/fluid/tests/unittests/test_profiler.py b/python/paddle/fluid/tests/unittests/test_profiler.py index 3413b6b3d1def..6e5c130ce954f 100644 --- a/python/paddle/fluid/tests/unittests/test_profiler.py +++ b/python/paddle/fluid/tests/unittests/test_profiler.py @@ -50,7 +50,7 @@ def build_program(self, compile_program=True): with while_op.block(): hidden_n = fluid.layers.fc(input=hidden1, size=64, act='relu') layers.array_write(hidden_n, i, data_arr) - paddle.increment(x=counter, value=1, in_place=True) + paddle.increment(x=counter, value=1) paddle.assign(paddle.less_than(x=counter, y=until), cond) hidden_n = layers.array_read(data_arr, i) diff --git a/python/paddle/fluid/tests/unittests/test_while_loop_op.py b/python/paddle/fluid/tests/unittests/test_while_loop_op.py index 792387c76fd53..533429d5b0fc8 100644 --- a/python/paddle/fluid/tests/unittests/test_while_loop_op.py +++ b/python/paddle/fluid/tests/unittests/test_while_loop_op.py @@ -324,7 +324,7 @@ def internal_body(j, x, mem_array): inner_prev = layers.array_read(array=mem_array, i=j) inner_sum_0 = paddle.add(x=inner_data, y=inner_prev) inner_sum_1 = paddle.add(x=x, y=inner_sum_0) - j = paddle.increment(x=j, in_place=True) + j = paddle.increment(x=j) layers.array_write(inner_sum_1, i=j, array=mem_array) return [j, x, mem_array] @@ -332,7 +332,7 @@ def internal_body(j, x, mem_array): outer_prev = layers.array_read(array=mem_array, i=i) outer_sum_0 = paddle.add(x=outer_data, y=outer_prev) outer_sum_1 = paddle.add(x=x, y=outer_sum_0) - i = paddle.increment(x=i, in_place=True) + i = paddle.increment(x=i) layers.array_write(outer_sum_1, i=i, array=mem_array) j, x, mem_array = paddle.static.nn.while_loop( internal_cond, internal_body, [j, x, mem_array] diff --git a/python/paddle/fluid/tests/unittests/test_while_op.py b/python/paddle/fluid/tests/unittests/test_while_op.py index 79e9ffbc2ffd8..d9b8e52172871 100644 --- a/python/paddle/fluid/tests/unittests/test_while_op.py +++ b/python/paddle/fluid/tests/unittests/test_while_op.py @@ -63,7 +63,7 @@ def simple_net(self): prev = layers.array_read(array=mem_array, i=i) result = layers.sums(input=[d, prev]) - i = paddle.increment(x=i, in_place=True) + i = paddle.increment(x=i) layers.array_write(result, i=i, array=mem_array) paddle.assign(paddle.less_than(x=i, y=array_len), cond) @@ -72,7 +72,7 @@ def simple_net(self): prev2 = layers.array_read(array=mem_array, i=j) result2 = layers.sums(input=[d2, prev2]) - j = paddle.increment(x=j, in_place=True) + j = paddle.increment(x=j) layers.array_write(result2, i=j, array=mem_array) paddle.assign(paddle.less_than(x=j, y=array_len2), cond2) sum_result = layers.array_read(array=mem_array, i=j) diff --git a/python/paddle/fluid/tests/unittests/xpu/test_while_op_xpu.py b/python/paddle/fluid/tests/unittests/xpu/test_while_op_xpu.py index 2d3253295d0e7..d627b8fb35d72 100644 --- a/python/paddle/fluid/tests/unittests/xpu/test_while_op_xpu.py +++ b/python/paddle/fluid/tests/unittests/xpu/test_while_op_xpu.py @@ -62,7 +62,7 @@ def simple_net(self): prev = layers.array_read(array=mem_array, i=i) result = layers.sums(input=[d, prev]) - i = paddle.increment(x=i, in_place=True) + i = paddle.increment(x=i) layers.array_write(result, i=i, array=mem_array) paddle.assign(paddle.less_than(x=i, y=array_len), cond) @@ -71,7 +71,7 @@ def simple_net(self): prev2 = layers.array_read(array=mem_array, i=j) result2 = layers.sums(input=[d2, prev2]) - j = paddle.increment(x=j, in_place=True) + j = paddle.increment(x=j) layers.array_write(result2, i=j, array=mem_array) paddle.assign(paddle.less_than(x=j, y=array_len2), cond2) sum_result = layers.array_read(array=mem_array, i=j) diff --git a/python/paddle/jit/dy2static/convert_operators.py b/python/paddle/jit/dy2static/convert_operators.py index 1a814086f5790..9e39c6df445f3 100644 --- a/python/paddle/jit/dy2static/convert_operators.py +++ b/python/paddle/jit/dy2static/convert_operators.py @@ -732,7 +732,7 @@ def convert_assert(cond, message=""): if isinstance(cond, Variable): cond = cast(cond, "bool") # NOTE: message is not used because Paddle Assert has no corresponding parameter to use. - from paddle.static.nn import Assert + from paddle.static.nn.control_flow import Assert return Assert(cond) else: diff --git a/python/paddle/static/nn/control_flow.py b/python/paddle/static/nn/control_flow.py index d331dd419fada..3b2ae2537cded 100644 --- a/python/paddle/static/nn/control_flow.py +++ b/python/paddle/static/nn/control_flow.py @@ -66,7 +66,7 @@ def Assert(cond, data=None, summarize=20, name=None): .. code-block:: python import paddle - from paddle.static.nn import Assert + from paddle.static.nn.control_flow import Assert paddle.enable_static() x = paddle.full([2, 3], 2.0, 'float32')