Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【PaddlePaddle Hackathon 2】9、为 Paddle 新增 logspace API #41261

Merged
merged 21 commits into from
Apr 20, 2022
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
调整 logspace 的位置
BrilliantYuKaimin committed Apr 16, 2022
commit 3530acf1cea35aa1db8a46ce5d70e4426291fe65
125 changes: 0 additions & 125 deletions python/paddle/fluid/layers/tensor.py
Original file line number Diff line number Diff line change
@@ -56,7 +56,6 @@
'isfinite',
'range',
'linspace',
'logspace',
'zeros_like',
'ones_like',
'diag',
@@ -1615,130 +1614,6 @@ def linspace(start, stop, num, dtype=None, name=None):
return out


def logspace(start, stop, num, base=10.0, dtype=None, name=None):
r"""
Return fixed number of logarithmical-evenly spaced values within the interval \
:math:`[base^{start}, base^{stop}]`.
Notes:
This API does not compute the gradient.
Args:
start(int|float|Tensor): The input :attr:`start` is exponent of first entry in \
the sequence. It is a scalar, or a Tensor of shape [1] with input data \
type int32, int64, float32 or float64.
stop(int|float|Tensor): The input :attr:`stop` is exponent of last entry in the \
sequence. It is a scalar, or a Tensor of shape [1] with input data \
type int32, int64, float32 or float64.
num(int|Tensor): The input :attr:`num` is given number of items in the sequence. \
It is an int scalar, or a Tensor of shape [1] with data type int32.
base(int|float|Tensor): The input :attr:`base` is base of the logarithm function. \
It is a scalar, or a Tensor of shape [1] with input data type int32, int64, \
float32 or float64.
dtype(np.dtype|str, optional): The data type of output tensor, it could be \
int32, int64, float32 or 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:
Tensor: The output data type will be float32, float64. The 1-D tensor with \
fixed number of logarithmical-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 exponential of :attr:`start` with base :attr:`base`.
Examples:
.. code-block:: python
:name: logspace-example
import paddle
data = paddle.logspace(0, 10, 5, 2, 'float32')
# [1. , 5.65685415 , 32. , 181.01933289, 1024. ]
data = paddle.logspace(0, 10, 1, 2, 'float32')
# [1.]
"""
if dtype is None:
dtype = 'float32'
tensor_num = num
tensor_start = start
tensor_stop = stop
tensor_base = base
if not isinstance(num, Variable):
check_type(num, 'num', (int), 'logspace')
if not isinstance(dtype, core.VarDesc.VarType):
dtype = convert_np_dtype_to_dtype_(dtype)
if not isinstance(start, Variable):
with device_guard("cpu"):
tensor_start = fill_constant([1], dtype, start)
if not isinstance(stop, Variable):
with device_guard("cpu"):
tensor_stop = fill_constant([1], dtype, stop)
if not isinstance(num, Variable):
with device_guard("cpu"):
tensor_num = fill_constant([1], 'int32', num)
if not isinstance(base, Variable):
with device_guard("cpu"):
tensor_base = fill_constant([1], dtype, base)
if _non_static_mode():
return _C_ops.logspace(tensor_start, tensor_stop, tensor_num,
tensor_base, 'dtype', dtype)

helper = LayerHelper("logspace", **locals())

start_dtype = convert_dtype(tensor_start.dtype)
stop_dtype = convert_dtype(tensor_stop.dtype)
base_dtype = convert_dtype(tensor_base.dtype)
out_dtype = convert_dtype(dtype)
if isinstance(start, Variable):
check_dtype(start.dtype, 'start',
['float32', 'float64', 'int32', 'int64'], 'logspace')
else:
check_type(start, 'start', (int, float), 'logspace')

if isinstance(stop, Variable):
check_dtype(stop.dtype, 'stop',
['float32', 'float64', 'int32', 'int64'], 'logspace')
else:
check_type(stop, 'stop', (int, float), 'logspace')

if isinstance(num, Variable):
check_dtype(num.dtype, 'num', ['int32'], 'logspace')

if isinstance(base, Variable):
check_dtype(base.dtype, 'base',
['float32', 'float64', 'int32', 'int64'], 'logspace')
else:
check_type(base, 'base', (int, float), 'logspace')

check_dtype(dtype, 'dtype', ['int32', 'int64', 'float32', 'float64'],
'logspace')
if ((stop_dtype == "float64" or start_dtype == "float64"
or base_dtype == "float64")
and out_dtype in ["float32", "int32"]) or \
((stop_dtype == "int64" or start_dtype == "int64"
or base_dtype == "int64")
and out_dtype == "int32"):
raise ValueError(
"The dtype of start/stop/base is {}/{}/{} but the attr(dtype) of logspace is {}, "
"which may cause data type overflows. Please reset attr(dtype) of logspace."
.format(start_dtype, stop_dtype, base_dtype, dtype))

out = helper.create_variable_for_type_inference(dtype=dtype)

helper.append_op(
type='logspace',
inputs={
'Start': tensor_start,
'Stop': tensor_stop,
'Num': tensor_num,
'Base': tensor_base
},
attrs={'dtype': dtype},
outputs={'Out': [out]})
if isinstance(num, int):
out.desc.set_shape((num, ))
return out


