
    Αiw                    X   S SK Jr  S SKrS SKrS SKrS SKrS SKJrJrJ	r	J
r
Jr  S SKJr  S SKrS SKJrJr  S SKJq  S SKJr  S SKJr  S S	KJr  S
SKJr  S
SKJrJrJr  SSKJ r   \(       a,  S SK!J"r"  S SK#J$r$J%r%  S SK&J'r'  S SK(J)r)  S SKJ*r*  S SKJ+r+  S SK,J-r-  / r.\" S5      r/\
" S5      r0Sr1S6S jr2S6S jr3\2r4S r5    S7S jr6\" \65      r7\ S8   S9S jj5       r8\    S:S j5       r9S  r:S6S! jr;S;S<S" jjr<S=S# jr=\ S8   S>S$ jj5       r>\S?S@S% jj5       r?\S7S& j5       r?\" SS'/05      S;S( j5       r? " S) S*5      r@S6S+ jrASAS, jrB " S- S.\@5      rC " S/ S0\@5      rD " S1 S2\@5      rE\S;SBS3 jj5       rF\R                        SCSS4.                   SDS5 jjj5       rHg)E    )annotationsN)TYPE_CHECKINGAnyCallableTypeVaroverload)	ParamSpec)core	framework)
global_var)CleanupFuncRegistrar)ParamAliasDecorator)check_and_create_dir   )_get_paddle_place)copy_signaturesignature_safe_contextmanagerwrap_decorator   )Tracer)OrderedDict)	GeneratorSequence)AbstractContextManager)TracebackType)Self)Tensor)	PlaceLike_InputT_RetT__non_persistablec                 "    [         R                  $ )zM
Return a bool value that indicates whether running code under `@to_static`

r   _in_to_static_mode_     X/var/www/html/banglarbhumi/venv/lib/python3.13/site-packages/paddle/base/dygraph/base.pyin_to_static_moder(   A   s    
 )))r&   c                     g)a  
Returns whether the code is running under the SOT simulation context.

NOTE: Always returns False because if this function is called directly from native Python,
it is not within the SOT simulation process. In that case, returning False is correct.
If the code is running within the SOT simulation process, the function will be represented
by UserDefinedFunctionVariable, which is specially handled in its `call_function` method
to return True when this function is called.

This design avoids introducing `global_var` into the guard logic.
Fr%   r%   r&   r'   in_sot_simulation_moder*   I   s     r&   c                |    [        XU5       H,  u  pEnXV:w  d  M  [        R                  " U  S3U S3-   5        M.     g)z
Warning if inputs do not elementwisely equals to support_values.
It's a utility function for dy2static when dygraph interface have
more inputs than static interface such as paddle.grad.

