o
    "j                     @   s   d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZmZ d dl	m
Z
mZ d dlmZ d dlmZ ddlmZmZmZ ddlmZmZmZmZ d	d
lmZ d	dlmZ dZG dd dZdadd ZdS )    N)_C_opsprofiler)_PADDLE_DTYPE_2_NUMPY_DTYPEconvert_uint16_to_float)in_profiler_mode)
deprecated   )core	frameworkunique_name)EagerParamBase	ParameterVariableconvert_np_dtype_to_dtype_   )switch_to_static_graph)monkey_patch_math_tensorc                   @   s    e Zd ZdZdd Zdd ZdS )TensorHookRemoveHelperz
    A helper class that for removing Tensor gradient's hook.
    NOTE(wuweilong):the operation weakref.ref(tensor) will cause some unexpected errors in eager mode.
    c                 C   s   || _ || _d S N)_tensor_hook_id)selftensorhook_id r   i/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/paddle/base/dygraph/tensor_patch_methods.py__init__2   s   
zTensorHookRemoveHelper.__init__c                 C   sB   | j }|dur|| j}|du rdS td| j|jf t dS )zy
        Remove reference Tensor's hook.

        Returns:
            bool: Return True if removed successfully
        NTz`The backward hook (ID: %d) of Tensor `%s` you want to remove does not exist or has been removed.F)r   Z_remove_grad_hookr   warningswarnnameRuntimeWarning)r   r   resr   r   r   remove6   s   
zTensorHookRemoveHelper.removeN)__name__
__module____qualname____doc__r   r"   r   r   r   r   r   ,   s    r   Fc            &         sZ  t dwdd} tjdd }tjdxdd}tjtdd	d
ddd }tjdd }tjdydd}tjdd }tdd }dd }dd }	tdd }
dd }dd }td d! }d"d# }d$d% }	 	 dzd&d'}d(d) fd*d+}fd,d-}tjd.d/ }tjd0d1 }tjd2d3 }tjd4d5 }tjd6d7 }tjd{d9d:}tjd|d<d=}tjd>d? }tjd}d@dA}tjd{dBdC}tjdDdE }tjdFdG }tjdHdI }tjdJdK } dLdM }!tjd~dNdO}"ttdPsd S g dQ|fdR|fdS| fdT|fdU|fdV|fdW|fdX|
fdY|fdZ|fd[|fd\|fd]|fd^d_|fd`|fda|	fdb|fdc|fdd|fde|fdf|fdg|fdh|"fdi|fdj|fdk|fdl|fdm|fdn|fdo|fdp|fdq|fdr|!fds|fdt| fR D ]\}#}$ttjj	|#|$ qt
stjjj  fdudv}%|%tjj_d8a
t  d S )NFc                    sF  g d}ddg}t  tr j }|D ]	}t |||< qn(g }t D ]}||vr=tt |s=|ds=|	| q% fdd|D }g d}	|	D ]
}
t |
d||
< qMd	|v rb|d	 |d	< |
| |snt  tr|d
= |d	 j |d	< tdi |}ntdi |} jdurddlm} |j| jj j|jd}|S )a  
        **Notes**:
            **This API is ONLY available in Dygraph mode**

        Transform a Tensor into static Variable with same attributes. It's a low level interface used
        in dy2static and shall not be called directly.

        Args:
            to_parameter (bool): It takes effect only if the input a Tensor. If set True,
                                 the Tensor will be converted into framework.Parameters. Otherwise, it will
                                 be converted into framework.Variable. Default False.

        Examples:
            .. code-block:: python

                >>> import paddle.base as base
                >>> from paddle.base.dygraph.base import to_variable
                >>> import numpy as np

                >>> data = np.ones([3, 1024], dtype='float32')
                >>> with base.dygraph.guard():
                ...     tensor = to_variable(data)
                ...     static_var = tensor._to_static_var()
        )gradTplaceZ
_place_strdataZgrad_stridesoffsetstop_gradientZ	trainable_c                    s   i | ]}|t  |qS r   )getattr).0r   r   r   r   
<dictcomp>   s    z?monkey_patch_tensor.<locals>._to_static_var.<locals>.<dictcomp>)blockshapedtypetyper   persistableNr3   r7   r   )r-   r   )
isinstancer   __dict__copyr/   dirinspectismethod
startswithappendupdateprogramglobal_blockr   r   Z	dist_attrZpaddle.distributeddistributedshard_tensorprocess_mesh
placementsr-   )r   Zto_parameterkwargsZattr_not_need_keysZ
param_keysZattr_kwargskeyZ
attr_namesr   Z	attr_keysattrZ
static_vardistr   r1   r   _to_static_varO   sL   





