
    zjC.                    P   d dl mZ d dlZd dlZd dlmZmZ d dlZd dlmZm	Z	m
Z
 d dlmZ d dlmZmZ er%d dlmZ d dlmZ d d	lmZ  ed
eee                   Ze
j        	 ddd            Ze
j        	 dd d            Ze
j         e             e            ddfd!d            ZdS )"    )annotationsN)TYPE_CHECKINGTypeVar)backwardcore	framework)prim_config)primxutils)Sequence)Tensor)Block_TensorOrTensorsToutputsinputsgrad_inputs_TensorOrTensorsT | Nonereturnc                  	 t          j                    st          d          t          | t          j        t          j        t          j	        j
        f          s t          dt          |            d          t          |t          j        t          j        t          j	        j
        f          s t          dt          |           d          t          j        |           t          j        |          t          j        |          }}}t	          j                                                    	t!          	fd||z   D                       rt          d          t#          j        	           t#          j        |d         j                  }|                    |||          \  }}t          | t          j        t          j	        j
        f          r|d         n|S )a  Forward mode of automatic differentiation.

    Note:
        **ONLY available in the static graph mode and primitive operators.**

    Args:
        outputs(Tensor|Sequence[Tensor]): The output tensor or tensors.
        inputs(Tensor|Sequence[Tensor]): The input tensor or tensors.
        grad_inputs(Tensor|Sequence[Tensor]): Optional, the gradient Tensor or
            Tensors of inputs which has the same shape with inputs, Defaults to
            None, in this case is equivalent to all ones.

    Returns:
        grad_outputs(Tensor|Sequence[Tensor]): The gradients for outputs.

    Examples:

        .. code-block:: python

            >>> # doctest: +SKIP('Transform NOT has linearize')
            >>> import numpy as np
            >>> import paddle

            >>> paddle.enable_static()
            >>> paddle.incubate.autograd.enable_prim()

            >>> startup_program = paddle.static.Program()
            >>> main_program = paddle.static.Program()

            >>> with paddle.static.program_guard(main_program, startup_program):
            ...     x = paddle.static.data('x', shape=[1], dtype='float32')
            ...     y = x * x
            ...     y_grad = paddle.incubate.autograd.forward_grad(y, x)
            ...     paddle.incubate.autograd.prim2orig()
            ...
            >>> exe = paddle.static.Executor()
            >>> exe.run(startup_program)
            >>> y_grad = exe.run(main_program, feed={'x': np.array([2.]).astype('float32')}, fetch_list=[y_grad])
            >>> print(y_grad)
            [array([4.], dtype=float32)]

            >>> paddle.incubate.autograd.disable_prim()
            >>> paddle.disable_static()
    zRforward_grad must be running on primitiveoperators, use enable_prim to turn it on.5Expected outputs is Tensor|Sequence[Tensor], but got .4Expected inputs is Tensor|Sequence[Tensor], but got c              3  .   K   | ]}|j         k    V  d S Nblock.0xr   s     p/lsinfo/ai/hellotax_ai/data_center/backend/venv/lib/python3.11/site-packages/paddle/incubate/autograd/primapi.py	<genexpr>zforward_grad.<locals>.<genexpr>r   s*      
-
-17e
-
-
-
-
-
-    zMVariable in inputs and targets should exist in current block of main program.r   )r   prim_enabledRuntimeError
isinstancer   Variabletypingr   paddlepirValue	TypeErrortype
as_tensorsdefault_main_programcurrent_blockanyr
   	orig2prim	Transformr   	linearize)
r   r   r   ysxsxs_dotad_ys_dotr   s
            @r    forward_gradr:   #   s   d  