z# has unsupported parameter in jit: z, jit will discard itN)zipwarningswarn)	func_nameinput_namesinputssupport_valuesnameinpsups          r'   &to_static_unsupported_argument_warningr6   \   sF     k>B3:MM+@AF/01 Cr&   funcc                   ^  SU 4S jjnU$ )Nc                 v   > [         R                  " S 5         T" U 0 UD6sS S S 5        $ ! , (       d  f       g = fN)r   _dygraph_guardargskwargsr7   s     r'   __impl__*_switch_to_static_graph_.<locals>.__impl__p   s*    %%d+(( ,++s   *
8r=   z_InputT.argsr>   z_InputT.kwargsreturnr    r%   r7   r?   s   ` r'   _switch_to_static_graph_rD   m   s    ) Or&   c              #     #    [         R                  nU [         l         S v   U[         l        g ! U[         l        f = f7fr:   r#   )is_to_staticoriginal_vals     r'   to_static_mode_guardrH   z   s2     
 11L%1J"6)5
&
&s   ?/ ?<?c              #    #    [        5       (       a  [        R                  " 5       (       d  U (       a   U R                  5       nU R	                  5        HE  u  p#[        U[        5      (       a  U Vs/ s H  n[        U5      PM     nnO[        U5      nXPU'   MG     S v   U R                  U5        g S v   g s  snf ! U R                  W5        f = f7fr:   )	r(   paddlein_dynamic_modecopyitems
isinstancelist_convert_into_variableupdate)
parametersorigin_parametersr3   var_basevarnew_vars         r'   param_guardrW      s     
 6#9#9#;#;

	1 * 1","2"2"4h--FNOhs5c:hGOG4X>G#*4  #5 /0 P /0s.   1C>B= 2B8B= !C8B= =CCc                   [         R                  R                  5       (       a)  [         R                  R                  R                  U 5      $ [        U [         R                  5      (       a  U R                  R                  U R                  5      nUb"  [        U[        R                  5      (       d   eOW[        U [        R                  5      (       a  U R                  SS9nO(Sn[        U R                  ;   a  SnU R                  SUS9nUR                  SL aD  SSKJn  UR%                  5       R&                  R)                  U R                  R*                  U 5        U$ U $ )z
Convert Tensor into Variable.
T)to_parameterF)rY   persistabler   )ProgramTranslator)rJ   r   use_pir_apipirr
   _convert_into_valuerN   r   block_find_var_recursiver3   VariableEagerParamBase_to_static_varNON_PERSISTABLE_VAR_NAME_SUFFIXrZ   'paddle.jit.dy2static.program_translatorr[   get_instance_params_recorderaddprogram)tensorrV   is_persistabler[   s       r'   rP   rP      s#    ##%%zz226::&&--((,,226;;?gy'9'9::::	 8 899+++>G "N /&++=!&++" , G $& **,==AA$$f r&   c                 ,    [         R                  " 5       $ )a  
This function checks whether the program runs in dynamic graph mode or not.
You can enable dynamic graph mode with :ref:`api_paddle_disable_static` api,
or disable dynamic graph mode with :ref:`api_paddle_enable_static` .

**Note**:
    ``base.dygraph.enabled`` is the alias of ``base.in_dygraph_mode``, and
    ``base.in_dygraph_mode`` is recommended to use for now.

Returns:
    bool: Whether the program is running in dynamic graph mode.

Examples:
    .. code-block:: python

        >>> import paddle.base as base

        >>> base.enable_dygraph()  # Now we are in dygragh mode
        >>> print(base.dygraph.enabled())
        True
        >>> base.disable_dygraph()
        >>> print(base.dygraph.enabled())
        False
)r   in_dygraph_moder%   r&   r'   enabledrn      s    4 $$&&r&   c                    [         R                  cT  [        [        U 5      S9[         l        [         R                  R	                  5         [
        R                  " [        5        gg)aT  

.. note::
    Dynamic graph mode is turn ON by default since paddle 2.0.0

This API turn OFF static graph mode. You can turn ON static graph mode by `enable_static <./disable_dygraph_en.html>`_ .

Parameters:
    place(paddle.CPUPlace|paddle.CUDAPlace|str, optional): Place to run dynamic graph. Default: None. Which means that the running place will be
        determined according to the way of paddle compilation. If ``place`` is string, It can be ``cpu``, and ``gpu:x``, where ``x`` is the
        index of the GPUs.

return:
    None

Examples:
    .. code-block:: python

        >>> import paddle
        >>> print(paddle.in_dynamic_mode())
        True

        >>> paddle.enable_static()
        >>> print(paddle.in_dynamic_mode())
        False

        >>> paddle.disable_static()
        >>> print(paddle.in_dynamic_mode())
        True

Nplace)r   #_functional_dygraph_context_managerguardr   	__enter__r   registerdisable_dygraphrp   s    r'   enable_dygraphrw      sO    B 55=9>#E*:

6 	66@@B 	%%o6 >r&   c                     [         R                  b<  [         R                  R                  " [        R                  " 5       6   S[         l        gg)a  

.. note::
    Dynamic graph mode is turn ON by default since paddle 2.0.0

This API turn ON static graph mode. You can turn ON static graph mode by `disable_static <./enable_dygraph_en.html>`_ .

return:
    None

Examples:
    .. code-block:: python

        >>> import paddle
        >>> print(paddle.in_dynamic_mode())
        True

        >>> paddle.enable_static()
        >>> print(paddle.in_dynamic_mode())
        False

        >>> paddle.disable_static()
        >>> print(paddle.in_dynamic_mode())
        True

N)r   rr   __exit__sysexc_infor%   r&   r'   rv   rv     s8    8 55A66??P9=
6 Br&   c              #     #    [         R                  " 5       n[         R                  " U 5         S v   [         R                  " U5        g ! [         R                  " U5        f = f7fr:   )r
   	_has_grad_set_has_grad)is_trainhas_grads     r'   _switch_tracer_mode_guard_r   4  sE      ~~Hx %8$8$s   ,A%A
 A%
A""A%c                    g r:   r%   r7   s    r'   no_gradr   @  s    9<r&   c                    g r:   r%   r   s    r'   r   r   D  s    ILr&   	orig_funcc                   ^  T c	  [        SS9$ [        R                  " T 5            SU 4S jj5       n[        T U5        U$ )aO  
:api_attr: imperative

Create a context which disables dygraph gradient calculation.
In this mode, the result of every computation will have `stop_gradient=True`.

Also functions as a decorator. (Make sure to instantiate without parenthesis.)

.. note::
    Alias Support: The parameter name ``orig_func`` can be used as an alias for ``func``.

Examples:

    .. code-block:: python

        >>> import numpy as np
        >>> import paddle.base as base

        >>> # use as generator

        >>> data = np.array([[2, 3], [4, 5]]).astype('float32')
        >>> with base.dygraph.guard():
        ...     l0 = paddle.nn.Linear(2, 2)  # l0.weight.gradient() is None
        ...     l1 = paddle.nn.Linear(2, 2)
        ...     with base.dygraph.no_grad():
        ...         # l1.weight.stop_gradient is False
        ...         tmp = l1.weight * 2  # tmp.stop_gradient is True
        ...     x = base.dygraph.to_variable(data)
        ...     y = l0(x) + tmp
        ...     o = l1(y)
        ...     o.backward()
        ...     print(tmp.gradient() is None)
        ...     print(l0.weight.gradient() is None)
        True
        False

        >>> @base.dygraph.no_grad
        >>> def test_layer():
        ...     with base.dygraph.guard():
        ...         inp = np.ones([3, 1024], dtype='float32')
        ...         t = base.dygraph.base.to_variable(inp)
        ...         linear1 = paddle.nn.Linear(1024, 4, bias_attr=False)
        ...         linear2 = paddle.nn.Linear(4, 4)
        ...         ret = linear1(t)
        ...         dy_ret = linear2(ret)
        ...
        >>> test_layer()

Fr   c                 \   > [        SS9   T" U 0 UD6sS S S 5        $ ! , (       d  f       g = f)NFr   )r   r<   s     r'   r?   no_grad.<locals>.__impl__  s&    
 ,U;T,V, <;;s   
+rA   )r   	functoolswrapsr   rC   s   ` r'   r   r   H  s^    f |)599 
		-	-$	- 	- 
	- 	tX&r&   c                  \    \ rS rSrSrSr    S