z+monkey_patch_tensor.<locals>._to_static_varc              
   S   s  t jj}t|tj|ttfsJ d|  r"t|tj|fs"J dt|ttfrVt	| t	|ks?J d
| jt	| t	|t|trM|  | dS |  | dS | jt|jksjJ d
| j| j|jt||rs|j}nt|j}| j|ksJ d
| j| j||  rt|tjr| rddlm} |j|  jks||j|  jsJ d|j d	|  j d
|j d	|  j d	ntj||  j|  j}|   |  dS |   |t  dS )a  
        **Notes**:
            **This API is ONLY available in Dygraph mode**

        Set a new value for this Variable.

        Args:
            value (Variable|np.ndarray): the new value.

        Examples:
            .. code-block:: python

                >>> import paddle.base as base
                >>> from paddle.base.dygraph.base import to_variable
                >>> from paddle.nn import Linear
                >>> import numpy as np

                >>> data = np.ones([3, 1024], dtype='float32')
                >>> with base.dygraph.guard():
                ...     linear = Linear(1024, 4)
                ...     t = to_variable(data)
                ...     linear(t)  # call with default weight
                ...     custom_weight = np.random.randn(1024, 4).astype("float32")
                ...     linear.weight.set_value(custom_weight)  # change existing weight
                ...     out = linear(t)  # call with different weight
        z_Variable set_value function, arguments type only support Variable, numpy, Tensor, dict, string.zSFor set_value function of dist tensor, arguments type only support numpy or Tensor.zhVariable length not match, Variable [ {} ] need tensor with length {} but load set tensor with length {}zeVariable Shape not match, Variable [ {} ] need tensor with shape {} but load set tensor with shape {}zbVariable dtype not match, Variable [ {} ] need tensor with dtype {}  but load tensor with dtype {}r   )check_placements_equalzprocess_mesh:z != z or placements:z
 not matchN)r	   eagerTensorr8   npndarraydictstrZis_distlenformatr   valueZ	set_vocabZset_string_listr4   listr5   r   paddleZ/paddle.distributed.auto_parallel.placement_typerL   rE   rF   rC   rD   
get_tensorsetr
   _current_expected_place)r   rU   Zbase_tensorr5   rL   r   r   r   	set_value   sr   




,z&monkey_patch_tensor.<locals>.set_valuec                 S   s   t  r[t rtdtjj}|  |dur6t|t	j
js"J d|j| jks6J d|j|j| j| j|du r=g }n|g}trGt| } t	j
| g|| t rY|  dS dS td)ac  
        Run backward of current Graph which starts from current Tensor.

        The new gradient will accumulate on previous gradient.

        You can clear gradient by ``Tensor.clear_grad()`` .

        Args:
            grad_tensor(Tensor, optional): initial gradient values of the current Tensor. If `grad_tensor` is None,
            the initial gradient values of the current Tensor would be Tensor filled with 1.0;
            if `grad_tensor` is not None, it must have the same length as the current Tensor.
            The default value is None.

            retain_graph(bool, optional): If False, the graph used to compute grads will be freed. If you would
                like to add more ops to the built graph after calling this method( :code:`backward` ), set the parameter
                :code:`retain_graph` to True, then the grads will be retained. Thus, setting it to False is much more memory-efficient.
                Defaults to False.
        Returns:
            NoneType: None

        Examples:
            .. code-block:: python

                >>> import paddle
                >>> x = paddle.to_tensor(5., stop_gradient=False)
                >>> for i in range(5):
                ...     y = paddle.pow(x, 4.0)
                ...     y.backward()
                ...     print("{}: {}".format(i, x.grad))
                0: Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=False,
                500.)
                1: Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=False,
                1000.)
                2: Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=False,
                1500.)
                3: Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=False,
                2000.)
                4: Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=False,
                2500.)

                >>> x.clear_grad()
                >>> print("{}".format(x.grad))
                Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=False,
                0.)

                >>> grad_tensor=paddle.to_tensor(2.)
                >>> for i in range(5):
                ...     y = paddle.pow(x, 4.0)
                ...     y.backward(grad_tensor)
                ...     print("{}: {}".format(i, x.grad))
                0: Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=False,
                1000.)
                1: Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=False,
                2000.)
                2: Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=False,
                3000.)
                3: Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=False,
                4000.)
                4: Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=False,
                5000.)
        zGradient BackwardNz-The type of grad_tensor must be paddle.TensorzgTensor shape not match, Tensor of grad_tensor [ {} ] with shape {} mismatch Tensor [ {} ] with shape {}z5Variable.backward() is only available in DyGraph mode)r
   Zin_dygraph_moder   r   ZRecordEventZTracerEventTypeZBackwardbeginr8   r	   rM   rN   r4   rT   r   _grad_scalarscaleZrun_backwardend