8
 
 	

 )$fovz7GH  
 (G}}( ( (
 
 	

 #V_fj6FG  
 'F||' ' '
 
 	
 	!!  %% B *,,::<<E

-
-
-
-R"W
-
-
--- 

 
 	

 
OE	A	%	%BRV,,IAv g	 2FJ4DEFF	q		r"   grad_outputsc                   t          j                    sxt          j        | ||          }t	          |t
          j        t          j        j	        f          r5t	          |t          j                  rt          |          dk    r|d         S |S t	          | t
          j        t          j        t          j        j	        f          s t          dt          |            d          t	          |t
          j        t          j        t          j        j	        f          s t          dt          |           d          t          j        |           t          j        |          t          j        |          }}}t          j                                                    t%          fd||z   D                       rt'          d          t)          j                   t)          j                  }|                    ||          \  }}	t%          d |	D                       rt'          d          |                    |	||          \  }}
g }|D ]Q}|Mj                            |j                  }|dk     rt9          d
| d          |                    |           R|                    t?          |                     |                     |           t	          |t
          j        t          j        j	        f          r|
d         n|
S )a  Reverse mode of automatic differentiation.

    Note:
        **ONLY available in the static graph mode and primitive operators**

    Args:
        outputs(Tensor|Sequence[Tensor]): The output Tensor or Tensors.
        inputs(Tensor|Sequence[Tensor]): The input Tensor or Tensors.
        grad_outputs(Tensor|Sequence[Tensor]): Optional, the gradient Tensor or
            Tensors of outputs which has the same shape with outputs, Defaults
            to None, in this case is equivalent to all ones.

    Returns:
        grad_inputs(Tensor|Tensors): The gradients for inputs.

    Examples:

        .. code-block:: python

            >>> # doctest: +SKIP('Transform NOT has linearize')
            >>> import numpy as np
            >>> import paddle

            >>> paddle.enable_static()
            >>> paddle.incubate.autograd.enable_prim()

            >>> startup_program = paddle.static.Program()
            >>> main_program = paddle.static.Program()
            >>> with paddle.static.program_guard(main_program, startup_program):
            ...     x = paddle.static.data('x', shape=[1], dtype='float32')
            ...     x.stop_gradients = False
            ...     y = x * x
            ...     x_grad = paddle.incubate.autograd.grad(y, x)
            ...     paddle.incubate.autograd.prim2orig()
            ...
            >>> exe = paddle.static.Executor()
            >>> exe.run(startup_program)
            >>> x_grad = exe.run(main_program, feed={'x': np.array([2.]).astype('float32')}, fetch_list=[x_grad])
            >>> print(x_grad)
            [array([4.], dtype=float32)]

            >>> paddle.incubate.autograd.disable_prim()
            >>> paddle.disable_static()
    r   r   r   r   c              3  6   K   | ]}|d uo
|j         k    V  d S r   r   r   s     r    r!   zgrad.<locals>.<genexpr>   s3      
A
AAATM.ag.
A
A
A
A
A
Ar"   zQVariable in inputs and outputs should be None or in current block of main programc              3     K   | ]}|d u V  	d S r    )r   vars     r    r!   zgrad.<locals>.<genexpr>   s&      
)
)33$;
)
)
)
)
)
)r"   zEGrads cannot be computed. The given outputs does not depend on inputsNz<op_index should be greater than or equal to 0, but op_index=)!r   r#   r   	gradientsr%   r   r&   r(   r)   r*   r'   r   lenr+   r,   r-   r.   r/   r0   r$   r
   r1   r2   r3   	transposeopsindexop