S jrSS jr        SS jrSS jr	Sr
g	)_DecoratorContextManageri  z1Allow a context manager to be used as a decorator__decorated_by__c                  ^ ^ [         R                  " T5      UU 4S j5       n[         R                  " T5      UU 4S j5       n[        R                  " T5      (       a  UnOUn[	        TU5        [        U[        R                  T 5        U$ )Nc                 N   > T   T" U 0 UD6sS S S 5        $ ! , (       d  f       g = fr:   r%   )r=   r>   r7   selfs     r'   _decorate_function=_DecoratorContextManager.__call__.<locals>._decorate_function  s    T,V, s   
$c               ?  n   >#    T" U 0 UD6nT   U S h  vN   S S S 5        g  N! , (       d  f       g = f7fr:   r%   )r=   r>   genr7   r   s      r'   _decorate_generator>_DecoratorContextManager.__call__.<locals>._decorate_generator  s0     ''C  s    5$"$	5$
25)r   r   inspectisgeneratorfunctionr   setattrr   DECORATED_BY_MARKER_ATTR)r   r7   r   r   decorated_fns   ``   r'   __call__!_DecoratorContextManager.__call__  s     
		- 
	- 
		 
	
 &&t,,.L-Lt\*$==	

 r&   c                    [         er:   NotImplementedErrorr   s    r'   rt   "_DecoratorContextManager.__enter__  s    !!r&   c                    [         er:   r   )r   exc_type	exc_value	tracebacks       r'   ry   !_DecoratorContextManager.__exit__  s
     "!r&   c                "    U R                  5       $ r:   )	__class__r   s    r'   clone_DecoratorContextManager.clone  s    ~~r&   r%   Nr7   Callable[_InputT, _RetT]rB   r   )rB   r   )r   ztype[BaseException] | Noner   zBaseException | Noner   zTracebackType | NonerB   boolrB   r   )__name__