ValueError)r   Zgrad_tensorZretain_graphZrecord_eventr   r   r   backward   s:   ?
z%monkey_patch_tensor.<locals>.backwardz2.1.0r   zGPlease use tensor.grad, which returns the tensor value of the gradient.)Zsincelevelreasonc                 S   s@   | j du rdS | j  rt| j t| j  fS t| j S )a  
        .. warning::
          This API will be deprecated in the future, it is recommended to use
          :code:`x.grad` which returns the tensor value of the gradient.

        Get the Gradient of Current Tensor.

        Returns:
            ndarray: Numpy value of the gradient of current Tensor

        Examples:
            .. code-block:: python

                >>> import paddle

                >>> x = paddle.to_tensor(5., stop_gradient=False)
                >>> y = paddle.pow(x, 4.0)
                >>> y.backward()
                >>> print("grad of x: {}".format(x.gradient()))
                grad of x: 500.0

        N)r'   Zis_selected_rowsrO   arrayrowsr1   r   r   r   gradient_  s
   

z%monkey_patch_tensor.<locals>.gradientc                 S   s*   | j du r	td| |}t| |}|S )aS	  
        Registers a backward hook for current Tensor.

        The hook will be called every time the gradient Tensor of current Tensor is computed.

        The hook should not modify the input gradient Tensor, but it can optionally return
        a new gradient Tensor which will be used in place of current Tensor's gradient.

        The hook should have the following signature:

            hook(grad) -> Tensor or None

        Args:
            hook(function): A backward hook to be registered for Tensor.grad

        Returns:
            TensorHookRemoveHelper: A helper object that can be used to remove the registered hook by calling `remove()` method.

        Examples:
            .. code-block:: python

                >>> import paddle

                >>> # hook function return None
                >>> def print_hook_fn(grad):
                ...     print(grad)
                ...
                >>> # hook function return Tensor
                >>> def double_hook_fn(grad):
                ...     grad = grad * 2
                ...     return grad
                ...
                >>> x = paddle.to_tensor([0., 1., 2., 3.], stop_gradient=False)
                >>> y = paddle.to_tensor([4., 5., 6., 7.], stop_gradient=False)
                >>> z = paddle.to_tensor([1., 2., 3., 4.])

                >>> # one Tensor can register multiple hooks
                >>> h = x.register_hook(print_hook_fn)
                >>> x.register_hook(double_hook_fn)

                >>> w = x + y
                >>> # register hook by lambda function
                >>> w.register_hook(lambda grad: grad * 2)

                >>> o = z.matmul(w)
                >>> o.backward()
                >>> # print_hook_fn print content in backward
                Tensor(shape=[4], dtype=float32, place=Place(cpu), stop_gradient=False,
                [2., 4., 6., 8.])

                >>> print("w.grad:", w.grad)
                w.grad: None
                >>> print("x.grad:", x.grad)
                x.grad: Tensor(shape=[4], dtype=float32, place=Place(cpu), stop_gradient=False,
                [4. , 8. , 12., 16.])
                >>> print("y.grad:", y.grad)
                y.grad: Tensor(shape=[4], dtype=float32, place=Place(cpu), stop_gradient=False,
                [2., 4., 6., 8.])

                >>> # remove hook
                >>> h.remove()
        Tz4Cannot register hook on a tensor that stop gradient.)r-   RuntimeErrorZ_register_grad_hookr   )r   hookr   helperr   r   r   register_hook  s   
