
    ͑i                        S SK Jr  S SKJr  S SKrS SKJrJr  S SKJ	r	  S SK
Jr  \(       a  S SKJr  S SKJr  / r\R                     SSS	.         SS
 jjj5       rg)    )annotations)TYPE_CHECKINGN)core	framework)gradients_with_optimizer)check_and_create_dir)Sequence)Tensor)dump_backward_graph_pathc                        S	S jnU" U S5      n [        U 5      [        [        U 5      5      :X  d   S5       eUbS  [        U[        [        45      (       d  U/nU H.  nUc  M  [        U[
        R                  5      (       a  M)   S5       e   O/ n[        U5      S:  a  [        U 5      [        U5      :X  d   S5       e[        U[        5      (       d   S5       e[        U5        [        R                  R                  XX#5        g)
aw	  
Compute the backward gradients of given tensors.

Args:
    tensors(list of Tensors): the tensors which the gradient to be computed. The tensors can not contain the same tensor.

    grad_tensors(list of Tensors of None, optional): the init gradients of the `tensors`` .If not None, it must have the same length with ``tensors`` ,
        and if any of the elements is None, then the init gradient is the default value which is filled with 1.0.
        If None, all the gradients of the ``tensors`` is the default value which is filled with 1.0.
        Defaults to 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.
    dump_backward_graph_path(str, optional): Specifies the directory path for storing the debug file.
        If this parameter is specified, the backward-related graph (in dot format)
        and the debugging call stack information will be generated in this directory.
Returns:
    NoneType: None


Examples:
    .. code-block:: python

        >>> import paddle
        >>> x = paddle.to_tensor([[1, 2], [3, 4]], dtype='float32', stop_gradient=False)
        >>> y = paddle.to_tensor([[3, 2], [3, 4]], dtype='float32')

        >>> grad_tensor1 = paddle.to_tensor([[1,2], [2, 3]], dtype='float32')
        >>> grad_tensor2 = paddle.to_tensor([[1,1], [1, 1]], dtype='float32')

        >>> z1 = paddle.matmul(x, y)
        >>> z2 = paddle.matmul(x, y)

        >>> paddle.autograd.backward([z1, z2], [grad_tensor1, grad_tensor2], True)
        >>> print(x.grad)
        Tensor(shape=[2, 2], dtype=float32, place=Place(cpu), stop_gradient=False,
        [[12., 18.],
         [17., 25.]])


        >>> x.clear_grad()

        >>> paddle.autograd.backward([z1, z2], [grad_tensor1, None], True)
        >>> print(x.grad)
        Tensor(shape=[2, 2], dtype=float32, place=Place(cpu), stop_gradient=False,
        [[12., 18.],
         [17., 25.]])

        >>> x.clear_grad()

        >>> paddle.autograd.backward([z1, z2])
        >>> print(x.grad)
        Tensor(shape=[2, 2], dtype=float32, place=Place(cpu), stop_gradient=False,
        [[10., 14.],
         [10., 14.]])


c                F   U c
   U S35       e[        U [        [        45      (       aN  [        U 5      S:  d
   U S35       eU  H-  n[        U[        R
                  5      (       a  M$   SU S35       e   U $ [        U [        R
                  5      (       d
   U S35       eU /$ )Nz should not be Noner   z cannot be emptyzElements of z must be paddle.Tensorz! must be Tensor or list of Tensor)
isinstancelisttuplelenpaddler
   )in_out_listnameeach_vars      ]/var/www/html/banglarbhumi/venv/lib/python3.13/site-packages/paddle/autograd/backward_mode.pycheck_tensorsbackward.<locals>.check_tensorsf   s     &D4&0C(DD&kD%=11{#a'BD61A)BB''!(FMM:: "4&(>?: ( k6==99 &9:9  =     tensorsz[The argument 'tensors' of paddle.autograd.backward contains duplicate paddle.Tensor object.NzThe argument 'grad_tensors' of paddle.autograd.backward is invalid, it can be 'None', 'paddle.Tensor' or 'list[None/paddle.Tensor]'.r   z3The length of grad_tensors must be equal to tensorsz"retain_graph must be True or False)r   zSequence[Tensor] | Tensorr   strreturnzSequence[Tensor])r   setr   r   r   r   r
   boolr   r   eagerrun_backward)r   grad_tensorsretain_graphr   r   each_tensors         r   backwardr$   !   s   J!.!69!	!$ GY/Gw<3s7|,, e, ,u66(>L'K&!+v}}==  [= ( 
<17|s<00 	
A	
0 lD))O+OO)12JJ|r   )NF)
r   zTensor | Sequence[Tensor]r!   z'Tensor | Sequence[Tensor | None] | Noner"   r   r   z
str | Noner   None)
__future__r   typingr   r   paddle.baser   r   paddle.base.backwardr   paddle.utils.downloadr   collections.abcr	   r
   __all__dygraph_onlyr$    r   r   <module>r/      s    #    ' 9 6(   =Aq
 ,0q&q9q q
 )q 
q qr   