__module____qualname____firstlineno____doc__r   r   rt   ry   r   __static_attributes__r%   r&   r'   r   r     sU    ;1,	!8""," (" (	"
 
" r&   r   c                 ,    [         R                  " 5       $ )a  
Returns whether current gradient calculation mode is enabled.

Returns:
    bool: True if current gradient calculation mode is enabled, otherwise false.

Examples:
    .. code-block:: pycon

        >>> import paddle

        >>> # Gradient calculation mode is enabled by default.
        >>> paddle.is_grad_enabled()
        True

        >>> with paddle.set_grad_enabled(False):
        ...     paddle.is_grad_enabled()
        False

        >>> paddle.enable_static()
        >>> paddle.is_grad_enabled()
        True
)r
   r}   r%   r&   r'   is_grad_enabledr     s    0 >>r&   c                0    [         R                  " U 5        g r:   )r
   r~   )modes    r'   _set_grad_enabledr     s    tr&   c                  @    \ rS rSrSrS	S jrS	S jrS
S jrSS jrSr	g)set_grad_enabledi  a  
Create a context which enables or disables dygraph gradient calculation.

Args:
    mode(bool): whether to enable (`True`), or disable (`False`) grad.

Returns:
    None.

Examples:
    .. code-block:: python

        >>> import paddle
        >>> x = paddle.to_tensor([1.], stop_gradient=False)
        >>> is_train = False
        >>> with paddle.set_grad_enabled(is_train):
        ...     y = x * 2
        >>> print(y.stop_gradient)
        True

        >>> paddle.set_grad_enabled(True)
        >>> y = x * 2
        >>> print(y.stop_gradient)
        False

        >>> paddle.set_grad_enabled(False)
        >>> y = x * 2
        >>> print(y.stop_gradient)
        True
c                D    [        5       U l        [        U5        Xl        g r:   )r   prevr   r   )r   r   s     r'   __init__set_grad_enabled.__init__  s    #%	$	r&   c                    g r:   r%   r   s    r'   rt   set_grad_enabled.__enter__   s    r&   c                .    [        U R                  5        g r:   r   r   r   r=   s     r'   ry   set_grad_enabled.__exit__      $))$r&   c                8    U R                  U R                  5      $ r:   )r   r   r   s    r'   r   set_grad_enabled.clone  s    ~~dii((r&   )r   r   NrB   Noner=   objectrB   r   r   )
r   r   r   r   r   r   rt   ry   r   r   r%   r&   r'   r   r     s    >
 %%)r&   r   c                  ,    \ rS rSrSrSS jrSS jrSrg)	no_grad_i	  a@  
:api_attr: imperative

Create a context which disables dygraph gradient calculation.
In this mode, the result of every computation will have `stop_gradient` set
to `True`.

Also functions as a decorator. (Make sure to use an instance.)

Examples:

    .. code-block:: python

        >>> import numpy as np
        >>> import paddle

        >>> # use as generator

        >>> data = np.array([[2, 3], [4, 5]]).astype('float32')
        >>> l0 = paddle.nn.Linear(2, 2)  # l0.weight.gradient() is None
        >>> l1 = paddle.nn.Linear(2, 2)
        >>> with paddle.no_grad():
        ...     # l1.weight.stop_gradient is False
        ...     tmp = l1.weight * 2  # tmp.stop_gradient is True
        >>> x = paddle.to_tensor(data)
        >>> y = l0(x) + tmp
        >>> o = l1(y)
        >>> o.backward()
        >>> print(tmp.gradient() is None)
        True
        >>> print(l0.weight.gradient() is None)
        False

        >>> # use as decorator

        >>> @paddle.no_grad()
        >>> def test_layer():
        ...     inp = np.ones([3, 1024], dtype='float32')
        ...     t = paddle.to_tensor(inp)
        ...     linear1 = paddle.nn.Linear(1024, 4, bias_attr=False)
        ...     linear2 = paddle.nn.Linear(4, 4)
        ...     ret = linear1(t)
        ...     dy_ret = linear2(ret)
        ...
        >>> test_layer()
