chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:40:42 +08:00
commit e25996e7db
15472 changed files with 3536181 additions and 0 deletions
File diff suppressed because it is too large Load Diff
+381
View File
@@ -0,0 +1,381 @@
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Define functions about array.
from __future__ import annotations
from typing import TYPE_CHECKING, Any, TypeVar, overload
import paddle
from paddle import _typing
from ..base.data_feeder import check_type, check_variable_and_dtype
from ..base.framework import in_pir_mode
from ..common_ops_import import Variable
from ..framework import LayerHelper, core, in_dynamic_mode
if TYPE_CHECKING:
from collections.abc import Sequence
__all__ = []
T = TypeVar("T")
@overload
def array_length(array: list[Any]) -> int: ...
@overload
def array_length(array: paddle.Tensor) -> paddle.Tensor: ...
def array_length(array):
"""
This OP is used to get the length of the input array.
Args:
array (list|Tensor): The input array that will be used to compute the length. In dynamic mode, ``array`` is a Python list. But in static graph mode, array is a Tensor whose VarType is DENSE_TENSOR_ARRAY.
Returns:
Tensor, 0-D Tensor with shape [], which is the length of array.
Examples:
.. code-block:: pycon
>>> import paddle
>>> arr = paddle.tensor.create_array(dtype='float32')
>>> x = paddle.full(shape=[3, 3], fill_value=5, dtype="float32")
>>> i = paddle.zeros(shape=[1], dtype="int32")
>>> arr = paddle.tensor.array_write(x, i, array=arr)
>>> arr_len = paddle.tensor.array_length(arr)
>>> print(arr_len)
1
"""
if in_dynamic_mode():
assert isinstance(array, list), (
"The 'array' in array_write must be a list in dygraph mode"
)
return len(array)
elif in_pir_mode():
if (
not isinstance(array, paddle.pir.Value)
or not array.is_dense_tensor_array_type()
):
raise TypeError(
"array should be tensor array variable in array_length Op"
)
return paddle._pir_ops.array_length(array)
else:
if (
not isinstance(array, Variable)
or array.type != core.VarDesc.VarType.DENSE_TENSOR_ARRAY
):
raise TypeError(
"array should be tensor array variable in array_length Op"
)
helper = LayerHelper('array_length', **locals())
tmp = helper.create_variable_for_type_inference(dtype='int64')
tmp.stop_gradient = True
helper.append_op(
type='lod_array_length',
inputs={'X': [array]},
outputs={'Out': [tmp]},
)
return tmp
@overload
def array_read(array: list[T], i: paddle.Tensor) -> T: ...
@overload
def array_read(array: paddle.Tensor, i: paddle.Tensor) -> paddle.Tensor: ...
def array_read(array, i):
"""
This OP is used to read data at the specified position from the input array.
Case:
.. code-block:: text
Input:
The shape of first three tensors are [1], and that of the last one is [1,2]:
array = ([0.6], [0.1], [0.3], [0.4, 0.2])
And:
i = [3]
Output:
output = [0.4, 0.2]
Args:
array (list|Tensor): The input array. In dynamic mode, ``array`` is a Python list. But in static graph mode, array is a Tensor whose ``VarType`` is ``DENSE_TENSOR_ARRAY``.
i (Tensor): 1-D Tensor, whose shape is [1] and dtype is int64. It represents the
specified read position of ``array``.
Returns:
Tensor, A Tensor that is read at the specified position of ``array``.
Examples:
.. code-block:: pycon
>>> import paddle
>>> arr = paddle.tensor.create_array(dtype="float32")
>>> x = paddle.full(shape=[1, 3], fill_value=5, dtype="float32")
>>> i = paddle.zeros(shape=[1], dtype="int32")
>>> arr = paddle.tensor.array_write(x, i, array=arr)
>>> item = paddle.tensor.array_read(arr, i)
>>> print(item.numpy())
[[5. 5. 5.]]
"""
if in_dynamic_mode():
assert isinstance(array, list), (
"The 'array' in array_read must be list in dygraph mode"
)
assert isinstance(i, Variable), (
"The index 'i' in array_read must be Variable in dygraph mode"
)
assert i.shape == [1], (
"The shape of index 'i' should be [1] in dygraph mode"
)
i = i.item(0)
return array[i]
elif in_pir_mode():
if (
not isinstance(array, paddle.pir.Value)
or not array.is_dense_tensor_array_type()
):
raise TypeError(
"array should be tensor array variable in array_length Op"
)
return paddle._pir_ops.array_read(array, i)
else:
check_variable_and_dtype(i, 'i', ['int64'], 'array_read')
helper = LayerHelper('array_read', **locals())
if (
not isinstance(array, Variable)
or array.type != core.VarDesc.VarType.DENSE_TENSOR_ARRAY
):
raise TypeError("array should be tensor array variable")
out = helper.create_variable_for_type_inference(dtype=array.dtype)
helper.append_op(
type='read_from_array',
inputs={'X': [array], 'I': [i]},
outputs={'Out': [out]},
)
return out
@overload
def array_write(
x: paddle.Tensor, i: paddle.Tensor, array: None = None
) -> list[Any] | paddle.Tensor: ...
@overload
def array_write(
x: paddle.Tensor, i: paddle.Tensor, array: list[paddle.Tensor]
) -> list[paddle.Tensor]: ...
@overload
def array_write(
x: paddle.Tensor, i: paddle.Tensor, array: paddle.Tensor
) -> paddle.Tensor: ...
def array_write(
x,
i,
array=None,
):
"""
This OP writes the input ``x`` into the i-th position of the ``array`` returns the modified array.
If ``array`` is none, a new array will be created and returned.
Args:
x (Tensor): The input data to be written into array. It's multi-dimensional
Tensor. Data type: float32, float64, int32, int64 and bool.
i (Tensor): 0-D Tensor with shape [], which represents the position into which
``x`` is written.
array (list|Tensor, optional): The array into which ``x`` is written. The default value is None,
when a new array will be created and returned as a result. In dynamic mode, ``array`` is a Python list.
But in static graph mode, array is a Tensor whose ``VarType`` is ``DENSE_TENSOR_ARRAY``.
Returns:
list|Tensor, The input ``array`` after ``x`` is written into.
Examples:
.. code-block:: pycon
>>> import paddle
>>> arr = paddle.tensor.create_array(dtype="float32")
>>> x = paddle.full(shape=[1, 3], fill_value=5, dtype="float32")
>>> i = paddle.zeros(shape=[1], dtype="int32")
>>> arr = paddle.tensor.array_write(x, i, array=arr)
>>> item = paddle.tensor.array_read(arr, i)
>>> print(item.numpy())
[[5. 5. 5.]]
"""
if in_dynamic_mode():
assert isinstance(x, Variable), (
"The input data 'x' in array_write must be Variable in dygraph mode"
)
assert isinstance(i, Variable), (
"The index 'i' in array_write must be Variable in dygraph mode"
)
assert i.shape == [1], (
"The shape of index 'i' should be [1] in dygraph mode"
)
i = i.item(0)
if array is None:
array = create_array(x.dtype)
assert isinstance(array, list), (
"The 'array' in array_write must be a list in dygraph mode"
)
assert i <= len(array), (
"The index 'i' should not be greater than the length of 'array' in dygraph mode"
)
if i < len(array):
array[i] = x
else:
array.append(x)
return array
elif in_pir_mode():
check_variable_and_dtype(i, 'i', ['int64'], 'array_write')
if not isinstance(x, paddle.pir.Value):
raise TypeError(f"x should be pir.Value, but received {type(x)}.")
if array is not None:
if (
not isinstance(array, paddle.pir.Value)
or not array.is_dense_tensor_array_type()
):
raise TypeError("array should be tensor array variable")
if array is None:
array = paddle._pir_ops.create_array(x.dtype)
if array.dtype != paddle.base.libpaddle.DataType.UNDEFINED:
x = paddle.cast(x, array.dtype)
paddle._pir_ops.array_write_(array, x, i)
return array
else:
check_variable_and_dtype(i, 'i', ['int64'], 'array_write')
check_type(x, 'x', (Variable), 'array_write')
helper = LayerHelper('array_write', **locals())
if array is not None:
if (
not isinstance(array, Variable)
or array.type != core.VarDesc.VarType.DENSE_TENSOR_ARRAY
):
raise TypeError(
"array should be tensor array variable in array_write Op"
)
if array is None:
array = helper.create_variable(
name=f"{helper.name}.out",
type=core.VarDesc.VarType.DENSE_TENSOR_ARRAY,
dtype=x.dtype,
)
helper.append_op(
type='write_to_array',
inputs={'X': [x], 'I': [i]},
outputs={'Out': [array]},
)
return array
def create_array(
dtype: _typing.DTypeLike,
initialized_list: Sequence[paddle.Tensor] | None = None,
) -> paddle.Tensor | list[paddle.Tensor]:
"""
This OP creates an array. It is used as the input of :ref:`api_paddle_tensor_array_array_read` and
:ref:`api_paddle_tensor_array_array_write`.
Args:
dtype (str): The data type of the elements in the array. Support data type: float32, float64, int32, int64 and bool.
initialized_list(list): Used to initialize as default value for created array.
All values in initialized list should be a Tensor.
Returns:
list|Tensor, An empty array. In dynamic mode, ``array`` is a Python list. But in static graph mode, array is a Tensor
whose ``VarType`` is ``DENSE_TENSOR_ARRAY``.
Examples:
.. code-block:: pycon
>>> import paddle
>>> arr = paddle.tensor.create_array(dtype="float32")
>>> x = paddle.full(shape=[1, 3], fill_value=5, dtype="float32")
>>> i = paddle.zeros(shape=[1], dtype="int32")
>>> arr = paddle.tensor.array_write(x, i, array=arr)
>>> item = paddle.tensor.array_read(arr, i)
>>> print(item.numpy())
[[5. 5. 5.]]
"""
array = []
if initialized_list is not None:
if not isinstance(initialized_list, (list, tuple)):
raise TypeError(
f"Require type(initialized_list) should be list/tuple, but received {type(initialized_list)}"
)
array = list(initialized_list)
# NOTE: Only support plain list like [x, y,...], not support nested list in static graph mode.
for val in array:
if not isinstance(val, (Variable, paddle.pir.Value)):
raise TypeError(
f"All values in `initialized_list` should be Variable or pir.Value, but received {type(val)}."
)
if in_dynamic_mode():
return array
elif in_pir_mode():
if not isinstance(dtype, (core.VarDesc.VarType, core.DataType)):
dtype = paddle.base.framework.convert_nptype_to_datatype_or_vartype(
dtype
)
out = paddle._pir_ops.create_array(dtype)
for val in array:
if dtype != paddle.base.libpaddle.DataType.UNDEFINED:
val = paddle.cast(val, dtype)
paddle._pir_ops.array_write_(out, val, array_length(out))
return out
else:
helper = LayerHelper("array", **locals())
tensor_array: paddle.Tensor = helper.create_variable(
name=f"{helper.name}.out",
type=core.VarDesc.VarType.DENSE_TENSOR_ARRAY,
dtype=dtype,
)
for val in array:
array_write(x=val, i=array_length(tensor_array), array=tensor_array)
return tensor_array
+291
View File
@@ -0,0 +1,291 @@
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations
from typing import TYPE_CHECKING
import numpy as np
import paddle
from paddle import _C_ops
from paddle._C_ops import imag, real # noqa: F401
from paddle.utils.decorator_utils import param_one_alias
from ..base.data_feeder import check_type, check_variable_and_dtype
from ..base.framework import in_dynamic_or_pir_mode, use_pir_api
from ..common_ops_import import Variable
from ..framework import LayerHelper, core
from .creation import assign
if TYPE_CHECKING:
from paddle import Tensor
__all__ = []
def rank(input: Tensor) -> Tensor:
"""
Returns the number of dimensions for a tensor, which is a 0-D int32 Tensor.
Args:
input (Tensor): The input Tensor with shape of :math:`[N_1, N_2, ..., N_k]`, the data type is arbitrary.
Returns:
Tensor, the output data type is int32.: The 0-D tensor with the dimensions of the input Tensor.
Examples:
.. code-block:: pycon
>>> import paddle
>>> input = paddle.rand((3, 100, 100))
>>> rank = paddle.rank(input)
>>> print(rank.numpy())
3
"""
check_type(input, 'input', (Variable, paddle.pir.Value), 'input')
ndims = len(input.shape)
out = assign(np.array(ndims, 'int32'))
return out
def shape(input: Tensor) -> Tensor:
"""
Get the shape of the input.
.. code-block:: text
Case1:
Given N-D Tensor:
input = [ [1, 2, 3, 4], [5, 6, 7, 8] ]
Then:
input.shape = [2, 4]
Case2:
Given SelectedRows:
input.rows = [0, 4, 19]
input.height = 20
input.value = [ [1, 2], [3, 4], [5, 6] ] # inner tensor
Then:
input.shape = [3, 2]
Args:
input (Tensor): The input can be N-D Tensor or SelectedRows with data type bool, bfloat16, float16, float32, float64, int32, int64.
If input variable is type of SelectedRows, returns the shape of it's inner tensor.
Returns:
Tensor: The shape of the input variable.
Examples:
.. code-block:: pycon
>>> import numpy as np
>>> import paddle
>>> paddle.enable_static()
>>> inputs = paddle.static.data(name="x", shape=[3, 100, 100], dtype="float32")
>>> output = paddle.shape(inputs)
>>> exe = paddle.static.Executor(paddle.CPUPlace())
>>> exe.run(paddle.static.default_startup_program())
>>> img = np.ones((3, 100, 100)).astype(np.float32)
>>> res = exe.run(paddle.static.default_main_program(), feed={'x': img}, fetch_list=[output])
>>> print(res)
[array([ 3, 100, 100], dtype=int64)]
"""
if in_dynamic_or_pir_mode():
out = _C_ops.shape64(input) # type: ignore
out.stop_gradient = True
return out
else:
check_variable_and_dtype(
input,
'input',
[
'bool',
'uint16',
'float16',
'float32',
'float64',
'int32',
'int64',
'complex64',
'complex128',
'uint16',
'float8_e4m3fn',
'float8_e5m2',
],
'shape',
)
helper = LayerHelper('shape', **locals())
out = helper.create_variable_for_type_inference(dtype='int32')
helper.append_op(
type='shape',
inputs={'Input': input},
outputs={'Out': out},
stop_gradient=True,
)
out.stop_gradient = True
return out
@param_one_alias(["x", "input"])
def is_complex(x: Tensor) -> bool:
"""Return whether x is a tensor of complex data type(complex64 or complex128).
.. note::
Alias Support: The parameter name ``input`` can be used as an alias for ``x``.
For example, ``input=tensor_x`` is equivalent to ``x=tensor_x``.
Args:
x (Tensor): The input tensor.
input: An alias for ``x`` , with identical behavior.
Returns:
bool: True if the data type of the input is complex data type, otherwise false.
Examples:
.. code-block:: pycon
>>> import paddle
>>> x = paddle.to_tensor([1 + 2j, 3 + 4j])
>>> print(paddle.is_complex(x))
True
>>> x = paddle.to_tensor([1.1, 1.2])
>>> print(paddle.is_complex(x))
False
>>> x = paddle.to_tensor([1, 2, 3])
>>> print(paddle.is_complex(x))
False
"""
if not isinstance(
x, (paddle.Tensor, paddle.static.Variable, paddle.pir.Value)
):
raise TypeError(f"Expected Tensor, but received type of x: {type(x)}")
dtype = x.dtype
is_complex_dtype = (
dtype == core.VarDesc.VarType.COMPLEX64
or dtype == core.VarDesc.VarType.COMPLEX128
or dtype == core.DataType.COMPLEX64
or dtype == core.DataType.COMPLEX128
)
return is_complex_dtype
@param_one_alias(["x", "input"])
def is_floating_point(x: Tensor) -> bool:
"""
Returns whether the dtype of `x` is one of paddle.float64, paddle.float32, paddle.float16, and paddle.bfloat16.
.. note::
Alias Support: The parameter name ``input`` can be used as an alias for ``x``.
For example, ``is_floating_point(input=tensor_x)`` is equivalent to ``is_floating_point(x=tensor_x)``.
Args:
x (Tensor): The input tensor. alias: ``input``.
Returns:
bool: True if the dtype of `x` is floating type, otherwise false.
Examples:
.. code-block:: pycon
>>> import paddle
>>> x = paddle.arange(1.0, 5.0, dtype='float32')
>>> y = paddle.arange(1, 5, dtype='int32')
>>> print(paddle.is_floating_point(x))
True
>>> print(paddle.is_floating_point(y))
False
"""
if not isinstance(
x, (paddle.Tensor, paddle.static.Variable, paddle.pir.Value)
):
raise TypeError(f"Expected Tensor, but received type of x: {type(x)}")
dtype = x.dtype
is_fp_dtype = (
dtype == core.VarDesc.VarType.FP32
or dtype == core.VarDesc.VarType.FP64
or dtype == core.VarDesc.VarType.FP16
or dtype == core.VarDesc.VarType.BF16
or dtype == core.DataType.FLOAT32
or dtype == core.DataType.FLOAT64
or dtype == core.DataType.FLOAT16
or dtype == core.DataType.BFLOAT16
)
return is_fp_dtype
def is_integer(x: Tensor) -> bool:
"""Return whether x is a tensor of integral data type.
Args:
x (Tensor): The input tensor.
Returns:
bool: True if the data type of the input is integer data type, otherwise false.
Examples:
.. code-block:: pycon
>>> import paddle
>>> x = paddle.to_tensor([1 + 2j, 3 + 4j])
>>> print(paddle.is_integer(x))
False
>>> x = paddle.to_tensor([1.1, 1.2])
>>> print(paddle.is_integer(x))
False
>>> x = paddle.to_tensor([1, 2, 3])
>>> print(paddle.is_integer(x))
True
"""
if not isinstance(
x, (paddle.Tensor, paddle.static.Variable, paddle.pir.Value)
):
raise TypeError(f"Expected Tensor, but received type of x: {type(x)}")
dtype = x.dtype
is_int_dtype = False
if not use_pir_api():
is_int_dtype = (
dtype == core.VarDesc.VarType.UINT8
or dtype == core.VarDesc.VarType.INT8
or dtype == core.VarDesc.VarType.INT16
or dtype == core.VarDesc.VarType.INT32
or dtype == core.VarDesc.VarType.INT64
)
else:
is_int_dtype = (
dtype == core.DataType.UINT8
or dtype == core.DataType.INT8
or dtype == core.DataType.INT16
or dtype == core.DataType.INT32
or dtype == core.DataType.INT64
)
return is_int_dtype
+261
View File
@@ -0,0 +1,261 @@
# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations
from typing import TYPE_CHECKING
from paddle import _C_ops
from paddle.framework import core, in_dynamic_or_pir_mode
from paddle.utils.decorator_utils import ForbidKeywordsIgnoreOneParamDecorator
from ..base.framework import convert_nptype_to_datatype_or_vartype
if TYPE_CHECKING:
from paddle import Tensor
from paddle._typing import DTypeLike
@ForbidKeywordsIgnoreOneParamDecorator(
illegal_keys={"x", "axis", "name"},
ignore_param=('_stacklevel', 2, int),
func_name="paddle.compat.nn.functional.softmax",
correct_name="paddle.nn.functional.softmax",
url_suffix="torch.nn.functional.softmax",
)
def softmax(
input: Tensor,
dim: int | None = None,
dtype: DTypeLike | None = None,
*,
out: Tensor | None = None,
) -> Tensor:
r"""
This operator implements PyTorch compatible softmax. The calculation process is as follows:
1. The dimension :attr:`dim` of ``input`` will be permuted to the last.
2. Then ``input`` will be logically flattened to a 2-D matrix. The matrix's second
dimension(row length) is the same as the dimension :attr:`axis` of ``input``,
and the first dimension(column length) is the product of all other dimensions
of ``input``. For each row of the matrix, the softmax operator squashes the
K-dimensional(K is the width of the matrix, which is also the size of ``input``'s
dimension :attr:`dim`) vector of arbitrary real values to a K-dimensional
vector of real values in the range [0, 1] that add up to 1.
3. After the softmax operation is completed, the inverse operations of steps 1 and 2
are performed to restore the two-dimensional matrix to the same dimension as the ``input`` .
It computes the exponential of the given dimension and the sum of exponential
values of all the other dimensions in the K-dimensional vector input.
Then the ratio of the exponential of the given dimension and the sum of
exponential values of all the other dimensions is the output of the softmax
operator.
For each row :math:`i` and each column :math:`j` in the matrix, we have:
.. math::
softmax[i, j] = \frac{\exp(input[i, j])}{\sum_j(exp(input[i, j])}
Example:
.. code-block:: text
Case 1:
Input:
input.shape = [2, 3, 4]
input.data = [[[2.0, 3.0, 4.0, 5.0],
[3.0, 4.0, 5.0, 6.0],
[7.0, 8.0, 8.0, 9.0]],
[[1.0, 2.0, 3.0, 4.0],
[5.0, 6.0, 7.0, 8.0],
[6.0, 7.0, 8.0, 9.0]]]
Attrs:
dim = -1
Output:
out.shape = [2, 3, 4]
out.data = [[[0.0320586 , 0.08714432, 0.23688282, 0.64391426],
[0.0320586 , 0.08714432, 0.23688282, 0.64391426],
[0.07232949, 0.19661193, 0.19661193, 0.53444665]],
[[0.0320586 , 0.08714432, 0.23688282, 0.64391426],
[0.0320586 , 0.08714432, 0.23688282, 0.64391426],
[0.0320586 , 0.08714432, 0.23688282, 0.64391426]]]
Case 2:
Input:
input.shape = [2, 3, 4]
input.data = [[[2.0, 3.0, 4.0, 5.0],
[3.0, 4.0, 5.0, 6.0],
[7.0, 8.0, 8.0, 9.0]],
[[1.0, 2.0, 3.0, 4.0],
[5.0, 6.0, 7.0, 8.0],
[6.0, 7.0, 8.0, 9.0]]]
Attrs:
dim = 1
Output:
out.shape = [2, 3, 4]
out.data = [[[0.00657326, 0.00657326, 0.01714783, 0.01714783],
[0.01786798, 0.01786798, 0.04661262, 0.04661262],
[0.97555875, 0.97555875, 0.93623955, 0.93623955]],
[[0.00490169, 0.00490169, 0.00490169, 0.00490169],
[0.26762315, 0.26762315, 0.26762315, 0.26762315],
[0.72747516, 0.72747516, 0.72747516, 0.72747516]]]
Parameters:
input (Tensor): The input Tensor with data type bfloat16, float16, float32, float64.
dim (int, optional): The dim along which to perform softmax
calculations. It should be in range [-D, D), where D is the
rank of ``input`` . If ``dim`` < 0, it works the same way as
:math:`dim + D` . Default is None.
dtype (str, optional): The data type of the output tensor, can be bfloat16, float16, float32, float64.
out (Tensor, optional): The output Tensor.
Returns:
A Tensor with the same shape and data type (use ``dtype`` if it is
specified) as input.
Examples:
.. code-block:: pycon
>>> import paddle
>>> x = paddle.to_tensor(
... [
... [[2.0, 3.0, 4.0, 5.0], [3.0, 4.0, 5.0, 6.0], [7.0, 8.0, 8.0, 9.0]],
... [[1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0], [6.0, 7.0, 8.0, 9.0]],
... ],
... dtype='float32',
... )
>>> out1 = paddle.compat.nn.functional.softmax(x, -1)
>>> out2 = paddle.compat.nn.functional.softmax(x, -1, dtype='float64')
>>> # out1's data type is float32; out2's data type is float64
>>> # out1 and out2's value is as follows:
>>> print(out1)
>>> print(out2)
Tensor(shape=[2, 3, 4], dtype=float32, place=Place(cpu), stop_gradient=True,
[[[0.03205860, 0.08714432, 0.23688284, 0.64391428],
[0.03205860, 0.08714432, 0.23688284, 0.64391428],
[0.07232949, 0.19661194, 0.19661194, 0.53444666]],
[[0.03205860, 0.08714432, 0.23688284, 0.64391428],
[0.03205860, 0.08714432, 0.23688284, 0.64391428],
[0.03205860, 0.08714432, 0.23688284, 0.64391428]]])
Tensor(shape=[2, 3, 4], dtype=float64, place=Place(cpu), stop_gradient=True,
[[[0.03205860, 0.08714432, 0.23688282, 0.64391426],
[0.03205860, 0.08714432, 0.23688282, 0.64391426],
[0.07232949, 0.19661193, 0.19661193, 0.53444665]],
[[0.03205860, 0.08714432, 0.23688282, 0.64391426],
[0.03205860, 0.08714432, 0.23688282, 0.64391426],
[0.03205860, 0.08714432, 0.23688282, 0.64391426]]])
"""
if dim is None:
ndim = input.ndim
if ndim == 0 or ndim == 1 or ndim == 3:
dim = 0
else:
dim = 1
if (
(dtype is not None)
and (not isinstance(dtype, core.VarDesc.VarType))
and (not isinstance(dtype, core.DataType))
):
dtype = convert_nptype_to_datatype_or_vartype(dtype)
if in_dynamic_or_pir_mode():
outs_cast = input if dtype is None else _C_ops.cast(input, dtype)
return _C_ops.softmax(outs_cast, dim, out=out)
@ForbidKeywordsIgnoreOneParamDecorator(
illegal_keys={"x", "axis", "name"},
ignore_param=('_stacklevel', 2, int),
func_name="paddle.compat.nn.functional.log_softmax",
correct_name="paddle.nn.functional.log_softmax",
url_suffix="torch.nn.functional.log_softmax",
)
def log_softmax(
input: Tensor,
dim: int | None = None,
dtype: DTypeLike | None = None,
*,
out: Tensor | None = None,
) -> Tensor:
r"""
This operator implements PyTorch compatible log_softmax. The calculation process is as follows:
.. math::
\begin{aligned}
log\_softmax[i, j] &= log(softmax(input)) \\
&= log\left(\frac{\exp(input[i, j])}{\sum_j \exp(input[i, j])}\right)
\end{aligned}
Parameters:
input (Tensor): The input Tensor with data type float32, float64.
dim (int, optional): The dim along which to perform log_softmax
calculations. It should be in range [-D, D), where D is the
rank of ``input``. If ``dim`` < 0, it works the same way as
:math:`dim + D`. If ``dim`` is None, it defaults to 0 for
0-D, 1-D, and 3-D tensors, and 1 for 2-D tensors (same as
PyTorch behavior). Default is None.
dtype (str|np.dtype|core.VarDesc.VarType|core.DataType, optional):
The desired data type of the output tensor. If dtype is
specified, ``input`` is cast to ``dtype`` before the operation
is performed. Supported dtype: float32, float64. If ``dtype``
is None, the output Tensor has the same dtype as input.
Default is None.
out (Tensor, optional): The output Tensor.
Returns:
A Tensor with the same shape and data type (use ``dtype`` if it is
specified) as input.
Examples:
.. code-block:: pycon
>>> import paddle
>>> x = paddle.to_tensor(
... [
... [[2.0, 3.0, 4.0, 5.0], [3.0, 4.0, 5.0, 6.0], [7.0, 8.0, 8.0, 9.0]],
... [[1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0], [6.0, 7.0, 8.0, 9.0]],
... ],
... dtype='float32',
... )
>>> out1 = paddle.compat.nn.functional.log_softmax(x, -1)
>>> out2 = paddle.compat.nn.functional.log_softmax(x, -1, dtype='float64')
>>> # out1's data type is float32; out2's data type is float64
>>> print(out1)
>>> print(out2)
"""
if dim is None:
ndim = input.ndim
if ndim == 0 or ndim == 1 or ndim == 3:
dim = 0
else:
dim = 1
if (
(dtype is not None)
and (not isinstance(dtype, core.VarDesc.VarType))
and (not isinstance(dtype, core.DataType))
):
dtype = convert_nptype_to_datatype_or_vartype(dtype)
if in_dynamic_or_pir_mode():
outs_cast = input if dtype is None else _C_ops.cast(input, dtype)
return _C_ops.log_softmax(outs_cast, dim, out=out)
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,160 @@
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations
import re
from typing import TYPE_CHECKING
from ..common_ops_import import Variable
from ..framework import (
LayerHelper,
OpProtoHolder,
convert_nptype_to_datatype_or_vartype,
core,
)
if TYPE_CHECKING:
from paddle import Tensor
__all__ = []
def _convert_(name):
"""
Formatting.
Args:
name: The name/alias
This function takes in a name and converts it to a standard format of
group1_group2. Where as per the regular expression, group1 can have
alphabets and numbers and group2 has capital alphabets.
"""
s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
def generate_layer_fn(op_type: str):
"""Register the Python layer for an Operator.
Args:
op_type: The name of the operator to be created.
This function takes in the operator type (sigmoid, mean , average etc) and
creates the operator functionality.
"""
op_proto = OpProtoHolder.instance().get_op_proto(op_type)
not_intermediate_outputs = [
output for output in op_proto.outputs if not output.intermediate
]
intermediate_outputs = [
output for output in op_proto.outputs if output.intermediate
]
if len(not_intermediate_outputs) != 1:
raise ValueError(
"Only one non intermediate output operator can be"
f"automatically generated. {op_type}"
)
if not_intermediate_outputs[0].duplicable:
raise ValueError(
"Only non duplicable op can be automatically generated."
)
for output in intermediate_outputs:
if output.duplicable:
raise ValueError(
"The op can be automatically generated only when "
"all intermediate ops are not duplicable."
)
o_name = not_intermediate_outputs[0].name
intermediate_output_names = [output.name for output in intermediate_outputs]
def infer_and_check_dtype(op_proto, *args, **kwargs):
"""
This function performs the sanity check for dtype and
instance type.
"""
dtype = None
for ipt in op_proto.inputs:
name = _convert_(ipt.name)
val = kwargs.pop(name, [])
if not isinstance(val, list) and not isinstance(val, tuple):
val = [val]
if len(val) == 0:
if len(args) == 0:
continue
val = [args[0]]
args = args[1:]
for each in val:
if not isinstance(each, Variable):
raise ValueError(f"input of {op_type} must be variable")
if dtype is None:
dtype = each.dtype
elif dtype != each.dtype:
raise ValueError(
f"operator {op_type} must input same dtype. {dtype} vs {each.dtype}"
)
if dtype is None:
arg_dtype = kwargs.get("dtype")
if arg_dtype:
if not isinstance(arg_dtype, core.VarDesc.VarType):
dtype = convert_nptype_to_datatype_or_vartype(arg_dtype)
else:
dtype = arg_dtype
else:
dtype = core.VarDesc.VarType.FP32
return dtype
def func(*args, **kwargs) -> Tensor:
helper = LayerHelper(op_type, **kwargs)
dtype = infer_and_check_dtype(op_proto, *args, **kwargs)
inputs = {}
for ipt in op_proto.inputs:
name = _convert_(ipt.name)
val = kwargs.pop(name, [])
if not isinstance(val, list) and not isinstance(val, tuple):
val = [val]
if len(val) == 0 and len(args) != 0:
val = args[0]
args = args[1:]
inputs[ipt.name] = val
outputs = {}
out = kwargs.pop(_convert_(o_name), [])
if out:
out_var = out[0] if isinstance(out, (list, tuple)) else out
else:
out_var = helper.create_variable_for_type_inference(dtype=dtype)
outputs[o_name] = [out_var]
for name in intermediate_output_names:
outputs[name] = [
helper.create_variable_for_type_inference(dtype=dtype)
]
helper.append_op(
type=op_type, inputs=inputs, outputs=outputs, attrs=kwargs
)
return helper.append_activation(out_var)
func.__name__ = op_type
return func
File diff suppressed because it is too large Load Diff
+878
View File
@@ -0,0 +1,878 @@
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations
from typing import TYPE_CHECKING, Any, TypeGuard
import paddle
from paddle import _C_ops
from paddle._C_ops import ( # noqa: F401
allclose,
bitwise_and,
bitwise_and_,
bitwise_not,
bitwise_not_,
bitwise_or,
bitwise_or_,
bitwise_xor,
bitwise_xor_,
greater_than,
isclose,
logical_and,
logical_not,
logical_or,
logical_xor,
)
from paddle.tensor.creation import full
from paddle.tensor.math import broadcast_shape
from paddle.utils.decorator_utils import (
param_one_alias,
param_two_alias,
)
from paddle.utils.inplace_utils import inplace_apis_in_dygraph_only
from ..base.data_feeder import check_type, check_variable_and_dtype
from ..common_ops_import import Variable
from ..framework import (
LayerHelper,
in_dynamic_mode,
in_dynamic_or_pir_mode,
in_pir_mode,
)
if TYPE_CHECKING:
from paddle import Tensor
__all__ = []
@inplace_apis_in_dygraph_only
def logical_and_(x: Tensor, y: Tensor, name: str | None = None) -> Tensor:
r"""
Inplace version of ``logical_and`` API, the output Tensor will be inplaced with input ``x``.
Please refer to :ref:`api_paddle_logical_and`.
"""
out_shape = broadcast_shape(x.shape, y.shape)
if out_shape != x.shape:
raise ValueError(
f"The shape of broadcast output {out_shape} is different from that of inplace tensor {x.shape} in the Inplace operation."
)
if in_dynamic_mode():
return _C_ops.logical_and_(x, y)
@inplace_apis_in_dygraph_only
def logical_or_(x: Tensor, y: Tensor, name: str | None = None) -> Tensor:
r"""
Inplace version of ``logical_or`` API, the output Tensor will be inplaced with input ``x``.
Please refer to :ref:`api_paddle_logical_or`.
"""
out_shape = broadcast_shape(x.shape, y.shape)
if out_shape != x.shape:
raise ValueError(
f"The shape of broadcast output {out_shape} is different from that of inplace tensor {x.shape} in the Inplace operation."
)
if in_dynamic_mode():
return _C_ops.logical_or_(x, y)
@inplace_apis_in_dygraph_only
def logical_xor_(x: Tensor, y: Tensor, name: str | None = None) -> Tensor:
r"""
Inplace version of ``logical_xor`` API, the output Tensor will be inplaced with input ``x``.
Please refer to :ref:`api_paddle_logical_xor`.
"""
out_shape = broadcast_shape(x.shape, y.shape)
if out_shape != x.shape:
raise ValueError(
f"The shape of broadcast output {out_shape} is different from that of inplace tensor {x.shape} in the Inplace operation."
)
if in_dynamic_mode():
return _C_ops.logical_xor_(x, y)
@inplace_apis_in_dygraph_only
def logical_not_(x: Tensor, name: str | None = None) -> Tensor:
r"""
Inplace version of ``logical_not`` API, the output Tensor will be inplaced with input ``x``.
Please refer to :ref:`api_paddle_logical_not`.
"""
if in_dynamic_mode():
return _C_ops.logical_not_(x)
def is_empty(x: Tensor, name: str | None = None) -> Tensor:
"""
Test whether a Tensor is empty.
Args:
x (Tensor): The Tensor to be tested.
name (str|None, optional): The default value is ``None`` . Normally users don't have to set this parameter. For more information, please refer to :ref:`api_guide_Name` .
Returns:
Tensor: A bool scalar Tensor. True if 'x' is an empty Tensor.
Examples:
.. code-block:: pycon
>>> import paddle
>>> input = paddle.rand(shape=[4, 32, 32], dtype='float32')
>>> res = paddle.is_empty(x=input)
>>> print(res)
Tensor(shape=[], dtype=bool, place=Place(cpu), stop_gradient=True,
False)
"""
if in_dynamic_mode():
return _C_ops.is_empty(x)
check_variable_and_dtype(
x, 'x', ['float32', 'float64', 'int32', 'int64'], 'is_empty'
)
check_type(name, "name", (str, type(None)), "is_empty")
if in_pir_mode():
return _C_ops.is_empty(x)
else:
helper = LayerHelper("is_empty", **locals())
cond = helper.create_variable_for_type_inference(dtype='bool')
cond.stop_gradient = True
helper.append_op(
type='is_empty', inputs={'X': [x]}, outputs={'Out': [cond]}
)
return cond
def equal_all(x: Tensor, y: Tensor, name: str | None = None) -> Tensor:
"""
Returns the truth value of :math:`x == y`. True if two inputs have the same elements, False otherwise.
Note:
The output has no gradient.
Args:
x(Tensor): Tensor, data type is bool, float32, float64, int32, int64.
y(Tensor): Tensor, data type is bool, float32, float64, int32, int64.
name(str|None, optional): The default value is None. Normally there is no need for
user to set this property. For more information, please refer to :ref:`api_guide_Name`.
Returns:
Tensor: output Tensor, data type is bool, value is [False] or [True].
Examples:
.. code-block:: pycon
>>> import paddle
>>> x = paddle.to_tensor([1, 2, 3])
>>> y = paddle.to_tensor([1, 2, 3])
>>> z = paddle.to_tensor([1, 4, 3])
>>> result1 = paddle.equal_all(x, y)
>>> print(result1)
Tensor(shape=[], dtype=bool, place=Place(cpu), stop_gradient=True,
True)
>>> result2 = paddle.equal_all(x, z)
>>> print(result2)
Tensor(shape=[], dtype=bool, place=Place(cpu), stop_gradient=True,
False)
"""
if in_dynamic_or_pir_mode():
return _C_ops.equal_all(x, y)
else:
helper = LayerHelper("equal_all", **locals())
out = helper.create_variable_for_type_inference(dtype='bool')
helper.append_op(
type='equal_all',
inputs={'X': [x], 'Y': [y]},
outputs={'Out': [out]},
)
return out
@param_two_alias(["x", "input"], ["y", "other"])
def equal(
x: Tensor, y: Tensor, name: str | None = None, *, out: Tensor | None = None
) -> Tensor:
"""
This layer returns the truth value of :math:`x == y` elementwise.
Note:
The output has no gradient.
Args:
x (Tensor): Tensor, data type is bool, float16, float32, float64, uint8, int8, int16, int32, int64, complex64, complex128.
alias: ``input``
y (Tensor): Tensor, data type is bool, float16, float32, float64, uint8, int8, int16, int32, int64, complex64, complex128.
alias: ``other``
name (str|None, optional): The default value is None. Normally there is no need for
user to set this property. For more information, please refer to :ref:`api_guide_Name`.
out (Tensor, optional): Output tensor. If provided, the result will be stored in this tensor.
Returns:
Tensor: output Tensor, it's shape is the same as the input's Tensor,
and the data type is bool. The result of this op is stop_gradient.
Examples:
.. code-block:: pycon
>>> import paddle
>>> x = paddle.to_tensor([1, 2, 3])
>>> y = paddle.to_tensor([1, 3, 2])
>>> result1 = paddle.equal(x, y)
>>> print(result1)
Tensor(shape=[3], dtype=bool, place=Place(cpu), stop_gradient=True,
[True , False, False])
"""
if not isinstance(
y, (int, bool, float, Variable, complex, paddle.pir.Value)
):
raise TypeError(
f"Type of input args must be float, bool, complex, int or Tensor, but received type {type(y)}"
)
if not isinstance(y, (Variable, paddle.pir.Value, complex)):
y = full(shape=[], dtype=x.dtype, fill_value=y)
if isinstance(y, complex):
# full not support for complex yet
y = paddle.to_tensor(y)
if in_dynamic_or_pir_mode():
return _C_ops.equal(x, y, out=out)
else:
check_variable_and_dtype(
x,
"x",
[
"bool",
"float16",
"float32",
"float64",
"uint8",
"int8",
"int16",
"int32",
"int64",
"uint16",
"complex64",
"complex128",
],
"equal",
)
check_variable_and_dtype(
y,
"y",
[
"bool",
"float16",
"float32",
"float64",
"uint8",
"int8",
"int16",
"int32",
"int64",
"uint16",
"complex64",
"complex128",
],
"equal",
)
helper = LayerHelper("equal", **locals())
out = helper.create_variable_for_type_inference(dtype='bool')
out.stop_gradient = True
helper.append_op(
type='equal',
inputs={'X': [x], 'Y': [y]},
outputs={'Out': [out]},
)
return out
@inplace_apis_in_dygraph_only
def equal_(x: Tensor, y: Tensor, name: str | None = None) -> Tensor:
r"""
Inplace version of ``equal`` API, the output Tensor will be inplaced with input ``x``.
Please refer to :ref:`api_paddle_equal`.
"""
out_shape = broadcast_shape(x.shape, y.shape)
if out_shape != x.shape:
raise ValueError(
f"The shape of broadcast output {out_shape} is different from that of inplace tensor {x.shape} in the Inplace operation."
)
if in_dynamic_or_pir_mode():
return _C_ops.equal_(x, y)
@param_two_alias(["x", "input"], ["y", "other"])
def greater_equal(
x: Tensor, y: Tensor, name: str | None = None, *, out: Tensor | None = None
) -> Tensor:
"""
Returns the truth value of :math:`x >= y` elementwise, which is equivalent function to the overloaded operator `>=`.
Note:
The output has no gradient.
Args:
x (Tensor): First input to compare which is N-D tensor. The input data type should be bool, bfloat16, float16, float32, float64, uint8, int8, int16, int32, int64, complex64, complex128.
Alias: ``input``.
y (Tensor): Second input to compare which is N-D tensor. The input data type should be bool, bfloat16, float16, float32, float64, uint8, int8, int16, int32, int64, complex64, complex128.
Alias: ``other``.
name (str|None, optional): The default value is None. Normally there is no need for
user to set this property. For more information, please refer to :ref:`api_guide_Name`.
out (Tensor, optional): The output tensor. If set, the result will be stored in this tensor. Default is None.
Returns:
Tensor: The output shape is same as input :attr:`x`. The output data type is bool.
Examples:
.. code-block:: pycon
>>> import paddle
>>> x = paddle.to_tensor([1, 2, 3])
>>> y = paddle.to_tensor([1, 3, 2])
>>> result1 = paddle.greater_equal(x, y)
>>> print(result1)
Tensor(shape=[3], dtype=bool, place=Place(cpu), stop_gradient=True,
[True , False, True ])
"""
if in_dynamic_or_pir_mode():
return _C_ops.greater_equal(x, y, out=out)
else:
check_variable_and_dtype(
x,
"x",
[
"bool",
"float16",
"float32",
"float64",
"uint8",
"int8",
"int16",
"int32",
"int64",
"uint16",
"complex64",
"complex128",
],
"greater_equal",
)
check_variable_and_dtype(
y,
"y",
[
"bool",
"float16",
"float32",
"float64",
"uint8",
"int8",
"int16",
"int32",
"int64",
"uint16",
"complex64",
"complex128",
],
"greater_equal",
)
helper = LayerHelper("greater_equal", **locals())
out = helper.create_variable_for_type_inference(dtype='bool')
out.stop_gradient = True
helper.append_op(
type='greater_equal',
inputs={'X': [x], 'Y': [y]},
outputs={'Out': [out]},
)
return out
@inplace_apis_in_dygraph_only
def greater_equal_(x: Tensor, y: Tensor, name: str | None = None) -> Tensor:
r"""
Inplace version of ``greater_equal`` API, the output Tensor will be inplaced with input ``x``.
Please refer to :ref:`api_paddle_greater_equal`.
"""
out_shape = broadcast_shape(x.shape, y.shape)
if out_shape != x.shape:
raise ValueError(
f"The shape of broadcast output {out_shape} is different from that of inplace tensor {x.shape} in the Inplace operation."
)
if in_dynamic_mode():
return _C_ops.greater_equal_(x, y)
@inplace_apis_in_dygraph_only
@param_two_alias(["x", "input"], ["y", "other"])
def greater_than_(x: Tensor, y: Tensor, name: str | None = None) -> Tensor:
r"""
Inplace version of ``greater_than`` API, the output Tensor will be inplaced with input ``x``.
Please refer to :ref:`api_paddle_greater_than`.
"""
if not isinstance(y, paddle.Tensor):
y = paddle.to_tensor(y, dtype=x.dtype)
out_shape = broadcast_shape(x.shape, y.shape)
if out_shape != x.shape:
raise ValueError(
f"The shape of broadcast output {out_shape} is different from that of inplace tensor {x.shape} in the Inplace operation."
)
if in_dynamic_mode():
return _C_ops.greater_than_(x, y)
@param_two_alias(["x", "input"], ["y", "other"])
def less_equal(
x: Tensor, y: Tensor, name: str | None = None, *, out: Tensor | None = None
) -> Tensor:
"""
Returns the truth value of :math:`x <= y` elementwise, which is equivalent function to the overloaded operator `<=`.
Note:
The output has no gradient.
Args:
x (Tensor): First input to compare which is N-D tensor. The input data type should be bool, bfloat16, float16, float32, float64, uint8, int8, int16, int32, int64, complex64, complex128.
Alias: ``input``.
y (Tensor): Second input to compare which is N-D tensor. The input data type should be bool, bfloat16, float16, float32, float64, uint8, int8, int16, int32, int64, complex64, complex128.
Alias: ``other``.
name (str|None, optional): The default value is None. Normally there is no need for
user to set this property. For more information, please refer to :ref:`api_guide_Name`.
out (Tensor, optional): The output tensor. If set, the result will be stored in this tensor. Default is None.
Returns:
Tensor: The output shape is same as input :attr:`x`. The output data type is bool.
Examples:
.. code-block:: pycon
>>> import paddle
>>> x = paddle.to_tensor([1, 2, 3])
>>> y = paddle.to_tensor([1, 3, 2])
>>> result1 = paddle.less_equal(x, y)
>>> print(result1)
Tensor(shape=[3], dtype=bool, place=Place(cpu), stop_gradient=True,
[True , True , False])
"""
if in_dynamic_or_pir_mode():
return _C_ops.less_equal(x, y, out=out)
else:
check_variable_and_dtype(
x,
"x",
[
"bool",
"float16",
"float32",
"float64",
"uint8",
"int8",
"int16",
"int32",
"int64",
"uint16",
"complex64",
"complex128",
],
"less_equal",
)
check_variable_and_dtype(
y,
"y",
[
"bool",
"float16",
"float32",
"float64",
"uint8",
"int8",
"int16",
"int32",
"int64",
"uint16",
"complex64",
"complex128",
],
"less_equal",
)
helper = LayerHelper("less_equal", **locals())
out = helper.create_variable_for_type_inference(dtype='bool')
out.stop_gradient = True
helper.append_op(
type='less_equal',
inputs={'X': [x], 'Y': [y]},
outputs={'Out': [out]},
)
return out
@inplace_apis_in_dygraph_only
def less_equal_(x: Tensor, y: Tensor, name: str | None = None) -> Tensor:
r"""
Inplace version of ``less_equal`` API, the output Tensor will be inplaced with input ``x``.
Please refer to :ref:`api_paddle_less_equal`.
"""
out_shape = broadcast_shape(x.shape, y.shape)
if out_shape != x.shape:
raise ValueError(
f"The shape of broadcast output {out_shape} is different from that of inplace tensor {x.shape} in the Inplace operation."
)
if in_dynamic_mode():
return _C_ops.less_equal_(x, y)
@param_two_alias(["x", "input"], ["y", "other"])
def less_than(
x: Tensor, y: Tensor, name: str | None = None, *, out: Tensor | None = None
) -> Tensor:
"""
Returns the truth value of :math:`x < y` elementwise, which is equivalent function to the overloaded operator `<`.
Note:
The output has no gradient.
Args:
x (Tensor): First input to compare which is N-D tensor. The input data type should be bool, bfloat16, float16, float32, float64, uint8, int8, int16, int32, int64, complex64, complex128.
Alias: ``input``
y (Tensor): Second input to compare which is N-D tensor. The input data type should be bool, bfloat16, float16, float32, float64, uint8, int8, int16, int32, int64, complex64, complex128.
Alias: ``other``
name (str|None, optional): The default value is None. Normally there is no need for
user to set this property. For more information, please refer to :ref:`api_guide_Name`.
out (Tensor, optional): The output tensor. If set, the result will be stored in this tensor. Default is None.
Returns:
Tensor: The output shape is same as input :attr:`x`. The output data type is bool.
Examples:
.. code-block:: pycon
>>> import paddle
>>> x = paddle.to_tensor([1, 2, 3])
>>> y = paddle.to_tensor([1, 3, 2])
>>> result1 = paddle.less_than(x, y)
>>> print(result1)
Tensor(shape=[3], dtype=bool, place=Place(cpu), stop_gradient=True,
[False, True , False])
"""
if in_dynamic_or_pir_mode():
return _C_ops.less_than(x, y, out=out)
else:
check_variable_and_dtype(
x,
"x",
[
"bool",
"float16",
"float32",
"float64",
"uint8",
"int8",
"int16",
"int32",
"int64",
"uint16",
"complex64",
"complex128",
],
"less_than",
)
check_variable_and_dtype(
y,
"y",
[
"bool",
"float16",
"float32",
"float64",
"uint8",
"int8",
"int16",
"int32",
"int64",
"uint16",
"complex64",
"complex128",
],
"less_than",
)
helper = LayerHelper("less_than", **locals())
out = helper.create_variable_for_type_inference(dtype='bool')
out.stop_gradient = True
helper.append_op(
type='less_than',
inputs={'X': [x], 'Y': [y]},
outputs={'Out': [out]},
)
return out
@inplace_apis_in_dygraph_only
def less_than_(x: Tensor, y: Tensor, name: str | None = None) -> Tensor:
r"""
Inplace version of ``less_than`` API, the output Tensor will be inplaced with input ``x``.
Please refer to :ref:`api_paddle_less_than`.
"""
out_shape = broadcast_shape(x.shape, y.shape)
if out_shape != x.shape:
raise ValueError(
f"The shape of broadcast output {out_shape} is different from that of inplace tensor {x.shape} in the Inplace operation."
)
if in_dynamic_mode():
return _C_ops.less_than_(x, y)
@inplace_apis_in_dygraph_only
def less_(x: Tensor, y: Tensor, name: str | None = None) -> Tensor:
r"""
Inplace version of ``less_`` API, the output Tensor will be inplaced with input ``x``.
Please refer to :ref:`api_paddle_less`.
"""
# Directly call less_than_ API
return less_than_(x, y, name)
@param_two_alias(["x", "input"], ["y", "other"])
def not_equal(
x: Tensor, y: Tensor, name: str | None = None, *, out: Tensor | None = None
) -> Tensor:
"""
Returns the truth value of :math:`x != y` elementwise, which is equivalent function to the overloaded operator `!=`.
Note:
The output has no gradient.
Args:
x (Tensor): First input to compare which is N-D tensor. The input data type should be bool, bfloat16, float16, float32, float64, uint8, int8, int16, int32, int64, complex64, complex128.
Alias: ``input``.
y (Tensor): Second input to compare which is N-D tensor. The input data type should be bool, bfloat16, float16, float32, float64, uint8, int8, int16, int32, int64, complex64, complex128.
Alias: ``other``.
name (str|None, optional): The default value is None. Normally there is no need for
user to set this property. For more information, please refer to :ref:`api_guide_Name`.
out (Tensor, optional): The output tensor. If set, the result will be stored in this tensor. Default is None.
Returns:
Tensor: The output shape is same as input :attr:`x`. The output data type is bool.
Examples:
.. code-block:: pycon
>>> import paddle
>>> x = paddle.to_tensor([1, 2, 3])
>>> y = paddle.to_tensor([1, 3, 2])
>>> result1 = paddle.not_equal(x, y)
>>> print(result1)
Tensor(shape=[3], dtype=bool, place=Place(cpu), stop_gradient=True,
[False, True , True ])
"""
if in_dynamic_or_pir_mode():
return _C_ops.not_equal(x, y, out=out)
else:
check_variable_and_dtype(
x,
"x",
[
"bool",
"float16",
"float32",
"float64",
"uint8",
"int8",
"int16",
"int32",
"int64",
"uint16",
"complex64",
"complex128",
],
"not_equal",
)
check_variable_and_dtype(
y,
"y",
[
"bool",
"float16",
"float32",
"float64",
"uint8",
"int8",
"int16",
"int32",
"int64",
"uint16",
"complex64",
"complex128",
],
"not_equal",
)
helper = LayerHelper("not_equal", **locals())
out = helper.create_variable_for_type_inference(dtype='bool')
out.stop_gradient = True
helper.append_op(
type='not_equal',
inputs={'X': [x], 'Y': [y]},
outputs={'Out': [out]},
)
return out
@inplace_apis_in_dygraph_only
def not_equal_(x: Tensor, y: Tensor, name: str | None = None) -> Tensor:
r"""
Inplace version of ``not_equal`` API, the output Tensor will be inplaced with input ``x``.
Please refer to :ref:`api_paddle_not_equal`.
"""
out_shape = broadcast_shape(x.shape, y.shape)
if out_shape != x.shape:
raise ValueError(
f"The shape of broadcast output {out_shape} is different from that of inplace tensor {x.shape} in the Inplace operation."
)
if in_dynamic_mode():
return _C_ops.not_equal_(x, y)
@param_one_alias(["x", "obj"])
def is_tensor(x: Any) -> TypeGuard[Tensor]:
"""
Tests whether input object is a paddle.Tensor.
.. note::
Alias Support: The parameter name ``obj`` can be used as an alias for ``x``.
For example, ``is_tensor(obj=tensor_x)`` is equivalent to ``is_tensor(x=tensor_x)``.
Args:
x (object): Object to test. alias: ``obj``.
Returns:
A boolean value. True if ``x`` is a paddle.Tensor, otherwise False.
Examples:
.. code-block:: pycon
>>> import paddle
>>> input1 = paddle.rand(shape=[2, 3, 5], dtype='float32')
>>> check = paddle.is_tensor(input1)
>>> print(check)
True
>>> input3 = [1, 4]
>>> check = paddle.is_tensor(input3)
>>> print(check)
False
"""
if in_dynamic_or_pir_mode():
return isinstance(x, (paddle.Tensor, paddle.pir.Value))
else:
return isinstance(x, Variable)
def __rand__(x: Tensor, y: int | bool):
if isinstance(y, (int, bool)):
y_tensor = paddle.to_tensor(y, dtype=x.dtype)
return bitwise_and(y_tensor, x)
else:
raise TypeError(
f"unsupported operand type(s) for |: '{type(y).__name__}' and 'Tensor'"
)
def __ror__(
x: Tensor,
y: int | bool,
out: Tensor | None = None,
name: str | None = None,
) -> Tensor:
if isinstance(y, (int, bool)):
y = paddle.to_tensor(y, dtype=x.dtype)
return bitwise_or(y, x, out=out, name=name)
else:
raise TypeError(
f"unsupported operand type(s) for |: '{type(y).__name__}' and 'Tensor'"
)
def __rxor__(
x: Tensor,
y: int | bool,
out: Tensor | None = None,
name: str | None = None,
) -> Tensor:
if isinstance(y, (int, bool)):
y = paddle.to_tensor(y, dtype=x.dtype)
return bitwise_xor(y, x, out=out, name=name)
else:
raise TypeError(
f"unsupported operand type(s) for |: '{type(y).__name__}' and 'Tensor'"
)
def bitwise_invert(
x: Tensor, out: Tensor | None = None, name: str | None = None
) -> Tensor:
r"""
Apply ``bitwise_not`` (bitwise inversion) on Tensor ``x``.
This is an alias to the ``paddle.bitwise_not`` function.
.. math::
Out = \sim X
Note:
``paddle.bitwise_invert`` is functionally equivalent to ``paddle.bitwise_not``.
Args:
x (Tensor): Input Tensor of ``bitwise_invert``. It is a N-D Tensor of bool, uint8, int8, int16, int32, int64.
out (Tensor|None, optional): Result of ``bitwise_invert``. It is a N-D Tensor with the same data type as the input Tensor. Default: None.
name (str|None, optional): The default value is None. This property is typically not set by the user.
For more information, please refer to :ref:`api_guide_Name`.
Returns:
Tensor: Result of ``bitwise_invert``. It is a N-D Tensor with the same data type as the input Tensor.
Examples:
.. code-block:: pycon
>>> import paddle
>>> x = paddle.to_tensor([-5, -1, 1])
>>> res = x.bitwise_invert()
>>> print(res)
Tensor(shape=[3], dtype=int64, place=Place(cpu), stop_gradient=True,
[ 4, 0, -2])
"""
# Directly call bitwise_not for the implementation
return bitwise_not(x, out=out, name=name)
@inplace_apis_in_dygraph_only
def bitwise_invert_(x: Tensor, name: str | None = None) -> Tensor:
r"""
Inplace version of ``bitwise_invert`` API, the output Tensor will be inplaced with input ``x``.
Please refer to :ref:`api_paddle_bitwise_invert_`.
"""
# Directly call bitwise_not_ for the implementation
return bitwise_not_(x, name=name)
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+66
View File
@@ -0,0 +1,66 @@
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations
from paddle._C_ops import ( # noqa: F401
abs,
abs_,
acos,
acos_,
acosh,
acosh_,
asin,
asin_,
asinh,
asinh_,
atan,
atan_,
atanh,
atanh_,
ceil,
ceil_,
cos,
cos_,
cosh,
cosh_,
erf,
erf_,
exp,
exp_,
expm1,
expm1_,
floor,
floor_,
reciprocal,
reciprocal_,
round,
round_,
rsqrt,
rsqrt_,
scale as _scale,
sigmoid,
sigmoid_,
sin,
sin_,
sinh,
sinh_,
sqrt,
sqrt_,
square,
square_,
tan,
tan_,
)
__all__ = []
File diff suppressed because it is too large Load Diff
+1551
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+314
View File
@@ -0,0 +1,314 @@
# Copyright (c) 2024 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# The `Tensor` template `tensor.prototype.pyi` for `tools/gen_tensor_stub.py` to generate the stub file `tensor.pyi`.
# Add docstring, attributes, methods and alias with type annotations for `Tensor` in `tensor.prototype.pyi`
# if not conveniently coding in original place (like c++ source file).
# Import common typings for generated methods
# isort: off
from typing import * # noqa: F403
from typing_extensions import * # type: ignore # noqa: F403
from paddle._typing import * # noqa: F403
# isort: on
from builtins import ( # noqa: F401
bool as _bool,
bytes as _bytes,
complex as _complex,
float as _float,
int as _int,
str as _str,
)
from collections.abc import Iterator
from typing import Any, Literal, overload
import numpy.typing as npt
import paddle
from paddle import (
ParamAttr, # noqa: F401
_typing,
)
from paddle.base.dygraph.tensor_patch_methods import (
TensorHookRemoveHelper, # noqa: F401
)
from paddle.tensor.linalg import _POrder # noqa: F401
from paddle.tensor.stat import _Interpolation # noqa: F401
# annotation: ${eager_param_base_begin}
class AbstractEagerParamBase:
# annotation: ${eager_param_base_docstring}
# annotation: ${eager_param_base_attributes}
# annotation: ${eager_param_base_methods}
@property
def trainable(self) -> _bool: ...
@trainable.setter
def trainable(self, trainable: _bool) -> None: ...
# annotation: ${eager_param_base_alias}
# annotation: ${eager_param_base_end}
# annotation: ${tensor_begin}
class AbstractTensor:
# annotation: ${tensor_attributes}
# If method defined below, we should make the method's signature complete,
# and ignore the signature extracted from `paddle.Tensor`.
# `gen_tensor.stub.py` will NOT overwrite the signature below.
# If method has docstring (ignoring the spaces), `gen_tensor.stub.py` also will NOT overwrite it.
# annotation: ${tensor_methods}
@overload
def __init__(self) -> None: ...
@overload
def __init__(
self, dtype, dims, name: _str, type, persistable: _bool
) -> None: ...
@overload
def __init__(
self,
value: npt.NDArray[Any],
place,
persistable: _bool,
zero_copy: _bool,
name: _str,
stop_gradient: _bool,
) -> None: ...
@overload
def __init__(self, value: npt.NDArray[Any]) -> None: ...
@overload
def __init__(
self, value: Tensor, dims, name: _str, process_mesh, placements
) -> None: ...
@overload
def __init__(self, value: Tensor, place, name: _str) -> None: ...
@overload
def __init__(self, *args: Any, **kwargs: Any) -> None:
"""
ref: paddle/fluid/pybind/eager.cc
We should have init function with signature:
1.
def __init__ ()
2.
def __init__ (
dtype: paddle::framework::proto::VarType::Type,
dims: vector<int>,
name: std::string,
type: paddle::framework::proto::VarType::DenseTensor,
persistable: bool)
3. (multi-place)
(should have at least one parameter, one parameter equals to case 4, zero
parameter equals to case 1)
def __init__ (
value: ndarray,
place: paddle::platform::Place,
persistable: bool,
zero_copy: bool,
name: std::string,
stop_gradient: bool)
4.
def __init__ (
value: ndarray)
5.
def __init__ (
tensor: Tensor)
6. (multi-place)
(should have at least one parameter, one parameter equals to case 5, zero
parameter equals to case 1.)
def __init__ (
global_tensor: Tensor,
place: paddle::platform::Place,
name: std::string,
process_mesh: phi::distributed::ProcessMesh
placements: std::vector<Placement>)
7. (multi-place)
(should have at least one parameter, one parameter equals to case 5, zero
parameter equals to case 1.)
def __init__ (
local_tensor: Tensor,
global_dims: vector<int>,
name: std::string,
process_mesh: phi::distributed::ProcessMesh
placements: std::vector<Placement>)
8. (multi-place) (should have at least one parameter, one parameter similar
to case 5, zero parameter equals to case 1.)
def __init__ (
tensor: FrameworkTensor,
place: paddle::platform::Place,
name: std::string)
"""
...
# rich comparison
def __eq__(self, y: _typing.TensorLike) -> Tensor: ... # type: ignore[override]
def __ge__(self, y: _typing.TensorLike) -> Tensor: ...
def __gt__(self, y: _typing.TensorLike) -> Tensor: ...
def __lt__(self, y: _typing.TensorLike) -> Tensor: ...
def __le__(self, y: _typing.TensorLike) -> Tensor: ...
def __ne__(self, y: _typing.TensorLike) -> Tensor: ... # type: ignore[override]
# binary arithmetic operations
def __add__(self, y: _typing.TensorLike) -> Tensor: ...
def __sub__(self, y: _typing.TensorLike) -> Tensor: ...
def __mul__(self, y: _typing.TensorLike) -> Tensor: ...
def __matmul__(self, y: _typing.TensorLike) -> Tensor: ...
def __truediv__(self, y: _typing.TensorLike) -> Tensor: ...
def __floordiv__(self, y: _typing.TensorLike) -> Tensor: ...
def __mod__(self, y: _typing.TensorLike) -> Tensor: ...
def __pow__(self, y: _typing.TensorLike) -> Tensor: ...
def __and__(self, y: _typing.TensorLike) -> Tensor: ...
def __ror__(self, y: _typing.TensorLike) -> Tensor: ...
def __rxor__(self, y: _typing.TensorLike) -> Tensor: ...
def __div__(self, y: _typing.TensorLike) -> Tensor: ...
def __radd__(self, y: _typing.TensorLike) -> Tensor: ... # type: ignore
def __rsub__(self, y: _typing.TensorLike) -> Tensor: ... # type: ignore
def __rmul__(self, y: _typing.TensorLike) -> Tensor: ... # type: ignore
def __rmatmul__(self, y: _typing.TensorLike) -> Tensor: ... # type: ignore
def __rtruediv__(self, y: _typing.TensorLike) -> Tensor: ... # type: ignore
def __rmod__(self, y: _typing.TensorLike) -> Tensor: ... # type: ignore
def __rpow__(self, y: _typing.TensorLike) -> Tensor: ... # type: ignore
def __rdiv__(self, y: _typing.TensorLike) -> Tensor: ... # type: ignore
def __rfloordiv__(self, y: _typing.TensorLike) -> Tensor: ... # type: ignore
def __rand__(self, y: _typing.TensorLike) -> Tensor: ... # type: ignore
# type cast
def __bool__(self) -> _bool: ...
def __float__(self) -> _float: ...
def __int__(self) -> _int: ...
def __nonzero__(self) -> _bool: ...
def __complex__(self) -> _complex: ...
# emulating container types
def __getitem__(
self,
item: _typing.TensorIndex,
) -> Tensor: ...
def __setitem__(
self,
item: _typing.TensorIndex,
value: Tensor | npt.NDArray[Any] | _complex | _bool,
) -> None: ...
def __len__(self) -> _int: ...
# emulating numeric types
def __index__(self) -> _int: ...
# unary arithmetic operations
def __invert__(self) -> Tensor: ...
def __neg__(self) -> Tensor: ...
def __pos__(self) -> Tensor: ...
# basic
def __hash__(self) -> _int: ...
def clear_gradient(self, set_to_zero: _bool = True) -> None: ...
def clone(self) -> Tensor: ...
def cols(self) -> Tensor: ...
def contiguous(self) -> Tensor: ...
def copy_(self) -> Tensor: ...
def crows(self) -> Tensor: ...
@property
def data(self) -> Tensor: ...
@data.setter
def data(self, value: Tensor) -> None: ...
def data_ptr(self) -> _int: ...
def dense_dim(self) -> _int: ...
def detach(self) -> Tensor: ...
def detach_(self) -> Tensor: ...
@property
def dtype(self) -> paddle.dtype: ...
def element_size(self) -> _int: ...
def get_map_tensor(self) -> Tensor: ...
def get_selected_rows(self) -> None: ...
def get_strides(self) -> list[_int]: ...
def get_tensor(self) -> Tensor: ...
@property
def grad(self) -> Tensor | None: ...
@grad.setter
def grad(self, value: Tensor | None) -> None: ...
@property
def grad_(self) -> Tensor | None: ...
@grad_.setter
def grad_(self, value: Tensor) -> None: ...
@property
def grad_fn(self) -> Any: ...
def is_contiguous(self) -> _bool: ...
def is_coalesced(self) -> _bool: ...
def is_dense(self) -> _bool: ...
def is_dist(self) -> _bool: ...
@property
def is_leaf(self) -> _bool: ...
def is_same_shape(self, y: Tensor) -> _bool: ...
def is_selected_rows(self) -> _bool: ...
def is_sparse(self) -> _bool: ...
def is_sparse_coo(self) -> _bool: ...
def is_sparse_csr(self) -> _bool: ...
@property
def layout(self) -> _typing.DataLayoutND: ...
@property
def name(self) -> _str: ...
@name.setter
def name(self, value: _str) -> None: ...
@property
def ndim(self) -> _int: ...
def nnz(self) -> _int: ...
@property
def num_shard(self) -> _int: ...
def numpy(self) -> npt.NDArray[Any]: ...
@property
def offset(self) -> _int: ...
@property
def persistable(self) -> _bool: ...
@persistable.setter
def persistable(self, value: _bool) -> None: ...
@property
def place(self) -> paddle.core.Place: ...
@property
def placements(self) -> list[paddle.distributed.Placement] | None: ...
@property
def process_mesh(self) -> paddle.distributed.ProcessMesh | None: ...
def rows(self) -> list[_int]: ...
def set_string_list(self, value: _str) -> None: ...
def set_vocab(self, value: dict[_str, _int]) -> None: ...
@property
def shape(self) -> paddle.Size: ...
@property
def size(self) -> _int: ...
def sparse_dim(self) -> _int: ...
@property
def stop_gradient(self) -> _bool: ...
@stop_gradient.setter
def stop_gradient(self, value: _bool) -> None: ...
@property
def strides(self) -> list[_int]: ...
@property
def type(self) -> Any: ...
# virtual methods
def __iter__(self) -> Iterator[Tensor]: ... # For iterating over the tensor
# private methods
def _grad_ivar(self) -> Tensor | None: ...
# annotation: ${tensor_alias}
class Tensor(AbstractTensor, AbstractEagerParamBase):
# annotation: ${tensor_docstring}
__qualname__: Literal["Tensor"]
# annotation: ${tensor_end}
+17
View File
@@ -0,0 +1,17 @@
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# The generated `tensor.pyi` requires this file. It can not guarantee that all
# type checkers will work without deleting this file. So it is necessary to
# keep this file.
+481
View File
@@ -0,0 +1,481 @@
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations
import os
import numpy as np
import paddle
from paddle.base.data_feeder import check_type, convert_dtype
from ..framework import core
__all__ = []
class PrintOptions:
precision = 8
threshold = 1000
edgeitems = 3
linewidth = 80
sci_mode = False
DEFAULT_PRINT_OPTIONS = PrintOptions()
def set_printoptions(
precision: int | None = None,
threshold: int | None = None,
edgeitems: int | None = None,
sci_mode: bool | None = None,
linewidth: int | None = None,
) -> None:
"""Set the printing options for Tensor.
Args:
precision (int|None, optional): Number of digits of the floating number, default 8.
threshold (int|None, optional): Total number of elements printed, default 1000.
edgeitems (int|None, optional): Number of elements in summary at the beginning and ending of each dimension, default 3.
sci_mode (bool|None, optional): Format the floating number with scientific notation or not, default False.
linewidth (int|None, optional): Number of characters each line, default 80.
Returns:
None.
Examples:
.. code-block:: pycon
>>> import paddle
>>> paddle.seed(10)
>>> a = paddle.rand([10, 20])
>>> paddle.set_printoptions(4, 100, 3)
>>> print(a)
Tensor(shape=[10, 20], dtype=float32, place=Place(cpu), stop_gradient=True,
[[0.2727, 0.5489, 0.8655, ..., 0.2916, 0.8525, 0.9000],
[0.3806, 0.8996, 0.0928, ..., 0.9535, 0.8378, 0.6409],
[0.1484, 0.4038, 0.8294, ..., 0.0148, 0.6520, 0.4250],
...,
[0.3426, 0.1909, 0.7240, ..., 0.4218, 0.2676, 0.5679],
[0.5561, 0.2081, 0.0676, ..., 0.9778, 0.3302, 0.9559],
[0.2665, 0.8483, 0.5389, ..., 0.4956, 0.6862, 0.9178]])
"""
kwargs = {}
if precision is not None:
check_type(precision, 'precision', (int), 'set_printoptions')
DEFAULT_PRINT_OPTIONS.precision = precision
kwargs['precision'] = precision
if threshold is not None:
check_type(threshold, 'threshold', (int), 'set_printoptions')
DEFAULT_PRINT_OPTIONS.threshold = threshold
kwargs['threshold'] = threshold
if edgeitems is not None:
check_type(edgeitems, 'edgeitems', (int), 'set_printoptions')
DEFAULT_PRINT_OPTIONS.edgeitems = edgeitems
kwargs['edgeitems'] = edgeitems
if linewidth is not None:
check_type(linewidth, 'linewidth', (int), 'set_printoptions')
DEFAULT_PRINT_OPTIONS.linewidth = linewidth
kwargs['linewidth'] = linewidth
if sci_mode is not None:
check_type(sci_mode, 'sci_mode', (bool), 'set_printoptions')
DEFAULT_PRINT_OPTIONS.sci_mode = sci_mode
kwargs['sci_mode'] = sci_mode
core.set_printoptions(**kwargs)
def _to_summary(var):
edgeitems = DEFAULT_PRINT_OPTIONS.edgeitems
# Handle tensor of shape contains 0, like [0, 2], [3, 0, 3]
if np.prod(var.shape) == 0:
return np.array([])
if len(var.shape) == 0:
return var
elif len(var.shape) == 1:
if var.shape[0] > 2 * edgeitems:
return np.concatenate([var[:edgeitems], var[(-1 * edgeitems) :]])
else:
return var
else:
# recursively handle all dimensions
if var.shape[0] > 2 * edgeitems:
begin = list(var[:edgeitems])
end = list(var[(-1 * edgeitems) :])
return np.stack([_to_summary(x) for x in (begin + end)])
else:
return np.stack([_to_summary(x) for x in var])
def _format_item(np_var, max_width=0, signed=False):
if (
np_var.dtype == np.float32
or np_var.dtype == np.float64
or np_var.dtype == np.float16
):
if DEFAULT_PRINT_OPTIONS.sci_mode:
item_str = f'{np_var:.{DEFAULT_PRINT_OPTIONS.precision}e}'
elif np.ceil(np_var) == np_var:
item_str = f'{np_var:.0f}.'
else:
item_str = f'{np_var:.{DEFAULT_PRINT_OPTIONS.precision}f}'
elif np_var.dtype == np.complex64 or np_var.dtype == np.complex128:
re = np.real(np_var)
im = np.imag(np_var)
prec = DEFAULT_PRINT_OPTIONS.precision
if DEFAULT_PRINT_OPTIONS.sci_mode:
if im >= 0:
item_str = f'({re:.{prec}e}+{im:.{prec}e}j)'
else:
item_str = f'({re:.{prec}e}{im:.{prec}e}j)'
else:
if im >= 0:
item_str = f'({re:.{prec}f}+{im:.{prec}f}j)'
else:
item_str = f'({re:.{prec}f}{im:.{prec}f}j)'
else:
item_str = f'{np_var}'
if max_width > len(item_str):
if signed: # handle sign character for tensor with negative item
if np_var < 0:
return item_str.ljust(max_width)
else:
return ' ' + item_str.ljust(max_width - 1)
else:
return item_str.ljust(max_width)
else: # used for _get_max_width
return item_str
def _get_max_width(var):
# return max_width for a scalar
max_width = 0
signed = False
for item in list(var.flatten()):
if (not signed) and (item < 0):
signed = True
item_str = _format_item(item)
max_width = max(max_width, len(item_str))
return max_width, signed
def _format_tensor(var, summary, indent=0, max_width=0, signed=False):
"""
Format a tensor
Args:
var(Tensor): The tensor to be formatted.
summary(bool): Do summary or not. If true, some elements will not be printed, and be replaced with "...".
indent(int): The indent of each line.
max_width(int): The max width of each elements in var.
signed(bool): Print +/- or not.
"""
edgeitems = DEFAULT_PRINT_OPTIONS.edgeitems
linewidth = DEFAULT_PRINT_OPTIONS.linewidth
if len(var.shape) == 0:
# 0-D Tensor, whose shape = [], should be formatted like this.
return _format_item(var, max_width, signed)
elif len(var.shape) == 1:
item_length = max_width + 2
items_per_line = max(1, (linewidth - indent) // item_length)
if summary and var.shape[0] > 2 * edgeitems:
items = (
[
_format_item(var[i], max_width, signed)
for i in range(edgeitems)
]
+ ['...']
+ [
_format_item(var[i], max_width, signed)
for i in range(var.shape[0] - edgeitems, var.shape[0])
]
)
else:
items = [
_format_item(var[i], max_width, signed)
for i in range(var.shape[0])
]
lines = [
items[i : i + items_per_line]
for i in range(0, len(items), items_per_line)
]
s = (',\n' + ' ' * (indent + 1)).join(
[', '.join(line) for line in lines]
)
return '[' + s + ']'
else:
# recursively handle all dimensions
if summary and var.shape[0] > 2 * edgeitems:
vars = (
[
_format_tensor(
var[i], summary, indent + 1, max_width, signed
)
for i in range(edgeitems)
]
+ ['...']
+ [
_format_tensor(
var[i], summary, indent + 1, max_width, signed
)
for i in range(var.shape[0] - edgeitems, var.shape[0])
]
)
else:
vars = [
_format_tensor(var[i], summary, indent + 1, max_width, signed)
for i in range(var.shape[0])
]
s = (',' + '\n' * (len(var.shape) - 1) + ' ' * (indent + 1)).join(vars)
return '[' + s + ']'
def to_string(var, prefix='Tensor'):
indent = len(prefix) + 1
dtype = convert_dtype(var.dtype)
if var.dtype == paddle.bfloat16:
dtype = 'bfloat16'
_template = "{prefix}(shape={shape}, dtype={dtype}, place={place}, stop_gradient={stop_gradient},\n{indent}{data})"
tensor = var.value().get_tensor()
if not tensor._is_initialized():
return "Tensor(Not initialized)"
if var.dtype == paddle.bfloat16:
if not var.place.is_cpu_place():
paddle.device.synchronize()
var = var.astype('float32')
np_var = var.numpy(False)
if len(var.shape) == 0:
size = 0
else:
size = 1
for dim in var.shape:
size *= dim
summary = False
if size > DEFAULT_PRINT_OPTIONS.threshold:
summary = True
max_width, signed = _get_max_width(_to_summary(np_var))
data = _format_tensor(
np_var, summary, indent=indent, max_width=max_width, signed=signed
)
return _template.format(
prefix=prefix,
shape=var.shape,
dtype=dtype,
place=var._place_str,
stop_gradient=var.stop_gradient,
indent=' ' * indent,
data=data,
)
def mask_xpu_bf16_tensor(np_tensor):
# For XPU, we mask out the 0x8000 added to the tail when converting bf16 to fp32.
mask = np.array(0xFFFF0000, dtype='uint32')
return (np_tensor.view('uint32') & mask).view('float32')
def _format_dense_tensor(tensor, indent):
dtype = tensor.dtype
if dtype in {
paddle.bfloat16,
paddle.float8_e4m3fn,
paddle.float8_e5m2,
}:
if not tensor.place.is_cpu_place():
paddle.device.synchronize()
tensor = tensor.astype('float32')
# TODO(zhouwei): will remove 0-D Tensor.numpy() hack
np_tensor = tensor.numpy(False)
if (
paddle.is_compiled_with_xpu()
and os.getenv("XPU_PADDLE_MASK_BF16_PRINT") is not None
and (dtype == paddle.bfloat16 or dtype == core.VarDesc.VarType.BF16)
):
np_tensor = mask_xpu_bf16_tensor(np_tensor)
summary = (
np.prod(tensor.shape, dtype="int64") > DEFAULT_PRINT_OPTIONS.threshold
)
max_width, signed = _get_max_width(_to_summary(np_tensor))
data = _format_tensor(
np_tensor, summary, indent=indent, max_width=max_width, signed=signed
)
return data
def selected_rows_tensor_to_string(tensor, dtype, prefix='Tensor'):
indent = len(prefix) + 1
if tensor.is_selected_rows():
_template = "{prefix}(shape={shape}, dtype={dtype}, place={place}, stop_gradient={stop_gradient}, rows={rows},\n{indent}{data})"
data = _format_dense_tensor(tensor, indent)
return _template.format(
prefix=prefix,
shape=list(tensor.shape),
dtype=dtype,
place=tensor._place_str,
stop_gradient=tensor.stop_gradient,
indent=' ' * indent,
data=data,
rows=tensor.rows(),
)
def sparse_tensor_to_string(tensor, prefix='Tensor'):
indent = len(prefix) + 1
if tensor.is_sparse_coo():
_template = "{prefix}(shape={shape}, dtype={dtype}, place={place}, stop_gradient={stop_gradient}, \n{indent}{indices}, \n{indent}{values})"
indices_tensor = tensor.indices()
values_tensor = tensor.values()
indices_data = 'indices=' + _format_dense_tensor(
indices_tensor, indent + len('indices=')
)
values_data = 'values=' + _format_dense_tensor(
values_tensor, indent + len('values=')
)
return _template.format(
prefix=prefix,
shape=list(tensor.shape),
dtype=tensor.dtype,
place=tensor._place_str,
stop_gradient=tensor.stop_gradient,
indent=' ' * indent,
indices=indices_data,
values=values_data,
)
else:
_template = "{prefix}(shape={shape}, dtype={dtype}, place={place}, stop_gradient={stop_gradient}, \n{indent}{crows}, \n{indent}{cols}, \n{indent}{values})"
crows_tensor = tensor.crows()
cols_tensor = tensor.cols()
elements_tensor = tensor.values()
crows_data = 'crows=' + _format_dense_tensor(
crows_tensor, indent + len('crows=')
)
cols_data = 'cols=' + _format_dense_tensor(
cols_tensor, indent + len('cols=')
)
values_data = 'values=' + _format_dense_tensor(
elements_tensor, indent + len('values=')
)
return _template.format(
prefix=prefix,
shape=list(tensor.shape),
dtype=tensor.dtype,
place=tensor._place_str,
stop_gradient=tensor.stop_gradient,
indent=' ' * indent,
crows=crows_data,
cols=cols_data,
values=values_data,
)
def dist_tensor_to_string(tensor, prefix='Tensor'):
# TODO(dev): Complete tensor will be printed after reshard
# is ready.
indent = len(prefix) + 1
dtype = convert_dtype(tensor.dtype)
if tensor.dtype == paddle.bfloat16:
dtype = 'bfloat16'
if not tensor._is_dense_tensor_hold_allocation():
_template = "{prefix}(shape={shape}, dtype={dtype}, place={place}, stop_gradient={stop_gradient}, process_mesh={process_mesh}, placements={placements}, GlobalDenseTensor Not initialized)"
return _template.format(
prefix=prefix,
shape=list(tensor.shape),
dtype=dtype,
place=tensor._place_str,
stop_gradient=tensor.stop_gradient,
process_mesh=tensor.process_mesh,
placements=tensor._placements_str,
)
else:
indent = len(prefix) + 1
# If we print a dist_tensor with bf16 dtype and Partial placement, it is essential to ensure that the AllReduce communication
# is performed in bf16. After completing the communication, convert it to fp32, and then convert it into a numpy array.
from paddle.distributed import Replicate, reshard
placements = [Replicate() for _ in range(tensor.process_mesh.ndim)]
global_tensor = reshard(tensor, tensor.process_mesh, placements)
data = _format_dense_tensor(global_tensor, indent)
_template = "{prefix}(shape={shape}, dtype={dtype}, place={place}, stop_gradient={stop_gradient}, process_mesh={process_mesh}, placements={placements}, GlobalDenseTensor=\n{indent}{data})"
return _template.format(
prefix=prefix,
shape=list(tensor.shape),
dtype=dtype,
place=tensor._place_str,
stop_gradient=tensor.stop_gradient,
process_mesh=tensor.process_mesh,
placements=tensor._placements_str,
indent=' ' * indent,
data=data,
)
def tensor_to_string(tensor, prefix='Tensor'):
indent = len(prefix) + 1
dtype = convert_dtype(tensor.dtype)
if tensor.dtype == paddle.bfloat16:
dtype = 'bfloat16'
_template = "{prefix}(shape={shape}, dtype={dtype}, place={place}, stop_gradient={stop_gradient},\n{indent}{data})"
if tensor.is_sparse():
return sparse_tensor_to_string(tensor, prefix)
if tensor.is_selected_rows():
return selected_rows_tensor_to_string(tensor, dtype, prefix)
if tensor.is_dist():
return dist_tensor_to_string(tensor, prefix)
if not tensor._is_dense_tensor_hold_allocation():
return "Tensor(Not initialized)"
else:
data = _format_dense_tensor(tensor, indent)
return _template.format(
prefix=prefix,
shape=list(tensor.shape),
dtype=dtype,
place=tensor._place_str,
stop_gradient=tensor.stop_gradient,
indent=' ' * indent,
data=data,
)