-
Notifications
You must be signed in to change notification settings - Fork 5.9k
[API compatibility] add new API paddle.tensor and save paddle.tensor module #74540
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 all commits
ec05c8e
2a46d38
718ef0a
97d3365
3efaab1
ab25099
903e758
2c5405c
f53fbf4
16f7ef0
df58a7d
97f78c1
8e8c1e6
98fab20
78f13af
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 |
|---|---|---|
|
|
@@ -641,6 +641,34 @@ | |
| to_dlpack, | ||
| ) | ||
|
|
||
|
|
||
| class _TensorMethodOrModule: | ||
| def __init__(self): | ||
| import paddle.tensor as tensor_module | ||
|
|
||
| from .tensor.creation import tensor as tensor_api | ||
|
|
||
| self.module = tensor_module | ||
| self.method = tensor_api | ||
|
|
||
| def __call__(self, *args, **kwargs): | ||
| return self.method(*args, **kwargs) | ||
|
|
||
| def __getattr__(self, name): | ||
| return getattr(self.module, name) | ||
|
|
||
| def __repr__(self): | ||
| return repr(self.method) | ||
|
|
||
| def __str__(self): | ||
| return str(self.method) | ||
|
|
||
| def __dir__(self): | ||
| return dir(self.module) | ||
|
|
||
|
|
||
| tensor = _TensorMethodOrModule() # noqa: F811 | ||
|
|
||
| # CINN has to set a flag to include a lib | ||
|
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. new_tensor_api -> tensor_api
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. Done |
||
| if is_compiled_with_cinn(): | ||
| import os | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -63,7 +63,7 @@ | |
|
|
||
| __all__ = [] | ||
|
|
||
| _warned_in_to_tensor = False | ||
| _warned_in_tensor = False | ||
|
|
||
|
|
||
| def _complex_to_real_dtype(dtype: DTypeLike) -> DTypeLike: | ||
|
|
@@ -877,7 +877,129 @@ def _to_tensor_static( | |
| return output | ||
|
|
||
|
|
||
| @ParamAliasDecorator({"place": ["device"]}) | ||
| def tensor( | ||
| data: TensorLike | NestedNumericSequence, | ||
| dtype: DTypeLike | None = None, | ||
| device: PlaceLike | None = None, | ||
| requires_grad: bool = False, | ||
| pin_memory: bool = False, | ||
| ) -> paddle.Tensor: | ||
| r""" | ||
| Constructs a ``paddle.Tensor`` from ``data`` , | ||
| which can be scalar, tuple, list, numpy\.ndarray, paddle\.Tensor. | ||
|
|
||
| If the ``data`` is already a Tensor, copy will be performed and return a new tensor. | ||
| If you only want to change stop_gradient property, please call ``Tensor.stop_gradient = stop_gradient`` directly. | ||
|
|
||
| .. code-block:: text | ||
|
|
||
| We use the dtype conversion rules following this: | ||
| Keep dtype | ||
| np.number ───────────► paddle.Tensor | ||
| (0-D Tensor) | ||
| default_dtype | ||
| Python Number ───────────────► paddle.Tensor | ||
| (0-D Tensor) | ||
| Keep dtype | ||
| np.ndarray ───────────► paddle.Tensor | ||
|
|
||
| Args: | ||
| data(scalar|tuple|list|ndarray|Tensor): Initial data for the tensor. | ||
| Can be a scalar, list, tuple, numpy\.ndarray, paddle\.Tensor. | ||
| dtype(str|np.dtype, optional): The desired data type of returned tensor. Can be 'bool' , 'float16' , | ||
| 'float32' , 'float64' , 'int8' , 'int16' , 'int32' , 'int64' , 'uint8', | ||
| 'complex64' , 'complex128'. Default: None, infers dtype from ``data`` | ||
| except for python float number which gets dtype from ``get_default_type`` . | ||
| device(CPUPlace|CUDAPinnedPlace|CUDAPlace|str, optional): The place to allocate Tensor. Can be | ||
| CPUPlace, CUDAPinnedPlace, CUDAPlace. Default: None, means global place. If ``device`` is | ||
| string, It can be ``cpu``, ``gpu:x`` and ``gpu_pinned``, where ``x`` is the index of the GPUs. | ||
| requires_grad(bool, optional): Whether to block the gradient propagation of Autograd. Default: False. | ||
| pin_memory(bool, optional): If set, return tensor would be allocated in the pinned memory. Works only for CPU tensors. Default: False | ||
|
|
||
| Returns: | ||
| Tensor: A Tensor constructed from ``data`` . | ||
|
|
||
| Examples: | ||
| .. code-block:: python | ||
|
|
||
| >>> import paddle | ||
|
|
||
| >>> type(paddle.tensor(1)) | ||
| <class 'paddle.Tensor'> | ||
|
|
||
| >>> paddle.tensor(1) | ||
| Tensor(shape=[], dtype=int64, place=Place(cpu), stop_gradient=True, | ||
| 1) | ||
|
|
||
| >>> x = paddle.tensor(1, requires_grad=True) | ||
| >>> print(x) | ||
| Tensor(shape=[], dtype=int64, place=Place(cpu), stop_gradient=False, | ||
| 1) | ||
|
|
||
| >>> paddle.tensor(x) # A new tensor will be created with default stop_gradient=True | ||
| Tensor(shape=[], dtype=int64, place=Place(cpu), stop_gradient=True, | ||
| 1) | ||
|
|
||
| >>> paddle.tensor([[0.1, 0.2], [0.3, 0.4]], device=paddle.CPUPlace(), requires_grad=True) | ||
| Tensor(shape=[2, 2], dtype=float32, place=Place(cpu), stop_gradient=False, | ||
| [[0.10000000, 0.20000000], | ||
| [0.30000001, 0.40000001]]) | ||
|
|
||
| >>> type(paddle.tensor([[1+1j, 2], [3+2j, 4]], dtype='complex64')) | ||
| <class 'paddle.Tensor'> | ||
|
|
||
| >>> paddle.tensor([[1+1j, 2], [3+2j, 4]], dtype='complex64') | ||
| Tensor(shape=[2, 2], dtype=complex64, place=Place(cpu), stop_gradient=True, | ||
| [[(1+1j), (2+0j)], | ||
| [(3+2j), (4+0j)]]) | ||
| """ | ||
| if isinstance(device, str) and "cuda" in device: | ||
| device = device.replace("cuda", "gpu") | ||
| stop_gradient = not requires_grad | ||
| place = _get_paddle_place(device) | ||
| if place is None: | ||
| place = _current_expected_place_() | ||
| if pin_memory and not isinstance( | ||
|
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. 这里是not_instance,下面是isinstance?
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. 这里not isinstance是想确定place是不是已经是PinnedPlace了,是的话就没必要继续判断了,下面的isinstance是确定当前的Place是GPU或XPU。 好的我补充一下单测 |
||
| place, (core.CUDAPinnedPlace, core.XPUPinnedPlace) | ||
| ): | ||
| if isinstance(place, core.CUDAPlace): | ||
| place = core.CUDAPinnedPlace() | ||
| elif isinstance(place, core.XPUPlace): | ||
| place = core.XPUPinnedPlace() | ||
| else: | ||
| raise RuntimeError(f"Pinning memory is not supported for {place}.") | ||
|
|
||
| if in_dynamic_mode(): | ||
| is_tensor = paddle.is_tensor(data) | ||
| if not is_tensor and hasattr(data, "__cuda_array_interface__"): | ||
| if not core.is_compiled_with_cuda(): | ||
| raise RuntimeError( | ||
| "PaddlePaddle is not compiled with CUDA, but trying to create a Tensor from a CUDA array." | ||
| ) | ||
| tensor = core.tensor_from_cuda_array_interface(data) | ||
| if pin_memory: | ||
| tensor = tensor.pin_memory() | ||
| else: | ||
| if is_tensor: | ||
| global _warned_in_tensor | ||
| if not _warned_in_tensor: | ||
| warnings.warn( | ||
| "To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach(), " | ||
| "rather than paddle.to_tensor(sourceTensor).", | ||
| stacklevel=2, | ||
| ) | ||
| _warned_in_tensor = True | ||
| tensor = _to_tensor_non_static(data, dtype, place, stop_gradient) | ||
| return tensor | ||
| # call assign for static graph | ||
| else: | ||
| re_exp = re.compile(r'[(](.+?)[)]', re.DOTALL) | ||
| place_str = re.findall(re_exp, str(place))[0] | ||
| with paddle.static.device_guard(place_str): | ||
| tensor = _to_tensor_static(data, dtype, stop_gradient) | ||
| return tensor | ||
|
|
||
|
|
||
| def to_tensor( | ||
| data: TensorLike | NestedNumericSequence, | ||
| dtype: DTypeLike | None = None, | ||
|
|
@@ -957,34 +1079,9 @@ def to_tensor( | |
| [[(1+1j), (2+0j)], | ||
| [(3+2j), (4+0j)]]) | ||
| """ | ||
| place = _get_paddle_place(place) | ||
| if place is None: | ||
| place = _current_expected_place_() | ||
| if in_dynamic_mode(): | ||
| is_tensor = paddle.is_tensor(data) | ||
| if not is_tensor and hasattr(data, "__cuda_array_interface__"): | ||
| if not core.is_compiled_with_cuda(): | ||
| raise RuntimeError( | ||
| "PaddlePaddle is not compiled with CUDA, but trying to create a Tensor from a CUDA array." | ||
| ) | ||
| return core.tensor_from_cuda_array_interface(data) | ||
| if is_tensor: | ||
| global _warned_in_to_tensor | ||
| if not _warned_in_to_tensor: | ||
| warnings.warn( | ||
| "To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach(), " | ||
| "rather than paddle.to_tensor(sourceTensor).", | ||
| stacklevel=2, | ||
| ) | ||
| _warned_in_to_tensor = True | ||
| return _to_tensor_non_static(data, dtype, place, stop_gradient) | ||
|
|
||
| # call assign for static graph | ||
| else: | ||
| re_exp = re.compile(r'[(](.+?)[)]', re.DOTALL) | ||
| place_str = re.findall(re_exp, str(place))[0] | ||
| with paddle.static.device_guard(place_str): | ||
| return _to_tensor_static(data, dtype, stop_gradient) | ||
| return tensor( | ||
| data, dtype=dtype, device=place, requires_grad=not stop_gradient | ||
| ) | ||
|
|
||
|
|
||
| class MmapStorage(paddle.base.core.MmapStorage): | ||
|
|
||
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.
_TensorMethodOrModule 这个class的其他一些方法也需要实现下,结合python原生方法,使体验上更好。比如type、print、repr应该看起来是一个方法,而dir() 看起来是模块
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.
Done