未验证 提交 5a2d15a1 编写于 作者: Z zhupengyang 提交者: GitHub

arange API: start default is 0, end default is None (#25452)

上级 630f23ce
......@@ -1322,25 +1322,35 @@ def isfinite(x):
return out
def range(start, end, step, dtype):
def range(start, end, step, dtype, name=None):
"""
Return evenly spaced values within a given interval.
Values are generated within the half-open interval [start, stop) (in other words,
the interval including start but excluding stop).
Values are generated within the half-open interval [start, stop) (in other
words, the interval including start but excluding stop).
If dtype is float32 or float64, we advise adding a small epsilon to end to
avoid floating point rounding errors when comparing against end.
Parameters:
start(float32 | float64 | int32 | int64 | Variable): Start of interval. The interval includes this value.
when start is Variable, it is a 1-D Tensor with shape [1].
end(float32 | float64 | int32 | int64 | Variable): End of interval. The interval does not include this
value, except in some cases where step is not an integer
and floating point round-off affects the length of out. When end is Variable,
it is a 1-D Tensor with shape [1].
step(float32 | float64 | int32 | int64 | Variable): Spacing between values. For any output out, this is the
distance between two adjacent values, out[i+1] - out[i].
dtype(str|core.VarDesc.VarType): the data type of the output tensor, can be float32, float64, int32, int64.
Returns: a 1-D Tensor which is evenly spaced values within a given interval. Its data type is set by dtype.
start(float|int|Variable): Start of interval. The interval includes
this value. If start is Variable, it is a 1-D Tensor with shape [1],
and it's data type should be one of int32, int64, float32, float64.
end(float|int|Variable): End of interval. The interval does not include
this value. When end is Variable, it is a 1-D Tensor with shape [1],
and it's data type should be int32, int64, float32, float64.
step(float|int|Variable): Spacing between values. For any out, this is
the istance between two adjacent values, out[i+1] - out[i].
When end is Variable, it is a 1-D Tensor with shape [1], and it's
data type should be one of int32, int64, float32, float64.
dtype(str|np.dtype|core.VarDesc.VarType): The data type of the output
tensor, can be float32, float64, int32, int64.
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 is None.
Returns: a 1-D Tensor which is evenly spaced values within a given interval.
Its data type is set by dtype.
Return type: Variable
......@@ -1348,44 +1358,47 @@ def range(start, end, step, dtype):
.. code-block:: python
import paddle.fluid as fluid
data = fluid.layers.range(0, 10, 2, 'int32')
import paddle.fluid as fluid
"""
check_type(start, 'start', (float, int, Variable), 'range')
check_type(end, 'end', (float, int, Variable), 'range')
check_type(step, 'step', (float, int, Variable), 'range')
helper = LayerHelper("range", **locals())
out1 = fluid.layers.range(0, 10, 2, 'int32')
# [0, 2, 4, 6, 8]
check_dtype(dtype, 'create data type',
['float32', 'float64', 'int32', 'int64'], 'range')
start_var = fluid.layers.fill_constant([1], 'int64', 3)
out2 = fluid.layers.range(start_var, 7, 1, 'int64')
# [3, 4, 5, 6]
"""
if not isinstance(dtype, core.VarDesc.VarType):
dtype = convert_np_dtype_to_dtype_(dtype)
dtype = convert_dtype(dtype)
if not isinstance(start, Variable):
start = fill_constant([1], dtype, start)
elif convert_dtype(start.dtype) != dtype:
# make sure that start, end, step has the same dtype as
# `dtype`
start = cast(x=start, dtype=dtype)
elif start.dtype != dtype:
start = cast(start, dtype)
if not isinstance(end, Variable):
end = fill_constant([1], dtype, end)
elif convert_dtype(end.dtype) != dtype:
end = cast(x=end, dtype=dtype)
elif end.dtype != dtype:
end = cast(end, dtype)
if not isinstance(step, Variable):
step = fill_constant([1], dtype, step)
elif convert_dtype(step.dtype) != dtype:
step = cast(x=step, dtype=dtype)
elif step.dtype != dtype:
step = cast(step, dtype)
out = helper.create_variable_for_type_inference(dtype=start.dtype)
if in_dygraph_mode():
return core.ops.range(start, end, step)
check_dtype(dtype, 'dtype', ['float32', 'float64', 'int32', 'int64'],
'range/arange')
helper = LayerHelper('range', **locals())
out = helper.create_variable_for_type_inference(dtype)
helper.append_op(
type='range',
inputs={'Start': start,
'End': end,
'Step': step},
outputs={'Out': [out]})
outputs={'Out': out})
out.stop_gradient = True
return out
......
......@@ -15,7 +15,8 @@
from __future__ import print_function
import paddle
import paddle.fluid as fluid
from paddle.fluid import core
from paddle import program_guard, Program
import unittest
import numpy as np
from op_test import OpTest
......@@ -44,47 +45,67 @@ class TestArangeOp(OpTest):
self.check_output()
class TestFloatArangeOpCase0(TestArangeOp):
class TestFloatArangeOp(TestArangeOp):
def init_config(self):
self.dtype = np.float32
self.case = (0, 5, 1)
class TestInt32ArangeOpCase0(TestArangeOp):
class TestInt32ArangeOp(TestArangeOp):
def init_config(self):
self.dtype = np.int32
self.case = (0, 5, 2)
class TestInt32ArangeOpCase1(TestArangeOp):
class TestFloat64ArangeOp(TestArangeOp):
def init_config(self):
self.dtype = np.int32
self.dtype = np.float64
self.case = (10, 1, -2)
class TestInt32ArangeOpCase2(TestArangeOp):
class TestInt64ArangeOp(TestArangeOp):
def init_config(self):
self.dtype = np.int32
self.dtype = np.int64
self.case = (-1, -10, -2)
class TestArangeOpError(unittest.TestCase):
def test_errors(self):
with program_guard(Program(), Program()):
self.assertRaises(TypeError, paddle.arange, 10, dtype='int8')
class TestArangeAPI(unittest.TestCase):
def test_out(self):
with fluid.program_guard(fluid.Program()):
data = paddle.arange(0, 5, 1)
place = fluid.CPUPlace()
exe = fluid.Executor(place)
result, = exe.run(fetch_list=[data])
expected_data = np.arange(0, 5, 1).astype(np.float32)
self.assertEqual((result == expected_data).all(), True)
with fluid.program_guard(fluid.Program()):
data = paddle.arange(0.0, 5.0, 1.0, 'int32')
place = fluid.CPUPlace()
exe = fluid.Executor(place)
result, = exe.run(fetch_list=[data])
expected_data = np.arange(0, 5, 1).astype(np.int32)
self.assertEqual((result == expected_data).all(), True)
with program_guard(Program(), Program()):
x1 = paddle.arange(0, 5, 1, 'float32')
place = paddle.CUDAPlace(0) if core.is_compiled_with_cuda(
) else paddle.CPUPlace()
exe = paddle.Executor(place)
out = exe.run(fetch_list=[x1])
expected_data = np.arange(0, 5, 1).astype(np.float32)
self.assertEqual((out == expected_data).all(), True)
class TestArangeImperative(unittest.TestCase):
def test_out(self):
place = paddle.CUDAPlace(0) if core.is_compiled_with_cuda(
) else paddle.CPUPlace()
with paddle.imperative.guard(place):
x1 = paddle.arange(0, 5, 1)
x2 = paddle.tensor.arange(5)
x3 = paddle.tensor.creation.arange(5)
start = paddle.imperative.to_variable(np.array([0], 'float32'))
end = paddle.imperative.to_variable(np.array([5], 'float32'))
step = paddle.imperative.to_variable(np.array([1], 'float32'))
x4 = paddle.arange(start, end, step, 'int64')
expected_data = np.arange(0, 5, 1).astype(np.int64)
for i in [x1, x2, x3, x4]:
self.assertEqual((i.numpy() == expected_data).all(), True)
if __name__ == "__main__":
......
......@@ -21,6 +21,7 @@ from ..fluid.data_feeder import check_variable_and_dtype, check_type, check_dtyp
from ..fluid.framework import convert_np_dtype_to_dtype_, in_dygraph_mode, _varbase_creator, device_guard, OpProtoHolder
from ..fluid.layers import fill_constant
from paddle.common_ops_import import *
import paddle
# TODO: define functions to get create a tensor
from ..fluid.layers import crop_tensor #DEFINE_ALIAS
......@@ -413,76 +414,80 @@ def full(shape, fill_value, dtype=None, name=None):
return fill_constant(shape=shape, dtype=dtype, value=fill_value, name=name)
def arange(start, end, step=1, dtype=None, name=None):
def arange(start=0, end=None, step=1, dtype=None, name=None):
"""
:alias_main: paddle.arange
:alias: paddle.arange,paddle.tensor.arange,paddle.tensor.creation.arange
Return evenly spaced values within a given interval.
Values are generated within the half-open interval [start, stop) (in other words,
the interval including start but excluding stop).
Values are generated into the half-open interval [start, stop) with the step.
(the interval including start but excluding stop).
If dtype is float32 or float64, we advise adding a small epsilon to end to
avoid floating point rounding errors when comparing against end.
Parameters:
start(float32 | float64 | int32 | int64 | Variable): Start of interval. The interval includes this value.
when start is Variable, it is a 1-D Tensor with shape [1].
end(float32 | float64 | int32 | int64 | Variable): End of interval. The interval does not include this
value, except in some cases where step is not an integer
and floating point round-off affects the length of out. When end is Variable,
it is a 1-D Tensor with shape [1].
step(float32 | float64 | int32 | int64 | Variable): Spacing between values. For any output out, this is the
distance between two adjacent values, out[i+1] - out[i].
dtype(str|core.VarDesc.VarType): the data type of the output tensor, can be float32, float64, int32, int64.
Returns: a 1-D Tensor which is evenly spaced values within a given interval. Its data type is set by dtype.
start(float|int|Variable): Start of interval. The interval includes
this value. If end is None, the half-open interval is [0, start).
If start is Variable, it is a 1-D Tensor with shape [1], and it's
data type should be one of int32, int64, float32, float64. Default
is 0.
end(float|int|Variable, optional): End of interval. The interval does
not include this value. When end is Variable, it is a 1-D Tensor
with shape [1], and it's data type should be one of int32, int64,
float32, float64. If end is None, the half-open interval is [0, start).
Default is None.
step(float|int|Variable, optional): Spacing between values. For any
out, this is the istance between two adjacent values, out[i+1] - out[i].
When end is Variable, it is a 1-D Tensor with shape [1], and it's
data type should be one of int32, int64, float32, float64. Default is 1.
dtype(str|np.dtype|core.VarDesc.VarType, optional): The data type of
the output tensor, can be float32, float64, int32, int64. If dtype
is `None` , the data type of out tensor is `int64` . Defaule is 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 is None.
Returns: a 1-D Tensor which is evenly spaced values within a given interval.
Its data type is set by dtype.
Return type: Variable
Raises:
TypeError: If dtype is not float32, float64, int32 or int64.
examples:
.. code-block:: python
import paddle
# expected out put: [0, 2, 4, 6, 8]
data = paddle.arange(0, 10, 2, 'int32')
#dygraph mode
import paddle
import paddle.fluid as fluid
with fluid.dygraph.guard():
x = paddle.arange(0, 6, 2)
# x: [0, 2, 4]
# x dtype: float32
"""
helper = LayerHelper("range", **locals())
if dtype is None:
dtype = 'float32'
import paddle
import numpy as np
check_dtype(dtype, 'create data type',
['float32', 'float64', 'int32', 'int64'], 'range')
paddle.enable_imperative()
dtype = convert_dtype(dtype)
if not isinstance(start, Variable):
start = fill_constant([1], dtype, start)
out1 = paddle.arange(5)
# [0, 1, 2, 3, 4]
if not isinstance(end, Variable):
end = fill_constant([1], dtype, end)
out2 = paddle.arange(3, 9, 2.0)
# [3, 5, 7]
if not isinstance(step, Variable):
step = fill_constant([1], dtype, step)
# use 4.999 instead of 5.0 to avoid floating point rounding errors
out3 = paddle.arange(4.999, dtype='float32')
# [0., 1., 2., 3., 4.]
out = helper.create_variable_for_type_inference(dtype=start.dtype)
start_var = paddle.imperative.to_variable(np.array([3]))
out4 = paddle.arange(start_var, 7)
# [3, 4, 5, 6]
"""
if dtype is None:
dtype = 'int64'
if end is None:
end = start
start = 0
helper.append_op(
type='range',
inputs={'Start': start,
'End': end,
'Step': step},
outputs={'Out': [out]})
out.stop_gradient = True
return out
return paddle.fluid.layers.range(start, end, step, dtype, name)
def _tril_triu_op(helper):
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册