def zeros_like(x, out=None):
"""
This OP creates a zeros tensor which has identical shape and dtype
124 changes: 123 additions & 1 deletion python/paddle/tensor/creation.py
Original file line number Diff line number Diff line change
@@ -26,7 +26,6 @@
from ..fluid.data_feeder import check_variable_and_dtype, check_type, check_dtype, convert_dtype
from ..framework import convert_np_dtype_to_dtype_, _varbase_creator, OpProtoHolder
# TODO: define functions to get create a tensor
from ..fluid.layers import logspace # noqa: F401
import paddle
from paddle import _C_ops
from ..fluid.framework import _in_legacy_dygraph, _in_eager_without_dygraph_check
@@ -146,6 +145,129 @@ def linspace(start, stop, num, dtype=None, name=None):
out.desc.set_shape((num, ))
return out

def logspace(start, stop, num, base=10.0, dtype=None, name=None):
r"""
Return fixed number of logarithmical-evenly spaced values within the interval \
:math:`[base^{start}, base^{stop}]`.
Notes:
This API does not compute the gradient.
Args:
start(int|float|Tensor): The input :attr:`start` is exponent of first entry in \
the sequence. It is a scalar, or a Tensor of shape [1] with input data \
type int32, int64, float32 or float64.
stop(int|float|Tensor): The input :attr:`stop` is exponent of last entry in the \
sequence. It is a scalar, or a Tensor of shape [1] with input data \
type int32, int64, float32 or float64.
num(int|Tensor): The input :attr:`num` is given number of items in the sequence. \
It is an int scalar, or a Tensor of shape [1] with data type int32.
base(int|float|Tensor): The input :attr:`base` is base of the logarithm function. \
It is a scalar, or a Tensor of shape [1] with input data type int32, int64, \
float32 or float64.
dtype(np.dtype|str, optional): The data type of output tensor, it could be \
int32, int64, float32 or 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:
Tensor: The output data type will be float32, float64. The 1-D tensor with \
fixed number of logarithmical-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 exponential of :attr:`start` with base :attr:`base`.
Examples:
.. code-block:: python
:name: logspace-example
import paddle
data = paddle.logspace(0, 10, 5, 2, 'float32')
# [1. , 5.65685415 , 32. , 181.01933289, 1024. ]
data = paddle.logspace(0, 10, 1, 2, 'float32')
# [1.]
"""
if dtype is None:
dtype = 'float32'
tensor_num = num
tensor_start = start
tensor_stop = stop
tensor_base = base
if not isinstance(num, Variable):
check_type(num, 'num', (int), 'logspace')
if not isinstance(dtype, core.VarDesc.VarType):
dtype = convert_np_dtype_to_dtype_(dtype)
if not isinstance(start, Variable):
with device_guard("cpu"):
tensor_start = fill_constant([1], dtype, start)
if not isinstance(stop, Variable):
with device_guard("cpu"):
tensor_stop = fill_constant([1], dtype, stop)
if not isinstance(num, Variable):
with device_guard("cpu"):
tensor_num = fill_constant([1], 'int32', num)
if not isinstance(base, Variable):
with device_guard("cpu"):
tensor_base = fill_constant([1], dtype, base)
if _non_static_mode():
return _C_ops.logspace(tensor_start, tensor_stop, tensor_num,
tensor_base, 'dtype', dtype)

helper = LayerHelper("logspace", **locals())

start_dtype = convert_dtype(tensor_start.dtype)
stop_dtype = convert_dtype(tensor_stop.dtype)
base_dtype = convert_dtype(tensor_base.dtype)
out_dtype = convert_dtype(dtype)
if isinstance(start, Variable):
check_dtype(start.dtype, 'start',
['float32', 'float64', 'int32', 'int64'], 'logspace')
else:
check_type(start, 'start', (int, float), 'logspace')

if isinstance(stop, Variable):
check_dtype(stop.dtype, 'stop',
['float32', 'float64', 'int32', 'int64'], 'logspace')
else:
check_type(stop, 'stop', (int, float), 'logspace')

if isinstance(num, Variable):
check_dtype(num.dtype, 'num', ['int32'], 'logspace')

if isinstance(base, Variable):
check_dtype(base.dtype, 'base',
['float32', 'float64', 'int32', 'int64'], 'logspace')
else:
check_type(base, 'base', (int, float), 'logspace')

check_dtype(dtype, 'dtype', ['int32', 'int64', 'float32', 'float64'],
'logspace')
if ((stop_dtype == "float64" or start_dtype == "float64"
or base_dtype == "float64")
and out_dtype in ["float32", "int32"]) or \
((stop_dtype == "int64" or start_dtype == "int64"
or base_dtype == "int64")
and out_dtype == "int32"):
raise ValueError(
"The dtype of start/stop/base is {}/{}/{} but the attr(dtype) of logspace is {}, "
"which may cause data type overflows. Please reset attr(dtype) of logspace."
.format(start_dtype, stop_dtype, base_dtype, dtype))

out = helper.create_variable_for_type_inference(dtype=dtype)

helper.append_op(
type='logspace',
inputs={
'Start': tensor_start,
'Stop': tensor_stop,
'Num': tensor_num,
'Base': tensor_base
},
attrs={'dtype': dtype},
outputs={'Out': [out]})
if isinstance(num, int):
out.desc.set_shape((num, ))
return out


@dygraph_only
def to_tensor(data, dtype=None, place=None, stop_gradient=True):