@

z*monkey_patch_tensor.<locals>.register_hookc                 S   s   |d u r|d u r|d u r| S |d ur7t |trtj|}nt |tjtjtjtj	tj
fr.n	tdt|j |d u r>d}n	t |tsGJ ddd }t  tjdtd || |||W  d    S 1 shw   Y  d S )Nzdevice value error, must be str, paddle.CPUPlace(), paddle.CUDAPlace(), paddle.CUDAPinnedPlace(), paddle.XPUPlace() or paddle.CustomPlace(), but the type of device is Tz5blocking value error, must be the True, False or Nonec                 S   s8  |d u r| j }|d u r| j}t|tu rt|}| j  rIt|}| 	 | d d d d }t
 }||k rF| t |}|   n| }n| }|d urt||jkrttjjj|j d |j|d}W d    n1 snw   Y  n|}|d ur|j |s|||}	n|}	|   }
|	  }|
| | S )N   r   g333333?)r)   )r5   )r)   r5   r6   rR   r
   r   Zis_gpu_placer	   Zsize_of_dtype_numelgpu_memory_available_copy_torW   CPUPlace_clearbaseZ_dygraph_place_guardcast_equalsrU   rX   Z_share_data_with)tdevicer5   blockingZ
size_dtypeZwaiting_alloc_memoryrm   Zt_usedZt_castedZnew_tZ
dst_tensorZ
src_tensorr   r   r   	transform  s>   




