Skip to content

Commit

Permalink
【Hackathon 5th No.33】为 Paddle 新增 atleast_1d / atleast_2d / atleast_3d…
Browse files Browse the repository at this point in the history
… API -part (#58323)

* [Init] add atleast api

* [Add] add atleast test

* [Fix] import atleast

* [Change] test_atleast.py to test_atleast_nd.py and add bool data type test

* [Update] update dtype supports and unittest

* [Fix] dtype error unittest

* [Change] static test with test_with_pir_api

* [Add] atleast_Nd as tensor method
  • Loading branch information
megemini authored Nov 16, 2023
1 parent 431a0d5 commit 557499b
Show file tree
Hide file tree
Showing 4 changed files with 648 additions and 0 deletions.
6 changes: 6 additions & 0 deletions python/paddle/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,9 @@


from .tensor.manipulation import ( # noqa: F401
atleast_1d,
atleast_2d,
atleast_3d,
cast,
cast_,
concat,
Expand Down Expand Up @@ -833,6 +836,9 @@
'logspace',
'reshape',
'reshape_',
'atleast_1d',
'atleast_2d',
'atleast_3d',
'reverse',
'nonzero',
'CUDAPinnedPlace',
Expand Down
6 changes: 6 additions & 0 deletions python/paddle/tensor/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@
from .logic import isclose # noqa: F401
from .logic import equal_all # noqa: F401
from .logic import is_tensor # noqa: F401
from .manipulation import atleast_1d # noqa: F401
from .manipulation import atleast_2d # noqa: F401
from .manipulation import atleast_3d # noqa: F401
from .manipulation import cast # noqa: F401
from .manipulation import cast_ # noqa: F401
from .manipulation import concat # noqa: F401
Expand Down Expand Up @@ -731,6 +734,9 @@
'normal_',
'index_fill',
'index_fill_',
'atleast_1d',
'atleast_2d',
'atleast_3d',
]

# this list used in math_op_patch.py for magic_method bind
Expand Down
178 changes: 178 additions & 0 deletions python/paddle/tensor/manipulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3955,6 +3955,184 @@ def reshape_(x, shape, name=None):
return out


def atleast_1d(*inputs, name=None):
"""
Convert inputs to tensors and return the view with at least 1-dimension. Scalar inputs are converted,
one or high-dimensional inputs are preserved.
Args:
inputs (Tensor|list(Tensor)): One or more tensors. The data type is ``float16``, ``float32``, ``float64``, ``int16``, ``int32``, ``int64``, ``int8``, ``uint8``, ``complex64``, ``complex128``, ``bfloat16`` or ``bool``.
name (str, optional): Name for the operation (optional, default is None). For more information, please refer to :ref:`api_guide_Name`.
Returns:
One Tensor, if there is only one input.
List of Tensors, if there are more than one inputs.
Examples:
.. code-block:: python
>>> import paddle
>>> # one input
>>> x = paddle.to_tensor(123, dtype='int32')
>>> out = paddle.atleast_1d(x)
>>> print(out)
Tensor(shape=[1], dtype=int32, place=Place(cpu), stop_gradient=True,
[123])
>>> # more than one inputs
>>> x = paddle.to_tensor(123, dtype='int32')
>>> y = paddle.to_tensor([1.23], dtype='float32')
>>> out = paddle.atleast_1d(x, y)
>>> print(out)
[Tensor(shape=[1], dtype=int32, place=Place(cpu), stop_gradient=True,
[123]), Tensor(shape=[1], dtype=float32, place=Place(cpu), stop_gradient=True,
[1.23000002])]
>>> # more than 1-D input
>>> x = paddle.to_tensor(123, dtype='int32')
>>> y = paddle.to_tensor([[1.23]], dtype='float32')
>>> out = paddle.atleast_1d(x, y)
>>> print(out)
[Tensor(shape=[1], dtype=int32, place=Place(cpu), stop_gradient=True,
[123]), Tensor(shape=[1, 1], dtype=float32, place=Place(cpu), stop_gradient=True,
[[1.23000002]])]
"""
out = []
for tensor in inputs:
tensor = paddle.to_tensor(tensor)
if tensor.dim() == 0:
result = tensor.reshape((1,))
else:
result = tensor
out.append(result)

if len(out) == 1:
return out[0]
else:
return out


def atleast_2d(*inputs, name=None):
"""
Convert inputs to tensors and return the view with at least 2-dimension. Two or high-dimensional inputs are preserved.
Args:
inputs (Tensor|list(Tensor)): One or more tensors. The data type is ``float16``, ``float32``, ``float64``, ``int16``, ``int32``, ``int64``, ``int8``, ``uint8``, ``complex64``, ``complex128``, ``bfloat16`` or ``bool``.
name (str, optional): Name for the operation (optional, default is None). For more information, please refer to :ref:`api_guide_Name`.
Returns:
One Tensor, if there is only one input.
List of Tensors, if there are more than one inputs.
Examples:
.. code-block:: python
>>> import paddle
>>> # one input
>>> x = paddle.to_tensor(123, dtype='int32')
>>> out = paddle.atleast_2d(x)
>>> print(out)
Tensor(shape=[1, 1], dtype=int32, place=Place(cpu), stop_gradient=True,
[[123]])
>>> # more than one inputs
>>> x = paddle.to_tensor(123, dtype='int32')
>>> y = paddle.to_tensor([1.23], dtype='float32')
>>> out = paddle.atleast_2d(x, y)
>>> print(out)
[Tensor(shape=[1, 1], dtype=int32, place=Place(cpu), stop_gradient=True,
[[123]]), Tensor(shape=[1, 1], dtype=float32, place=Place(cpu), stop_gradient=True,
[[1.23000002]])]
>>> # more than 2-D input
>>> x = paddle.to_tensor(123, dtype='int32')
>>> y = paddle.to_tensor([[[1.23]]], dtype='float32')
>>> out = paddle.atleast_2d(x, y)
>>> print(out)
[Tensor(shape=[1, 1], dtype=int32, place=Place(cpu), stop_gradient=True,
[[123]]), Tensor(shape=[1, 1, 1], dtype=float32, place=Place(cpu), stop_gradient=True,
[[[1.23000002]]])]
"""
out = []
for tensor in inputs:
tensor = paddle.to_tensor(tensor)
if tensor.dim() == 0:
result = tensor.reshape((1, 1))
elif tensor.dim() == 1:
result = paddle.unsqueeze(tensor, axis=0)
else:
result = tensor
out.append(result)

if len(out) == 1:
return out[0]
else:
return out


def atleast_3d(*inputs, name=None):
"""
Convert inputs to tensors and return the view with at least 3-dimension. Three or high-dimensional inputs are preserved.
Args:
inputs (Tensor|list(Tensor)): One or more tensors. The data type is ``float16``, ``float32``, ``float64``, ``int16``, ``int32``, ``int64``, ``int8``, ``uint8``, ``complex64``, ``complex128``, ``bfloat16`` or ``bool``.
name (str, optional): Name for the operation (optional, default is None). For more information, please refer to :ref:`api_guide_Name`.
Returns:
One Tensor, if there is only one input.
List of Tensors, if there are more than one inputs.
Examples:
.. code-block:: python
>>> import paddle
>>> # one input
>>> x = paddle.to_tensor(123, dtype='int32')
>>> out = paddle.atleast_3d(x)
>>> print(out)
Tensor(shape=[1, 1, 1], dtype=int32, place=Place(cpu), stop_gradient=True,
[[[123]]])
>>> # more than one inputs
>>> x = paddle.to_tensor(123, dtype='int32')
>>> y = paddle.to_tensor([1.23], dtype='float32')
>>> out = paddle.atleast_3d(x, y)
>>> print(out)
[Tensor(shape=[1, 1, 1], dtype=int32, place=Place(cpu), stop_gradient=True,
[[[123]]]), Tensor(shape=[1, 1, 1], dtype=float32, place=Place(cpu), stop_gradient=True,
[[[1.23000002]]])]
>>> # more than 3-D input
>>> x = paddle.to_tensor(123, dtype='int32')
>>> y = paddle.to_tensor([[[[1.23]]]], dtype='float32')
>>> out = paddle.atleast_3d(x, y)
>>> print(out)
[Tensor(shape=[1, 1, 1], dtype=int32, place=Place(cpu), stop_gradient=True,
[[[123]]]), Tensor(shape=[1, 1, 1, 1], dtype=float32, place=Place(cpu), stop_gradient=True,
[[[[1.23000002]]]])]
"""
out = []
for tensor in inputs:
tensor = paddle.to_tensor(tensor)
if tensor.dim() == 0:
result = tensor.reshape((1, 1, 1))
elif tensor.dim() == 1:
result = paddle.unsqueeze(tensor, axis=[0, 2])
elif tensor.dim() == 2:
result = paddle.unsqueeze(tensor, axis=2)
else:
result = tensor
out.append(result)

if len(out) == 1:
return out[0]
else:
return out


def gather_nd(x, index, name=None):
"""
Expand Down
Loading

0 comments on commit 557499b

Please sign in to comment.