diff --git a/python/paddle/fluid/layers/tensor.py b/python/paddle/fluid/layers/tensor.py index 5bae5a8c62abbebcd5fde1f1c694d806eb97d8c3..e6a2d1ca86f2ea2252e1d1a45532c10a38d24c14 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 7d034d224ddc8f4ac486d9792e0233c64901c1e2..c7bab1a135bc439eefa822087869e08a43de0c51 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 6ae1eb5d750c207ec055a06743a5c6a69d7bca3a..36490731967a49032d4c937659678b4003e512f8 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