ValueErrorappend	erase_opssorted
erase_dots)r   r   r;   r   r4   r5   ys_barr7   r6   r9   xs_bar
op_indexesr@   op_indexr   s                 @r    gradrP      s   d  (&,GG
 v	 2FJ4DEFF	;88	 K  1$$q>!)$fovz7GH  
 (G}}( ( (
 
 	

 #V_fj6FG  
 'F||' ' '
 
 	
 	!!  && B
 *,,::<<E

A
A
A
Ab
A
A
AAA 
_
 
 	
 
OE			B\\"b))NFF

)
)&
)
)
))) 
S
 
 	
 \\&&&99NFF J ( (?ysv..H!|| ^S[^^^   h'''LL
##$$$MM& fy16:3CDEE	q		r"   blocksBlock | Sequence[Block]	blacklistset[str] | frozenset[str]	whitelist	start_idxintbackward_lengthNonec                   t          j                    sdS t          | t          j        j        j                  rt          j        d           | j	        }nt          | t          j                  rW| D ]F}t          |t          j        j        j                  s t          dt          |           d          G| d         j	        }n t          dt          |            d          t          t          t          f          s t          dt                     d          t          t          t          f          s t          dt                     d          t           d	         z  t          j        |          5  t          j        d
           t%                    dk    rt%                    dk    rfd}n[t%                    dk    rt%                    dk    rfd}n/t%                    dk    rt%                    dk    rfd}nd }t'          j        | |||           t           d         }t          j        d|            ddd           dS # 1 swxY w Y   dS )a  Search nonbasic ops which have be registered composite rules and replace them with primitive ops.
    The operators in blacklist will be excluded from program when lowering into primitives, and only the
    operators in whitelist will be lowering. The priority of blacklist is higher than whitelist, it means
    an operator both in blacklist and whitelist will not be lowering.

    The finally set that will be lowering is:
        (blocks.ops & ops have decomposite rule & whitelist) - blacklist

    Args:
        blacklist(frozenset): The Operators that will be exclude when lowering into primitives.
        whitelist(frozenset): Only the operators in whitelist will be lowering into primitives.
        start_idx(int): If start_idx exceeds -1, ops[start_idx:] will be processed. Default: -1.
        backward_length(int): If backward_length exceeds -1, ops[:-backward_length] will be processed. Default: -1.
    Nz,Atomize composite op to primitive ops begin.z:Expect block or sequence of blocks, but sequence contains r   r   z,Expect block or sequence of blocks, but got z5Expected type of blacklist is set|frozenset, but got z5Expected type of whitelist is set|frozenset, but got forward_blacklistz'Lowering composite forward ops begin...c                (    | j         v o| j         vS r   r,   )r   rT   rV   s    r    <lambda>zto_prim.<locals>.<lambda>5  s    ) 3 Oi8O r"   c                    | j         vS r   r^   )r   rT   s    r    r_   zto_prim.<locals>.<lambda>7  s    i 7 r"   c                    | j         v S r   r^   )r   rV   s    r    r_   zto_prim.<locals>.<lambda>9  s    ) 3 r"   c                    dS )NTr?   )r   s    r    r_   zto_prim.<locals>.<lambda>;  s     r"   )rW   rY   composite_ops_recordz'Lowering composite forward ops finish: )r   _is_fwd_prim_enabledr%   r(   baser   r   logginginfoprogramr'   r   r+   r,   set	frozensetr	   program_guardrB   r
   _lower_composite)	rR   rT   rV   rW   rY   main_programitemfilter_replace_opss	    ``      r    to_primrq      s   , $&& &&+/566 
CDDD~	FFO	,	, 

 	 	DdFK$9$?@@ ^QUVZQ[Q[^^^   ay(J4<<JJJ
 
 	
 i#y!122 
VDOOVVV
 
 	
 i#y!122 
VDOOVVV
 
 	
 /09<I		 	.	. N N>???y>>A#i..1"4"4OOOOOGG^^aC	NNa$7$77777GG^^q  S^^a%7%73333GG$nG+		
 	
 	
 	
 ""89L{LLMMM%N N N N N N N N N N N N N N N N N Ns   CI++I/2I/r   )r   r   r   r   r   r   r   r   )r   r   r   r   r;   r   r   r   )rR   rS   rT   rU   rV   rU   rW   rX   rY   rX   r   rZ   )
__future__r   rf   r'   r   r   r(   paddle.baser   r   r   paddle.base.corer	   paddle.incubate.autogradr
   r   collections.abcr   r   paddle.base.frameworkr   r   static_onlyr:   rP   rj   rq   r?   r"   r    <module>ry      s   # " " " " "   ) ) ) ) ) ) ) )  1 1 1 1 1 1 1 1 1 1 ( ( ( ( ( ( 1 1 1 1 1 1 1 1 O((((((++++++ 3VXf=MNN  -1\ \ \ \ \~  .2y y y y yx  ,59;;+49;;BN BN BN BN BN BN BNr"   