z3monkey_patch_tensor.<locals>._to.<locals>.transformignore)category)r8   rR   rW   ru   Z_convert_to_placer	   ro   	CUDAPlaceCUDAPinnedPlaceZXPUPlaceZCustomPlacer`   r6   r#   boolr   catch_warningsfilterwarningsUserWarning)r   ru   r5   rv   rw   r   r   r   _to  s@   


3$z monkey_patch_tensor.<locals>._toc                 _   s  d}d}d}t |}t |}dd }|| dks|| dkr"tdh d}	g d}
t| |	 }t |dkrBtd	t|d  |dkrt|d tjrf||d \}}|d
kr_|d }n|dd}nzt|d tj	t
j	fst|d tr|d  |
v r|d }|d
kr|d }nS|dd}nL|d }|d
kr|d }n?|dkr|d |d
 }}n1|dd}|dd}n$|dd}|dd}|dd}|du r|du r||dd\}}| |||S )a  
        Performs Tensor dtype and/or device conversion. A paddle.dtype and place
        are inferred from the arguments of ``self.to(*args, **kwargs)``.There are
        three ways to call `to`:

            1. to(dtype, blocking=True)
            2. to(device, dtype=None, blocking=True)
            3. to(other, blocking=True)

        Returns:
            Tensor: self

        Examples:
            .. code-block:: python

                >>> import paddle
                >>> tensorx = paddle.to_tensor([1,2,3])
                >>> print(tensorx)
                Tensor(shape=[3], dtype=int64, place=Place(gpu:0), stop_gradient=True,
                    [1, 2, 3])

                >>> tensorx = tensorx.to("cpu")
                >>> print(tensorx.place)
                Place(cpu)

                >>> tensorx = tensorx.to("float32")
                >>> print(tensorx.dtype)
                paddle.float32

                >>> tensorx = tensorx.to("gpu", "int16")
                >>> print(tensorx)
                Tensor(shape=[3], dtype=int16, place=Place(gpu:0), stop_gradient=True,
                    [1, 2, 3])
                >>> tensor2 = paddle.to_tensor([4,5,6])
                >>> tensor2
                Tensor(shape=[3], dtype=int64, place=Place(gpu:0), stop_gradient=True,
                    [4, 5, 6])
                >>> tensor2 = tensor2.to(tensorx)
                >>> print(tensor2)
                Tensor(shape=[3], dtype=int16, place=Place(gpu:0), stop_gradient=True,
                    [4, 5, 6])
        Nc                 S   s,   | d urt | jdd }| j}||fS dS )N   NN)rR   r)   r5   )otherru   r5   r   r   r   get_device_dtype_from_tensorT  s
   zEmonkey_patch_tensor.<locals>.to.<locals>.get_device_dtype_from_tensor   r   a  to() received too mant arguments - expected one of:
                  * (Union[str, paddle.CPUPlace(), paddle.CUDAPlace(), paddle.CUDAPinnedPlace(), paddle.XPUPlace(), paddle.CustomPlace()]                 device, Union[str, paddle.dtype, numpy.dtype] dtype, bool blocking)
                 * (Union[str, paddle.dtype, numpy.dtype] dtype, bool blocking)
                 * (paddle.Tensor other, bool blocking) >   r   rv   ru   r5   )bfloat16Zfloat16Zfloat32Zfloat64Zint8Zint16Zint32Zint64Zuint8Z	complex64Z
complex128r|   z(to() got an unexpected keyword argument r   r   rv   r5   ru   r   )rS   	TypeErrorrY   keysrV   r8   rW   rN   getr5   rO   rR   lowerr   )r   argsrG   ru   r5   rv   Z	size_argsZsize_kwargsr   Z
valid_keysZvalid_dtypesZinvalid_keysr   r   r   to"  sb   ,




zmonkey_patch_tensor.<locals>.toc                 S   s4   d}d| }t j dkrd| }t| |  S )a  
        .. warning::
          This API will return the tensor value of the gradient. If you want
          to get the numpy value of the gradient, you can use :code:`x.grad.numpy()`.

        Get the Gradient of Current Tensor.

        Returns:
            Tensor: the gradient of current Tensor

        Examples:
            .. code-block:: python

                >>> import paddle

                >>> x = paddle.to_tensor(5., stop_gradient=False)
                >>> y = paddle.pow(x, 4.0)
                >>> y.backward()
                >>> print("grad of x: {}".format(x.grad))
                grad of x: Tensor(shape=[], dtype=float32, place=CUDAPlace(0), stop_gradient=False, 500.)

        a%  tensor.grad will return the tensor value of the gradient. This is an incompatible upgrade for tensor.grad API.  It's return type changes from numpy.ndarray in version 2.0 to paddle.Tensor in version 2.1.0.  If you want to get the numpy value of the gradient, you can use :code:`x.grad.numpy()`z[93m
Warning:
%s [0mwin32z
Warning:
%s )sysplatformr   r   r   Z
_grad_ivar)r   msgZwarning_msgr   r   r   r'     s   
z!monkey_patch_tensor.<locals>.gradc                 S   s   |    dS )z0
        The alias of clear_gradient().
        N)Zclear_gradientr1   r   r   r   
clear_grad  s   z'monkey_patch_tensor.<locals>.clear_gradc                 W   s*   | j | }|jtjkrt| S | S )ac  
        Convert element at specific position in Tensor into Python scalars. If the position is not specified, the Tensor must be a
        single-element Tensor.

        Args:
            *args(int): The input coordinates. If it's single int, the data in the corresponding order of flattened Tensor will be returned.
                Default: None, and it must be in the case where Tensor has only one element.

        Returns(Python scalar): A Python scalar, whose dtype is corresponds to the dtype of Tensor.

        Raises:
            ValueError: If the Tensor has more than one element, there must be coordinates.

        Examples:
            .. code-block:: python

                >>> import paddle

                >>> x = paddle.to_tensor(1)
                >>> print(x.item())
                1
                >>> print(type(x.item()))
                <class 'int'>

                >>> x = paddle.to_tensor(1.0)
                >>> print(x.item())
                1.0
                >>> print(type(x.item()))
                <class 'float'>

                >>> x = paddle.to_tensor(True)
                >>> print(x.item())
                True
                >>> print(type(x.item()))
                <class 'bool'>

                >>> x = paddle.to_tensor(1+1j)
                >>> print(x.item())
                (1+1j)
                >>> print(type(x.item()))
                <class 'complex'>

                >>> x = paddle.to_tensor([[1.1, 2.2, 3.3]])
                >>> print(x.item(2))
                3.299999952316284
                >>> print(x.item(0, 2))
                3.299999952316284

        )Z_getitem_from_offsetr5   rO   uint16r   item)r   r   Zscalarr   r   r   r     s   
2z!monkey_patch_tensor.<locals>.itemc                 S      |   S )a  
        The inplace version of current Tensor.
        The version number is incremented whenever the current Tensor is modified through an inplace operation.

        **Notes: This is a read-only property**

        Examples:
            .. code-block:: python

                >>> import paddle
                >>> var = paddle.ones(shape=[4, 2, 3], dtype="float32")
                >>> print(var.inplace_version)
                0

                >>> var[1] = 2.2
                >>> print(var.inplace_version)
                1

        )Z_inplace_versionr1   r   r   r   inplace_version  s   z,monkey_patch_tensor.<locals>.inplace_versionc                 S   s   ddl m} || S )a*  
        Convert a Tensor object to a readable string.

        Returns(str): A readable string.

        Examples:
            .. code-block:: python

                >>> import paddle
                >>> paddle.seed(2023)
                >>> x = paddle.rand([2, 5])
                >>> print(x)
                Tensor(shape=[2, 5], dtype=float32, place=Place(cpu), stop_gradient=True,
                [[0.86583614, 0.52014720, 0.25960937, 0.90525323, 0.42400089],
                 [0.40641287, 0.97020894, 0.74437362, 0.51785129, 0.73292869]])
        r   )tensor_to_string)Zpaddle.tensor.to_stringr   )r   r   r   r   r   __str__  s   z$monkey_patch_tensor.<locals>.__str__c                 S   s8   t j }| jtd |_||t| < || d |S )a%  
        Deep copy Tensor, it will always performs Tensor copy.

        Examples:
            .. code-block:: python

                >>> import paddle
                >>> import copy
                >>> x = paddle.to_tensor(2.)
                >>> y = copy.deepcopy(x)
                >>> print(x)
                Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
                2.)
                >>> print(y)
                Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
                2.)
        Z	_deepcopyT)r	   rM   rN   r   r   generateidZcopy_)r   memoZ
new_tensorr   r   r   __deepcopy__+  s
   
z)monkey_patch_tensor.<locals>.__deepcopy__c                 S   s   t   S r   )r
   Zdefault_main_programrB   r1   r   r   r   r3   C     z"monkey_patch_tensor.<locals>.blockc                 S   sB   t t| j}|dksJ d|  sJ dtt| dkS )Nr   z[When Variable is used as the condition of if/while , Variable can only contain one element.ztensor not initializedr   )intrO   prodr4   Z_is_initializedr|   rd   )r   Znumelr   r   r   __nonzero__G  s   
z(monkey_patch_tensor.<locals>.__nonzero__c                 S   r   r   )r   r1   r   r   r   __bool__P  s   z%monkey_patch_tensor.<locals>.__bool__c                 S   s   |  d}|r||}|S )aI  
        Returns a numpy array shows the value of current Tensor.

        Returns:
            ndarray: The numpy value of current Tensor.

        Returns type:
            ndarray: dtype is same as current Tensor

        Examples:
            .. code-block:: python

                >>> import paddle
                >>> import numpy as np
                >>> x = paddle.randn([2, 2])
                >>> x_array = np.array(x)

                >>> print(type(x_array))
                <class 'numpy.ndarray'>
                >>> print(x_array.shape)
                (2, 2)
        F)numpyZastype)r   r5   r:   rd   r   r   r   	__array__S  s   

z&monkey_patch_tensor.<locals>.__array__c                 S   sp   t |tr	t|n|g}t|D ]#\}}t |ttjtfr%t|||< qt |tr3tt|||< qt|S r   )	r8   tuplerV   	enumeraterO   rP   rW   Z	to_tensorrange)r   r   iZ
slice_itemr   r   r   pre_deal_indexs  s   
z+monkey_patch_tensor.<locals>.pre_deal_indexc                    s    | |}|  |S r   )Z_getitem_dygraph)r   r   r   r   r   __getitem__  s   

z(monkey_patch_tensor.<locals>.__getitem__c                    s    | |}|  ||S r   )Z_setitem_dygraph)r   r   rU   r   r   r   __setitem__  s   
z(monkey_patch_tensor.<locals>.__setitem__c                 S   s$   t | tr|| _|   d S td)Nz5_set_grad_ivar is only supported for Parameter Tensor)r8   r   r'   Z_unset_fake_emptyr   )r   rU   r   r   r   _set_grad_ivar  s   
z+monkey_patch_tensor.<locals>._set_grad_ivarc                 S   s   | S r   r   r1   r   r   r   rU     s   z"monkey_patch_tensor.<locals>.valuec                 S   s   t j|  ||S r   )r	   rM   rN   rX   _slice)r   Z	begin_idxZend_idxr   r   r   r     s   z#monkey_patch_tensor.<locals>._slicec                 S   s   |    S r   )rX   rl   r1   r   r   r   rl     r   z#monkey_patch_tensor.<locals>._numelc                 S   s   |     d S r   )rX   rp   r1   r   r   r   _clear_data  s   z(monkey_patch_tensor.<locals>._clear_dataTc                 S   s
   |  |S r   )Z_tensor_use_gpudnn)r   Z
use_gpudnnr   r   r   _use_gpudnn  s   
z(monkey_patch_tensor.<locals>._use_gpudnnr   c                 S   s   |  | dS )a  
        Returns self tensor with the UVA(unified virtual addressing).

        Args:
            device_id(int, optional): The destination GPU device id. Default: None, means current device.

        Examples:
            .. code-block:: python

                >>> # doctest: +REQUIRES(env:GPU)
                >>> import paddle
                >>> paddle.device.set_device('gpu')
                >>> x = paddle.to_tensor([1, 2, 3], place=paddle.CPUPlace())
                >>> x._uva()
                >>> print(x)
        N)Z_tensor_uva)r   	device_idr   r   r   _uva  s   z!monkey_patch_tensor.<locals>._uvac                 S   s2   | j  r| S | t d}| j|_| j|_|S NT)r)   Zis_cpu_placern   r	   ro   r-   r7   )r   r!   r   r   r   cpu     
z monkey_patch_tensor.<locals>.cpuc                 S   sv   |d u rt  }t|tjstd}nt|trt|}ntd| j|r+| S | 	||}| j
|_
| j|_|S )Nr   zdevice_id must be int|None)r
   rZ   r8   r	   rz   r   r`   r)   rs   rn   r-   r7   )r   r   rv   Z	res_placer!   r   r   r   cuda  s   