c                8    [        5       U l        [        S5        g )NFr   r   r   r   s    r'   rt   no_grad_.__enter__9  s    #%	% r&   c                .    [        U R                  5        g r:   r   r   s     r'   ry   no_grad_.__exit__=  r   r&   r   Nr   r   r   r   r   r   r   rt   ry   r   r%   r&   r'   r   r   	  s    -^!%r&   r   c                  ,    \ rS rSrSrSS jrSS jrSrg)	enable_gradiA  a  
:api_attr: imperative

Create a context which enable dygraph gradient calculation,
if it has been disabled by `no_grad` or `set_grad_enabled`.

In this mode, the result of every computation will have `stop_gradient` set
to `False`.

Also functions as a decorator. (Make sure to use an instance.)

Examples:

    .. code-block:: python

        >>> import paddle

        >>> # use as generator

        >>> x = paddle.to_tensor([1.], stop_gradient=False)
        >>> with paddle.no_grad():
        ...     with paddle.enable_grad():
        ...         y = x * 2
        >>> assert(y.stop_gradient == False)
        >>> y.backward()
        >>> assert(x.grad is not None)

        >>> # use as decorator

        >>> @paddle.enable_grad()
        >>> def double(x):
        ...     return x * 2
        ...
        >>> with paddle.no_grad():
        ...     z = double(x)
        ...
        >>> assert(z.stop_gradient == False)
c                8    [        5       U l        [        S5        g )NTr   r   s    r'   rt   enable_grad.__enter__i  s    #%	$r&   c                .    [        U R                  5        g r:   r   r   s     r'   ry   enable_grad.__exit__m  r   r&   r   Nr   r   r   r%   r&   r'   r   r   A  s    %N %r&   r   c           	   #  T  #    [         R                  " 5       n[         R                  " 5       n[        5       nU b  [        U 5      nO[         R                  " 5       n[         R
                  " X5         [         R                  R                  5          [         R                  " U5         [         R                  " U5         Sv   SSS5        SSS5        SSS5        SSS5        g! , (       d  f       N'= f! , (       d  f       N0= f! , (       d  f       N9= f! , (       d  f       g= f7f)a  
:api_attr: imperative

This context will create a dygraph context for dygraph to run, using python ``with`` statement.

Parameters:
    place(base.CPUPlace| base.CUDAPlace|str, optional): Place to execute dygraph.
        If None, the running place will be determined according to the way of paddle compilation.
        If ``place`` is string, It can be ``cpu``, ``gpu:x`` and ``xpu:x``, where ``x`` is the
        index of the GPUs or XPUs. Default: None

return:
    None

Examples:

    .. code-block:: python

        >>> import numpy as np
        >>> import paddle.base as base

        >>> with base.dygraph.guard():
        ...     inp = np.ones([3, 1024], dtype='float32')
        ...     t = base.dygraph.base.to_variable(inp)
        ...     linear1 = paddle.nn.Linear(1024, 4, bias_attr=False)
        ...     linear2 = paddle.nn.Linear(4, 4)
        ...     ret = linear1(t)
        ...     dy_ret = linear2(ret)
        ...
N)
r   Programr   r   _current_expected_place_program_guardunique_namers   r;   _dygraph_place_guard)rq   trainstartuptracerexpected_places        r'   rs   rs   q  s     @ E!GXF*51";;= 	/##%  (&&~6 	7 	) 	& 	0/ 	76 	)( 	&% 	0/sf   A/D(1DD'C5>C$	C5DD	D($
C2.C55
D?D
D	D
D%!D()dump_backward_graph_pathc               `   [        5       (       a#  SSKJn	  [        S/ SQX4XV// SQ5        U	" XX'5      $ S n
U
" U S5      n U
" US5      nUb]  [	        U[
        [        45      (       d  U/nU H8  nUc  M  [	        U[        R                  R                  5      (       a  M3   S	5       e   O/ n[        U5      S:  a  [        U5      [        U 5      :X  d   S
5       eUc  / nO[	        U[        R                  R                  5      (       a  U/nOp[	        U[
        [        [        45      (       aE  [        U5      nU H3  n[	        U[        R                  R                  5      (       a  M.   S5       e   O[        S5      e[	        U[        5      (       d   S5       eUc  Un[	        U[        5      (       d   S5       e[	        U[        5      (       d   S5       e[	        U[        5      (       d   S5       eU(       d   S5       e[        U5        [        R                  R                  U UUUUUUUU5	      $ )a  
.. note::
    **This API is ONLY available in imperative mode.**

This API computes the sum of gradients of `outputs` with respect to each `inputs` .

Parameters:
    outputs (Tensor|list[Tensor]|tuple[Tensor]): the output Tensor or
        Tensor list/tuple of the graph to compute gradients.
    inputs (Tensor|list[Tensor]|tuple[Tensor]): the input Tensor or
        Tensor list/tuple of the graph to compute gradients. The returned
        values of this API are the gradients of `inputs` .
    grad_outputs (Tensor|list[Tensor|None]|tuple[Tensor|None], optional):
        initial gradient values of `outputs` . If `grad_outputs` is None,
        the initial gradient values of `outputs` would be Tensors filled with 1;
        if `grad_outputs` is not None, it must have the same length as `outputs` ,
        and in this case, the initial gradient value of the i-th `outputs` would
        be: (1) a Tensor filled with 1 when the i-th element of `grad_outputs`
        is None; (2) the i-th element of `grad_outputs` when the i-th element of
        `grad_outputs` is a Tensor. Default None.
    retain_graph (bool|None, optional): whether to retain the forward graph which
        is used to calculate the gradient. When it is True, the graph would
        be retained, in which way users can calculate backward twice for the
        same graph. When it is False, the graph would be freed. Default None,
        which means it is equal to `create_graph` .
    create_graph (bool, optional): whether to create the gradient graphs of
        the computing process. When it is True, higher order derivatives are
        supported to compute; when it is False, the gradient graphs of the
        computing process would be discarded. Default False.
    only_inputs (bool, optional): whether to only compute the gradients of
        `inputs` . If it is False, the gradients of all remaining leaf
        Tensors in the graph would be also computed and accumulated.
        If it is True, only the gradients of `inputs` would be computed.
        Default True. only_inputs=False is under development, and it is
        not supported yet.
    allow_unused (bool, optional): whether to raise error or return None if some
        Tensors of `inputs` are unreachable in the graph. If some Tensors of
        `inputs` are unreachable in the graph (i.e., their gradients are None),
        error would be raised if allow_unused=False, or None would be returned as
        their gradients if allow_unused=True. Default False.
    no_grad_vars (Tensor|list[Tensor]|tuple[Tensor]|set[Tensor], optional):
        the Tensors whose gradients are not needed to compute. Default None.
    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:
    list: a list of Tensors, whose length is the same as the Tensor number
    inside `inputs`, and the i-th returned Tensor is the sum of gradients of
    `outputs` with respect to the i-th `inputs`.

Examples:
    .. code-block:: python
        :name: code-example-1

        >>> import paddle

        >>> def test_dygraph_grad(create_graph):
        ...     x = paddle.ones(shape=[1], dtype='float32')
        ...     x.stop_gradient = False
        ...     y = x * x
        ...
        ...     # Since y = x * x, dx = 2 * x
        ...     dx = paddle.grad(
        ...         outputs=[y],
        ...         inputs=[x],
        ...         create_graph=create_graph,
        ...         retain_graph=True
        ...     )[0]
        ...
        ...     z = y + dx
        ...
        ...     # If create_graph = False, the gradient of dx
        ...     # would not be backpropagated. Therefore,
        ...     # z = x * x + dx, and x.gradient() = 2 * x = 2.0
        ...
        ...     # If create_graph = True, the gradient of dx
        ...     # would be backpropagated. Therefore,
        ...     # z = x * x + dx = x * x + 2 * x, and
        ...     # x.gradient() = 2 * x + 2 = 4.0
        ...
        ...     z.backward()
        ...     return x.gradient()
        ...
        >>> print(test_dygraph_grad(create_graph=False))
        [2.]
        >>> print(test_dygraph_grad(create_graph=True))
        [4.]

    .. code-block:: python
        :name: code-example-2

        >>> import paddle

        >>> def test_dygraph_grad(grad_outputs=None):
        ...     x = paddle.to_tensor(2.0)
        ...     x.stop_gradient = False
        ...
        ...     y1 = x * x
        ...     y2 = x * 3
        ...
        ...     # If grad_outputs=None, dy1 = [1], dy2 = [1].
        ...     # If grad_outputs=[g1, g2], then:
        ...     #    - dy1 = [1] if g1 is None else g1
        ...     #    - dy2 = [1] if g2 is None else g2
        ...
        ...     # Since y1 = x * x, dx = 2 * x * dy1.
        ...     # Since y2 = x * 3, dx = 3 * dy2.
        ...     # Therefore, the final result would be:
        ...     # dx = 2 * x * dy1 + 3 * dy2 = 4 * dy1 + 3 * dy2.
        ...
        ...     dx = paddle.grad(
        ...         outputs=[y1, y2],
        ...         inputs=[x],
        ...         grad_outputs=grad_outputs)[0]
        ...
        ...     return dx.numpy()
        ...
        >>> grad_value = paddle.to_tensor(4.0)
        >>> # dy1 = [1], dy2 = [1]
        >>> print(test_dygraph_grad(None))
        7.

        >>> # dy1 = [1], dy2 = [4]
        >>> print(test_dygraph_grad([None, grad_value]))
        16.

        >>> # dy1 = [4], dy2 = [1]
        >>> print(test_dygraph_grad([grad_value, None]))
        19.

        >>> # dy1 = [3], dy2 = [4]
        >>> grad_y1 = paddle.to_tensor(3.0)
        >>> print(test_dygraph_grad([grad_y1, grad_value]))
        24.
r   )	gradientszpaddle.grad)retain_graphcreate_graphonly_inputsallow_unused)NFTFc                n   U c
   U S35       e[        U [        [        45      (       aX  [        U 5      S:  d
   U S35       eU  H7  n[        U[        R
                  R                  5      (       a  M.   SU S35       e   U $ [        U [        R
                  R                  5      (       d
   U S35       eU /$ )Nz should not be Noner   z cannot be emptyzElements of z must be Tensorz! must be Tensor or list of Tensor)rN   rO   tuplelenr
   eagerr   )in_out_listr3   each_vars      r'   check_in_outgrad.<locals>.check_in_outD  s    &D4&0C(DD&kD%=11{#a'BD61A)BB''!(DJJ,=,=>> "4&8> ( k4::+<+<== &9:=  = r&   outputsr1   zLgrad_outputs must be None, a Variable or a list containing None or Variablesz3The length of grad_outputs must be equal to outputsz%no_grad_vars can only contains Tensorz>no_grad_vars must be None, Tensor or list/tuple/set of Tensorsz"create_graph must be True or Falsez(retain_graph must be None, True or Falsez"allow_unused must be True or Falsez!only_inputs must be True or Falsez&only_inputs=False is not supported yet)r(   paddle.staticr   r6   rN   rO   r   r
   r   r   r   setAssertionErrorr   r   run_partial_grad)r   r1   grad_outputsr   r   r   r   no_grad_varsr   r   r   r   rU   s                r'   gradr     s0   h  	,.KC&		
 ,EE!  7I.G&(+F,u66(>L$H#!(DJJ,=,=>> b> % 
<1< CL0 	
A	
0 	L$**"3"3	4	4$~	L4"4	5	5L)Cc4::#4#455 75  
 L
 	
 lD))O+OO)#lD)) 2) lD))O+OO)k4((M*MM(@@@;12::&& 
 
r&   )rB   r   r   )T)rF   r   rB   Generator[None, None, None])rR   zOrderedDict[str, Tensor]rB   r   r:   )rq   PlaceLike | NonerB   r   r   )r   r   rB   r   ).)r7   r   rB   r   )r   r   rB   r   )rq   r  rB   r   )NNFTFN)r   Tensor | Sequence[Tensor]r1   r  r   z'Tensor | Sequence[Tensor | None] | Noner   zbool | Noner   r   r   r   r   r   r   z.Tensor | Sequence[Tensor] | set[Tensor] | Noner   z
str | NonerB   zlist[Tensor])I
__future__r   r   r   rz   r-   typingr   r   r   r   r   typing_extensionsr	   rJ   paddle.baser
   r   paddle.base.frameworkr   paddle.base.multiprocess_utilsr   paddle.utils.decorator_utilsr   paddle.utils.downloadr   r   wrapped_decoratorr   r   r   r   r   collectionsr   collections.abcr   r   
contextlibr   typesr   r   r   paddle._typingr   __all__r   r    rd   r(   r*   in_declarative_moder6   rD   switch_to_static_graphrH   rW   rP   rn   rw   rv   r   r   r   r   r   r   r   r   rs   non_static_onlyr   r%   r&   r'   <module>r     s   #   
   (  ' , ? < 6 ) 
 '31#&(

I
"5 *  ( "
" ((@A  	6	6 	6 	6 (  (,^':(7V>B %% % % 
 < 
 < 
 L 
 L f{m,-? .?D.  . b6+)/ +)\5%' 5%p-%* -%` . .b  =A $CGk ,0k&k%k :k 	k
 k k k Ak )k k kr&   