From 0b2ec49ff9e7f249ffc94b9f6c99acf8842056eb Mon Sep 17 00:00:00 2001 From: wangchaochaohu Date: Fri, 10 Jul 2020 17:57:19 +0800 Subject: [PATCH] refine the linspace Op for API 2.0 test=develop (#25284) --- python/paddle/fluid/layers/tensor.py | 33 ++++--- .../fluid/tests/unittests/test_linspace.py | 36 +++---- python/paddle/tensor/creation.py | 94 +------------------ 3 files changed, 38 insertions(+), 125 deletions(-) diff --git a/python/paddle/fluid/layers/tensor.py b/python/paddle/fluid/layers/tensor.py index 5bae5a8c62a..e6a2d1ca86f 100644 --- a/python/paddle/fluid/layers/tensor.py +++ b/python/paddle/fluid/layers/tensor.py @@ -1387,7 +1387,7 @@ def range(start, end, step, dtype): return out -def linspace(start, stop, num, dtype): +def linspace(start, stop, num, dtype=None, name=None): """ This OP return fixed number of evenly spaced values within a given interval. @@ -1398,7 +1398,10 @@ def linspace(start, stop, num, dtype): or a tensor of shape [1] with input data type float32, float64. num(int|Variable): The input :attr:`num` is given num of the sequence. It is an int scalar, \ or a tensor of shape [1] with type int32. - dtype(string): The data type of output tensor, it could be 'float32' and 'float64'. + dtype(np.dtype|core.VarDesc.VarType|str): The data type of output tensor, it could be 'float32' and 'float64'. + Default: if None, the data type is `float32`. + name(str, optional): Normally there is no need for user to set this property. + For more information, please refer to :ref:`api_guide_Name`.Default: None. Returns: Variable, the output data type will be float32, float64.: The 1-D tensor with fixed number of evenly spaced values, \ @@ -1413,27 +1416,23 @@ def linspace(start, stop, num, dtype): data = fluid.layers.linspace(0, 10, 1, 'float32') # [0.0] """ - helper = LayerHelper("linspace", **locals()) - - check_type(start, 'start', (Variable, float, int), linspace) - check_type(stop, 'stop', (Variable, float, int), linspace) - check_type(num, 'num', (Variable, float, int), linspace) - + if dtype is None: + dtype = 'float32' if not isinstance(start, Variable): start = fill_constant([1], dtype, start) - else: - check_variable_and_dtype(start, "start", ["float32", "float64"], - "linspace") - if not isinstance(stop, Variable): stop = fill_constant([1], dtype, stop) - else: - check_variable_and_dtype(stop, "stop", ["float32", "float64"], - "linspace") if not isinstance(num, Variable): num = fill_constant([1], 'int32', num) - else: - check_variable_and_dtype(num, "num", ["int32"], "linspace") + if in_dygraph_mode(): + return core.ops.linspace(start, stop, num) + + helper = LayerHelper("linspace", **locals()) + + check_dtype(start.dtype, 'start', ['float32', 'float64'], 'linspace') + check_dtype(stop.dtype, 'stop', ['float32', 'float64'], 'linspace') + check_dtype(num.dtype, 'num', ['int32', 'int64'], 'linspace') + check_dtype(dtype, 'dtype', ['float32', 'float64'], 'linspace') out = helper.create_variable_for_type_inference(dtype=start.dtype) diff --git a/python/paddle/fluid/tests/unittests/test_linspace.py b/python/paddle/fluid/tests/unittests/test_linspace.py index 7d034d224dd..c7bab1a135b 100644 --- a/python/paddle/fluid/tests/unittests/test_linspace.py +++ b/python/paddle/fluid/tests/unittests/test_linspace.py @@ -20,6 +20,7 @@ from op_test import OpTest import paddle import paddle.fluid as fluid from paddle.fluid import compiler, Program, program_guard +from paddle.fluid import core class TestLinspaceOpCommonCase(OpTest): @@ -71,33 +72,36 @@ class TestLinspaceOpNumOneCase(OpTest): class TestLinspaceAPI(unittest.TestCase): - def test_out(self): - with program_guard(fluid.Program()): - out_1 = fluid.data(name="out_1", shape=[5], dtype="float32") - out_2 = paddle.tensor.linspace(0, 10, 5, dtype='float32', out=out_1) - exe = fluid.Executor(place=fluid.CPUPlace()) - ipt = {'out_1': np.random.random([5]).astype('float32')} - res_1, res_2 = exe.run(fluid.default_main_program(), - feed=ipt, - fetch_list=[out_1, out_2]) - assert np.array_equal(res_1, res_2) + def test_dtype(self): + out_1 = paddle.linspace(0, 10, 5, dtype='float32') + out_2 = paddle.linspace(0, 10, 5, dtype=np.float32) + out_3 = paddle.linspace(0, 10, 5, dtype=core.VarDesc.VarType.FP32) + exe = fluid.Executor(place=fluid.CPUPlace()) + res_1, res_2, res_3 = exe.run(fluid.default_main_program(), + fetch_list=[out_1, out_2, out_3]) + assert np.array_equal(res_1, res_2) def test_name(self): - with fluid.program_guard(fluid.Program()): + with paddle.program_guard(paddle.Program()): out = paddle.linspace( 0, 10, 5, dtype='float32', name='linspace_res') assert 'linspace_res' in out.name + def test_imperative(self): + with paddle.imperative.guard(): + out = paddle.linspace(0, 10, 5, dtype='float32') + np_out = np.linspace(0, 10, 5, dtype='float32') + self.assertEqual((out.numpy() == np_out).all(), True) + class TestLinspaceOpError(unittest.TestCase): def test_errors(self): with program_guard(Program(), Program()): - # for ci coverage - # The device of fill_constant must be in 'cpu', 'gpu' or None - def test_device_value(): - paddle.linspace(0, 10, 1, dtype="float32", device='xxxpu') - self.assertRaises(ValueError, test_device_value) + def test_dtype(): + fluid.layers.linspace(0, 10, 1, dtype="int32") + + self.assertRaises(TypeError, test_dtype) def test_start_type(): fluid.layers.linspace([0], 10, 1, dtype="float32") diff --git a/python/paddle/tensor/creation.py b/python/paddle/tensor/creation.py index 6ae1eb5d750..36490731967 100644 --- a/python/paddle/tensor/creation.py +++ b/python/paddle/tensor/creation.py @@ -27,8 +27,8 @@ from ..fluid.layers import crop_tensor #DEFINE_ALIAS from ..fluid.layers import diag #DEFINE_ALIAS from ..fluid.layers import eye #DEFINE_ALIAS from ..fluid.layers import fill_constant #DEFINE_ALIAS - from ..fluid.layers import create_tensor #DEFINE_ALIAS +from ..fluid.layers import linspace #DEFINE_ALIAS __all__ = [ 'create_tensor', @@ -65,8 +65,7 @@ def full_like(x, fill_value, dtype=None, name=None): Args: x(Variable): The input tensor which specifies shape and data type. The data type can be bool, float16, float32, float64, int32, int64. - fill_value(bool|float|int|Variable): The value to fill the tensor with. Default value is 0. - Note: this value shouldn't exceed the range of the output data type. + fill_value(bool|float|int|Variable): The value to fill the tensor with. Note: this value shouldn't exceed the range of the output data type. dtype(np.dtype|core.VarDesc.VarType|str, optional): The data type of output. The data type can be one of bool, float16, float32, float64, int32, int64. The default value is None, which means the output data type is the same as input. @@ -112,95 +111,6 @@ def full_like(x, fill_value, dtype=None, name=None): return out -def linspace(start, stop, num, dtype, out=None, device=None, name=None): - """ - :alias_main: paddle.linspace - :alias: paddle.linspace,paddle.tensor.linspace,paddle.tensor.creation.linspace - - This OP return fixed number of evenly spaced values within a given interval. - - **NOTICE**: The output of this OP has no gradient. - - Args: - start(float|Variable): The input :attr:`start` is start variable of range. It is a float scalar, \ - or a tensor of shape [1] with input data type float32, float64. - stop(float|Variable): The input :attr:`stop` is start variable of range. It is a float scalar, \ - or a tensor of shape [1] with input data type float32, float64. - num(int|Variable): The input :attr:`num` is given num of the sequence. It is an int scalar, \ - or a tensor of shape [1] with type int32. - dtype(string): The data type of output tensor, it could be 'float32' and 'float64'. - out (Variable, optional): Optional output which can be any created - Variable that meets the requirements to store the result of operation. - if out is None, a new Varibale will be create to store the result. Default: None. - device (string, optional): Which device to run the operator. The :attr:`device` must be - None, 'cpu', 'gpu'. If :attr:`device` is None, it will be choose the device that the user set in - the paddle program. Default: None. - name(str, optional): Normally there is no need for user to set this property. - For more information, please refer to :ref:`api_guide_Name`.Default: None. - - Returns: - Variable, the output data type will be float32, float64.: The 1-D tensor with fixed number of evenly spaced values, \ - the data shape of this tensor is :math:`[num]` . If the :attr:`num` is set 1, the output tensor just has \ - the value with input :attr:`start`. - - Examples: - .. code-block:: python - - import paddle - data = paddle.linspace(0, 10, 5, dtype='float32') # [0.0, 2.5, 5.0, 7.5, 10.0] - data = paddle.linspace(0, 10, 1, dtype='float32') # [0.0] - - """ - helper = LayerHelper("linspace", **locals()) - - if not isinstance(start, Variable): - start = fill_constant([1], dtype, start) - if not isinstance(stop, Variable): - stop = fill_constant([1], dtype, stop) - if not isinstance(num, Variable): - num = fill_constant([1], 'int32', num) - - if out is None: - out = helper.create_variable_for_type_inference(dtype=start.dtype) - else: - check_dtype( - out.dtype, out.name, - convert_dtype(start.dtype), 'linspace', - "The out data type '%s' in linspace must be the same with '%s' seted by parameter 'dtype'." - % (out.dtype, dtype)) - if name: - warning.warn( - "The output Variable name of the paddle.tensor.linspace operation can only be given by parameter out or name.\ - When parameter out and name are set at the same time, out has a higher priority than name. \ - Finally, the output Variable name is same as the out name %s." % - out.name, - category=UserWarning, - stacklevel=2) - - if device is not None: - if device not in ['cpu', 'gpu']: - raise ValueError( - "The value of 'device' in linspace operation must be cpu or gpu, but received %s." - % (device)) - else: - with device_guard(device): - helper.append_op( - type='linspace', - inputs={'Start': start, - 'Stop': stop, - 'Num': num}, - outputs={'Out': [out]}) - else: - helper.append_op( - type='linspace', - inputs={'Start': start, - 'Stop': stop, - 'Num': num}, - outputs={'Out': [out]}) - - return out - - def ones(shape, dtype=None, out=None, device=None): """ :alias_main: paddle.ones -- GitLab