chore: import upstream snapshot with attribution
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
@@ -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
|
||||
@@ -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
Executable
+878
@@ -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
@@ -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
Executable
+1551
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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}
|
||||
@@ -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.
|
||||
@@ -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,
|
||||
)
|
||||
Reference in New Issue
Block a user