-
Notifications
You must be signed in to change notification settings - Fork 6k
[API Compatibility] Fix Tensor.type #79641
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 29 commits
91b9144
3451263
d5154f3
4865ecc
8aa81ef
7f2684a
7eda286
ec4686b
cf76ec4
f668adb
111a665
b3bb47c
2f3cc36
ec1295c
f514e71
a721161
c64978f
826269a
a119dbe
5a5b7b3
219307c
fde90cf
b0217d4
82f8ebf
ce136ec
3eeb401
43c95f1
8c035b1
0488bce
2921bbb
6132cef
c995fa1
9c9fe9b
61b6e77
25748d7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -40,6 +40,7 @@ | |
| from collections.abc import Sequence | ||
|
|
||
| from paddle import Tensor | ||
| from paddle._typing import DTypeLike | ||
|
|
||
| __all__ = [ | ||
| 'allclose', | ||
|
|
@@ -56,6 +57,26 @@ | |
| ] | ||
|
|
||
|
|
||
| _TENSOR_TYPE_DTYPES = { | ||
| 'HalfTensor': 'float16', | ||
| 'FloatTensor': 'float32', | ||
| 'DoubleTensor': 'float64', | ||
| 'Float8_e4m3fnTensor': 'float8_e4m3fn', | ||
| 'Float8_e5m2Tensor': 'float8_e5m2', | ||
| 'BFloat16Tensor': 'bfloat16', | ||
| 'ByteTensor': 'uint8', | ||
| 'CharTensor': 'int8', | ||
| 'ShortTensor': 'int16', | ||
| 'IntTensor': 'int32', | ||
| 'LongTensor': 'int64', | ||
| 'BoolTensor': 'bool', | ||
| 'ComplexFloatTensor': 'complex64', | ||
| 'ComplexDoubleTensor': 'complex128', | ||
| } | ||
|
|
||
| _DTYPE_TENSOR_TYPES = {v: k for k, v in _TENSOR_TYPE_DTYPES.items()} | ||
|
|
||
|
|
||
| def __getattr__(name): | ||
| if name == "paddle_triton": | ||
| return paddle_triton_fun() | ||
|
|
@@ -66,6 +87,122 @@ def __getattr__(name): | |
| raise AttributeError(f"module {__name__!r} has no attribute {name!r}") | ||
|
|
||
|
|
||
| def _tensor_numel(input: Tensor) -> int: | ||
| """ | ||
| Returns the total number of elements in the tensor. | ||
|
|
||
| Args: | ||
| input (Tensor): The input tensor. | ||
|
|
||
| Returns: | ||
| int: The number of elements in ``input``. | ||
| """ | ||
| return int(input.size) | ||
|
|
||
|
|
||
| def _tensor_type_name(input: Tensor) -> str: | ||
| """The tensor type name of ``input``, e.g. ``'torch.cuda.sparse.FloatTensor'``, | ||
| following ``torch.Tensor.type``. Dtypes without a tensor type name fall back | ||
| to the dtype string.""" | ||
| dtype_name = str(input.dtype).removeprefix("paddle.") | ||
| tensor_type = _DTYPE_TENSOR_TYPES.get(dtype_name) | ||
| if tensor_type is None: | ||
| return str(input.dtype) | ||
| segments = ["torch"] | ||
| if input.place.is_gpu_place(): | ||
| segments.append("cuda") | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @risemeup1111 现在的改动可以吗
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. XPU/custom 的解析已补齐,但当前修改仍不完整:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @risemeup1111 我觉得像
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这里的
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @risemeup1111 现在可以没 审查一下 |
||
| if input.is_sparse_coo(): | ||
| segments.append("sparse") | ||
| segments.append(tensor_type) | ||
| return ".".join(segments) | ||
|
|
||
|
|
||
| def _tensor_type( | ||
| input: Tensor, | ||
| dtype: DTypeLike | str | type | None = None, | ||
| non_blocking: bool = False, | ||
| **kwargs: Any, | ||
| ) -> str | Tensor: | ||
| """ | ||
| Returns the tensor type when ``dtype`` is not specified, otherwise casts | ||
| the tensor to the requested type. | ||
|
|
||
| Args: | ||
| input (Tensor): The input tensor. | ||
| dtype (DTypeLike|str|type|None, optional): The target tensor type or | ||
| data type. Qualified ``torch.*`` and ``paddle.*`` dtype or tensor | ||
| type strings are supported. When it is ``None``, returns the tensor | ||
| type name. Default: ``None``. | ||
| non_blocking (bool, optional): Whether the conversion may occur | ||
| asynchronously. Default: ``False``. | ||
|
|
||
| Returns: | ||
| str|Tensor: The tensor type name when ``dtype`` is ``None``, e.g. | ||
| ``'torch.FloatTensor'``, ``'torch.cuda.FloatTensor'`` or | ||
| ``'torch.cuda.sparse.FloatTensor'``, encoding the dtype, the place | ||
| and the sparse COO layout as ``torch.Tensor.type`` does; otherwise, | ||
| a tensor with the requested type. | ||
| """ | ||
| if "async" in kwargs: | ||
| non_blocking = kwargs.pop("async") | ||
| if kwargs: | ||
| key = next(iter(kwargs)) | ||
| raise TypeError(f"type() got an unexpected keyword argument {key!r}") | ||
|
|
||
| if dtype is None: | ||
| return _tensor_type_name(input) | ||
|
|
||
| device = None | ||
| if getattr(dtype, "__name__", None) in _TENSOR_TYPE_DTYPES: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 当前 head 已改为带设备标记的独立 CUDA factory,并加入 CUDA 构造覆盖测试,原问题已修复。 |
||
| # tensor factory classes, e.g. paddle.DoubleTensor | ||
| dtype = getattr(paddle, _TENSOR_TYPE_DTYPES[dtype.__name__]) | ||
| device = "cpu" | ||
| elif isinstance(dtype, str): | ||
| dtype_string = dtype | ||
| tensor_type = dtype_string.rsplit(".", 1)[-1] | ||
| if not dtype_string.startswith(("torch.", "paddle.")): | ||
| raise ValueError(f"invalid type: {dtype_string!r}") | ||
| if tensor_type in _TENSOR_TYPE_DTYPES: | ||
| dtype = getattr(paddle, _TENSOR_TYPE_DTYPES[tensor_type]) | ||
| device = ( | ||
| "gpu" | ||
| if dtype_string.startswith(("torch.cuda.", "paddle.cuda.")) | ||
| else "cpu" | ||
| ) | ||
| elif tensor_type in _TENSOR_TYPE_DTYPES.values(): | ||
| dtype = getattr(paddle, tensor_type) | ||
| else: | ||
| raise ValueError(f"invalid type: {dtype_string!r}") | ||
|
|
||
| same_device = ( | ||
| device is None | ||
| or (device == "cpu" and input.place.is_cpu_place()) | ||
| or (device == "gpu" and input.place.is_gpu_place()) | ||
| ) | ||
| if input.dtype == dtype and same_device: | ||
| return input | ||
|
|
||
| return input.to( | ||
| device=device, | ||
| dtype=dtype, | ||
| blocking=not non_blocking, | ||
| ) | ||
|
|
||
|
|
||
| @property | ||
| def _tensor_is_sparse(input: Tensor) -> bool: | ||
| """ | ||
| Whether the tensor uses the sparse COO layout. | ||
|
|
||
| Args: | ||
| input (Tensor): The input tensor. | ||
|
|
||
| Returns: | ||
| bool: ``True`` for a sparse COO tensor, otherwise ``False``. | ||
| """ | ||
| return input.is_sparse_coo() | ||
|
|
||
|
|
||
| def allclose( | ||
| input: Tensor, | ||
| other: Tensor, | ||
|
|
@@ -1132,3 +1269,21 @@ def GetShapeOnDimInRange(shape, dim: int) -> int: | |
| split_size_or_sections | ||
| ) | ||
| return tuple(_C_ops.split(tensor, split_size_or_sections, dim)) | ||
|
|
||
|
|
||
| # ``paddle.Tensor`` APIs routed to their ``paddle.compat`` implementations | ||
| _TENSOR_API_OVERRIDES = { | ||
| 'allclose': allclose, | ||
| 'equal': equal, | ||
| 'slogdet': slogdet, | ||
| 'sort': sort, | ||
| 'split': split, | ||
| 'min': min, | ||
| 'max': max, | ||
| 'unique': unique, | ||
| 'median': median, | ||
| 'nanmedian': nanmedian, | ||
| 'numel': _tensor_numel, | ||
| 'type': _tensor_type, | ||
| 'is_sparse': _tensor_is_sparse, | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
torch.FloatTensor等无设备前缀名称,把设备元数据误报成 CPU。既然该实现承诺像torch.Tensor.type()一样编码 place,请按实际 place 处理 XPU/私有后端(或对无法可靠映射的设备显式回退),并补充相应设备类型测试。There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
当前 head 已补齐 GPU、XPU 和 custom place 的类型名分支,并加入对应覆盖测试,原问题已修复。