z!monkey_patch_tensor.<locals>.cudac                 S   s2   | j  r| S | t |}| j|_| j|_|S r   )r)   Zis_cuda_pinned_placern   r	   r{   r-   r7   )r   rv   r!   r   r   r   
pin_memory  r   z'monkey_patch_tensor.<locals>.pin_memoryc                 S   
   t | S )a	  
        **Notes**:
            **This API is ONLY available in Dygraph mode**

        Get the values of current SparseTensor(COO or CSR).

        Returns:
            Tensor: A DenseTensor

        Examples:
            .. code-block:: python

                >>> import paddle
                >>> indices = [[0, 0, 1, 2, 2], [1, 3, 2, 0, 1]]
                >>> values = [1, 2, 3, 4, 5]
                >>> dense_shape = [3, 4]
                >>> sparse_x = paddle.sparse.sparse_coo_tensor(paddle.to_tensor(indices, dtype='int32'), paddle.to_tensor(values, dtype='float32'), shape=dense_shape)
                >>> print(sparse_x.values())
                Tensor(shape=[5], dtype=float32, place=Place(cpu), stop_gradient=True,
                [1., 2., 3., 4., 5.])
        )r   Zsparse_valuesr1   r   r   r   values  s   
z#monkey_patch_tensor.<locals>.valuesc                 S   r   )a  
        **Notes**:
            **This API is ONLY available in Dygraph mode**

        Convert the current SparseTensor(COO or CSR) to DenseTensor.

        Returns:
            Tensor: A DenseTensor

        Examples:
            .. code-block:: python

                >>> import paddle
                >>> indices = [[0, 0, 1, 2, 2], [1, 3, 2, 0, 1]]
                >>> values = [1, 2, 3, 4, 5]
                >>> dense_shape = [3, 4]
                >>> sparse_x = paddle.sparse.sparse_coo_tensor(paddle.to_tensor(indices, dtype='int64'), paddle.to_tensor(values, dtype='float32'), shape=dense_shape)
                >>> dense_x = sparse_x.to_dense()
                >>> print(dense_x)
                Tensor(shape=[3, 4], dtype=float32, place=Place(cpu), stop_gradient=True,
                [[0., 1., 0., 2.],
                 [0., 0., 3., 0.],
                 [4., 5., 0., 0.]])
        )r   Zsparse_to_denser1   r   r   r   to_dense  s   
z%monkey_patch_tensor.<locals>.to_densec                 S   s   t | |S )a	  
        **Notes**:
            **This API is ONLY available in Dygraph mode**

        Convert the current DenseTensor to SparseTensor in COO format.

        Returns:
            Tensor: A SparseCooTensor

        Examples:
            .. code-block:: python

                >>> import paddle
                >>> dense_x = [[0, 1, 0, 2], [0, 0, 3, 4]]
                >>> dense_x = paddle.to_tensor(dense_x, dtype='float32')
                >>> sparse_x = dense_x.to_sparse_coo(sparse_dim=2)
                >>> print(sparse_x)
                Tensor(shape=[2, 4], dtype=paddle.float32, place=Place(cpu), stop_gradient=True,
                       indices=[[0, 0, 1, 1],
                                [1, 3, 2, 3]],
                       values=[1., 2., 3., 4.])
        )r   Zsparse_to_sparse_coo)r   Z
sparse_dimr   r   r   to_sparse_coo  s   z*monkey_patch_tensor.<locals>.to_sparse_cooc                 S   s    t | }| }t| S )a  
        **Notes**:
            **This API is ONLY available in Dygraph mode**

        Calculate the md5sum of current Tensor.

        Returns:
            str: The md5sum of current Tensor.

        Examples:

            .. code-block:: python

                >>> import paddle
                >>> x = paddle.to_tensor([1, 2, 3])
                >>> print(x._md5sum())
                >>> #'1f68049372c5b2a4e0d049044450
        )rO   rd   tobyteshashlibmd5	hexdigest)r   Znumpy_arrayZarray_bytesr   r   r   _md5sum1  s   
z$monkey_patch_tensor.<locals>._md5sumc                 S   s   t t| S r   )hashr   r1   r   r   r   __hash__I  s   z%monkey_patch_tensor.<locals>.__hash__c                 S   r   )a8  
        the coalesced operator include sorted and merge, after coalesced, the indices of x is sorted and unique.

        Parameters:
            x (Tensor): the input SparseCooTensor.
            name (str, optional): Name for the operation (optional, default is None).
                For more information, please refer to :ref:`api_guide_Name`.

        Returns:
            Tensor: return the SparseCooTensor after coalesced.

        Examples:
            .. code-block:: python

                >>> import paddle

                >>> indices = [[0, 0, 1], [1, 1, 2]]
                >>> values = [1.0, 2.0, 3.0]
                >>> sp_x = paddle.sparse.sparse_coo_tensor(indices, values)
                >>> sp_x = sp_x.coalesce()
                >>> print(sp_x.indices())
                Tensor(shape=[2, 2], dtype=int64, place=Place(cpu), stop_gradient=True,
                [[0, 1],
                [1, 2]])
                >>> print(sp_x.values())
                Tensor(shape=[2], dtype=float32, place=Place(cpu), stop_gradient=True,
                [3., 3.])
        )r   Zsparse_coalesce)r   r   r   r   r   coalesceL  s   
z%monkey_patch_tensor.<locals>.coalescerM   r   r   rK   r[   r3   ra   r   r   rf   rj   r   __repr__r   )r$   rW   r   r   r   r   r   r   r   r   r   r   r   rU   r   r   r   r   rl   r   r   r   r   r   c                    s0   | t v rt |  }|dkrd}d}|| S  | S )Nr   r   zpaddle.)r   )r5   Znumpy_dtypeprefix)originr   r   	dtype_str  s   z&monkey_patch_tensor.<locals>.dtype_str)F)NF)NNNr   )T)r   r   r   )r   r
   Zdygraph_onlyr   propertyhasattrr	   setattrrM   rN   _already_patch_reprZVarDescZVarTyper   r   )&rK   r[   ra   rf   rj   r   r   r'   r   r   r   r   r   r3   r   r   r   r   r   r   rU   r   rl   r   r   r   r   r   r   r   r   r   r   r   r   method_namemethodr   r   )r   r   r   monkey_patch_tensorN   s,  S
Z`
HV
z
$7

	
 
	




		




	
 !"#$&


r   ) r   r<   r   r   r   rO   rW   r   r   Zpaddle.base.data_feederr   r   Zpaddle.profiler.utilsr   Zpaddle.utilsr    r	   r
   r   r   r   r   r   rq   r   Zmath_op_patchr   r]   r   r   r   r   r   r   r   <module>   s$   