o
    pic                     @  sx  d dl mZ d dlZd dlZd dlmZ d dlmZmZ d dlZd dl	m
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 d	dlmZmZmZ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&	d4d5ddZ'd6ddZ(G d d! d!Z)G d"d# d#Z*d$d% Z+d&d' d(d(fd7d+d,Z,e
j-d4d8d.d/Z.e
j-	d9d:d2d3Z/dS );    )annotationsN)OrderedDict)TYPE_CHECKINGTypeVar)	framework)ops_contain_noneprim_config)Operatordefault_main_program)
as_tensors   )
_composite)lookup_compositelookup_orig2primlookup_prim2orig)
_orig2prim
_prim2orig)flatten_and_remove_noneget_input_var_listget_output_var_listmap_output_for_compositeprepare_python_api_arguments)Sequence)Tensor)Block_TensorOrTensorsTxsSequence[Tensor]ysblockBlock | Nonereturn/tuple[list[Tensor], list[Tensor], list[Tensor]]c                   s8  |du r	t   n|}g }g }t  t | D ]}|du s&|j|ks&J d| t|< q fdd}|jD ]}||rP|| tt|D ]}| t|< qGq6t fdd|D fdd}	t	|D ]}|	|r|| tt
|D ]}|t|< qwqffdd	| D }
 fd
d	|D }tt	||
|fS )a  Returns the list of ops on the path from `xs` to `ys` in topological
    order.

    TODO(Tongxin): supporting control flow and nested blocks.
    Args:
        xs: a list|tuple of vars as source
        ys: a list|tuple of vars as sink
        block: the program block containing the path, optional
    Returns:
        (path, unused_xs, unreached_ys): a tuple comprised of the resulting op
        path, the unused variables in `xs`, and the unreached variables in `ys`
    Nz"x is not None and x.block != blockc                      t  fddtt| D S )Nc                 3      | ]	}t | v V  qd S Nid.0vreached_vars e/home/app/PaddleOCR-VL/.venv_paddleocr/lib/python3.10/site-packages/paddle/incubate/autograd/primx.py	<genexpr>S   
    

.topo_path.<locals>.<lambda>.<locals>.<genexpr>)anyr   r   opr+   r-   r.   <lambda>S       
ztopo_path.<locals>.<lambda>c                 3  s(    | ]}t | v rt ||fV  qd S r%   r&   r)   yr+   r-   r.   r/   a   s   & ztopo_path.<locals>.<genexpr>c                   r#   )Nc                 3  r$   r%   r&   )r)   out	used_varsr-   r.   r/   b   r0   r1   )r2   r   r   r3   r:   r-   r.   r5   b   r6   c                      g | ]
}t | vr|qS r-   r&   )r)   xr:   r-   r.   
<listcomp>n       ztopo_path.<locals>.<listcomp>c                   r<   r-   r&   r7   r+   r-   r.   r>   o   r?   )r
   current_blockr   r   r'   opsappendr   r   reversedr   list)r   r   r   pathZbackpathr=   Zreachingr4   varZback_reachingZ	unused_xsZunreached_ysr-   )r,   r;   r.   	topo_path4   s8   


rG   rE   Sequence[Operator]OrderedDict[int, list[Tensor]]c                 C  s2   t  }| D ]}tt|D ]}||t|< qq|S )zReturns the output variables of all the ops on the path from `xs`
    to `ys`.

    Args:
        path: a list of ops on which to find the output variables

    Returns:
        vars: the output vars
    )r   r   r   r'   )rE   varsr4   r9   r-   r-   r.   output_vars_on_patht   s   rK   c                   @  s   e Zd ZU dZg dZded< ded< ded< d&ddZd'ddZd(ddZd)ddZ	d*ddZ
d+ddZd,ddZd-d!d"Zd.d#d$Zd%S )/VarMapz~A general map data structure for linking variables to variables.

    An example is linking variables to their gradients.
    )namevarsettabstrrM   OrderedDict[int, Tensor]rN   zOrderedDict[int, int]rO   r!   Nonec                 C  s   || _ || _t | _d S r%   )rM   rN   r   rO   )selfrM   rN   r-   r-   r.   __init__   s   zVarMap.__init__key_varr   	value_varc                 C  s   t || jt |< d S r%   r'   rO   )rS   rU   rV   r-   r-   r.   add   s   z
VarMap.addkey_vars
value_varsTensor | Nonec                 C  s   |d u rd S t |tjjjtjjfr2t |tjjjtjjfs'tdt| t	|| j
t	|< d S t|t|ksIJ dt| dt| dt||D ]
\}}| || qNd S )Nz%value_vars must be Variable, but got zDlen(key_vars) should be equal to len(value_vars), but len(key_vars)=z and len(value_vars)=.)
isinstancepaddlebaser   VariablepirValue	TypeErrortyper'   rO   lenzipadd_rec)rS   rY   rZ   rU   rV   r-   r-   r.   rg      s,   zVarMap.add_recc                 C  s(   | j t|}|d ur| j|S d S r%   )rO   getr'   rN   )rS   rU   Zvalue_idr-   r-   r.   lookup   s   zVarMap.lookupc                 C  s&   t |}|| jv r| jt |= d S d S r%   rW   )rS   rU   varidr-   r-   r.   delete   s   
zVarMap.deleter   c                 C  s(   |D ]}t |}|| jv r| j|= qd S r%   rW   )rS   rY   rF   rj   r-   r-   r.   delete_keyvars   s   
zVarMap.delete_keyvarsc                   s<   dd |D   fdd| j  D }|D ]}| j |= qd S )Nc                 S  s   g | ]}t |qS r-   r&   r(   r-   r-   r.   r>      s    z+VarMap.delete_valuevars.<locals>.<listcomp>c                   s   g | ]
\}}| v r|qS r-   r-   )r)   kr*   idsr-   r.   r>      r?   )rO   items)rS   rZ   keysrm   r-   rn   r.   delete_valuevars   s
   
zVarMap.delete_valuevarsboolc                 C  s   | j t|S r%   )rO   __contains__r'   )rS   rU   r-   r-   r.   contain_var   s   zVarMap.contain_varc                 C  s   t || j v S r%   )r'   rO   values)rS   rV   r-   r-   r.   contain_value   s   zVarMap.contain_valueN)rM   rP   rN   rQ   r!   rR   )rU   r   rV   r   r!   rR   )rY   r   rZ   r[   r!   rR   )rU   r   r!   r[   )rU   r   r!   rR   )rY   r   r!   rR   )rZ   r   r!   rR   )rU   r   r!   rs   )rV   r   r!   rs   )__name__
__module____qualname____doc__	__slots____annotations__rT   rX   rg   ri   rk   rl   rr   ru   rw   r-   r-   r-   r.   rL      s   
 







rL   c                   @  s   e Zd ZU dZded< ded< ded< ded< d%ddZd&ddZd'ddZd(ddZd)ddZ	d*ddZ
d+dd Zd,d"d#Zd$S )-	TransformzYAn object that maintains the state of transformations applied to a
    primitive program.r   r   rQ   rJ   rL   var2dotdot2barr!   rR   c                 C  sH   |t   ksJ d|| _| || _td| j| _td| j| _d S )Nz8only support transform on current block of main program.r   Zdot2var)r
   r@   r   	init_varsrJ   rL   r   r   )rS   r   r-   r-   r.   rT      s   zTransform.__init__c                 C  s*   t  }|j D ]
\}}||t|< q|S r%   )r   rJ   rp   r'   )rS   r   rJ   _rF   r-   r-   r.   r      s   zTransform.init_varsnew_varsSequence[Tensor | None]c                 C  s   | j dd |D  d S )Nc                 S  s   i | ]}|d urt ||qS r%   r&   r(   r-   r-   r.   
<dictcomp>   s    z&Transform.add_vars.<locals>.<dictcomp>)rJ   update)rS   r   r-   r-   r.   add_vars   s   zTransform.add_varsTensor | list[Tensor] | Nonec                 C  sp   |d u rd S t |tjjjtjjfr| jt	||i d S t |t
s,tdt| |D ]}| | q.d S )Nznew_vars must be list, but got )r]   r^   r_   r   r`   ra   rb   rJ   r   r'   rD   rc   rd   add_vars_rec)rS   r   rF   r-   r-   r.   r      s   
zTransform.add_vars_recordered_indexesSequence[int]c                 C  sH   | j }t|D ]}|j||d  qt|D ]}|j|= q|  d S )Nr   )r   rC   desc
_remove_oprA   _sync_with_cpp)rS   r   r   Zop_indexr-   r-   r.   	erase_ops   s   
zTransform.erase_opsvars_to_eraser   c                 C  sv   |D ]}t || jv r| jt |= q| j| | j| | j}|D ]}|j}|j	|
  |j|= q#|  d S r%   )r'   rJ   r   rl   r   rr   r   rM   r   _remove_varencoder   )rS   r   rF   r   rM   r-   r-   r.   
erase_dots  s   
zTransform.erase_dotsr   c                   s>   t |tjjjtjjfr j|}|S  fdd|D }|S )zLookup var2dot recursively.c                      g | ]}  |qS r-   )var2dot_rec)r)   rF   rS   r-   r.   r>         z)Transform.var2dot_rec.<locals>.<listcomp>)	r]   r^   r_   r   r`   ra   rb   r   ri   )rS   rJ   dotdotsr-   r   r.   r     s
   zTransform.var2dot_recr   c                   sN   t |tjjjtjjfr j|}|d usJ d|S  fdd|D }|S )Nzbar must be not Nonec                   r   r-   )dot2bar_rec)r)   r   r   r-   r.   r>      r   z)Transform.dot2bar_rec.<locals>.<listcomp>)	r]   r^   r_   r   r`   ra   rb   r   ri   )rS   r   barZbarsr-   r   r.   r     s   zTransform.dot2bar_recN)r   r   r!   rR   )r   r   r!   rQ   )r   r   r!   rR   )r   r   r!   rR   )r   r   r!   rR   )r   r   r!   rR   )rJ   r   r!   r   )r   r   r!   r   )rx   ry   rz   r{   r}   rT   r   r   r   r   r   r   r   r-   r-   r-   r.   r~      s   
 

	




	r~   c                   sZ   fdd fddfdd|rt nt}|rtnt}i }i }i }| j D ]}| | || < q)g }	t }
t	t
| jD ]}| j| }|	| ||jd ur|j|vrt|} ||| tt|t||g|R  D ]'\}}|d u |d u A rJ d|
|j |||j< |j||j< |j||j< qxqCi }t	t
|jD ]}||j| |||j| < qi }t	t
|jD ]}||j| ||j| < qi }t|jD ]	}||||< qdd	lm} | j }||( || t| ||j|||d
}W d    n	1 sw   Y  W d    n	1 s"w   Y  | j| qCt|	D ]}| j||d  | j|= q2|    t	t
| jD ]0}| j| }|j!D ]}||v rg|"|||  qX|j#D ]}||v r{|$|||  qlqNt|
D ]#}||v sJ d| d||| kr| j%|&  | j'|= q|    d S )Nc                   sf   t t| D ]*}t| | tr | | || q| | d ur0| | j|v r0||| | j  | |< qd S r%   )rangere   r]   rD   rM   argsto_bindvalue_tableibindr-   r.   r   '  s   z_lower.<locals>.bindc                   H   g }| D ]}t |tr| || q|||v r|| n| q|S r%   r]   rD   rB   namesr   return_listrM   	bind_namer-   r.   r   .     
z_lower.<locals>.bind_namec                   4   g }| D ]}t |tr| | }q|| q|S r%   r   r   r   r=   expand_nested_listr-   r.   r   7     
z"_lower.<locals>.expand_nested_list"orig_out and new_out should match.r   )param_guard)r   r   rd   inputsoutputsattrsr   
var_name "" is not in to_bind_rev.)(r   r   r   r   r   all_varsrF   rM   setr   re   rA   rB   rd   r   rf   r   r   rX   Zinput_namesinputZoutput_namesoutputsortedZ
attr_namesattrZpaddle.base.dygraph.baser   	append_opr	   rC   r   r   input_arg_names_rename_inputoutput_arg_names_rename_outputr   r   rJ   )r   reverse	blacklistlower_fn	lookup_fnr   r   to_bind_revrF   ops_to_removevars_to_removeop_idxr4   
input_argsorig_outnew_outr   r   r   r   rM   r   Znew_op_descin_nameout_namevar_namer-   r   r   r   r.   _lower%  s   	





 	





r   c                 C  s   dS )NTr-   )r=   r-   r-   r.   r5     s    r5   filter_+typing.Callable[[framework.Operator], bool]c                   sH   fdd fddfddt | tjjjrtd t}t}i }i }i }| j	
 D ]}	| |	 ||	 < q/g }
t }t }d}t| j}t|}d	|  krZ|ksen J d
| d| d	|  kro|kszn J d| d| |d	kr|d	krJ d| d| |d	krt|| }|d	krt||}d }}t|D ]}| j| }|
| |j}||duo||o||v }|s|r|   |}|rd}td | t|} ||| t|}t||g|R  }t|t|ksJ d| dt| dt| t||D ]\}}|du s$|du r6|tvr6td| d| d| |du r=q|dur|j|jks`J d| d|j d|j d|j d|j 
d	|jvsnJ d| d|j|jksJ d| d|j d|j d|j d|j 
|du |du A rJ d||j |||j< |j||j< |j||j< q||j qq| j	 }||j	 q|   t |
D ]}| j	!||d   | j|= q|   tt| jD ]0}| j| }|j"D ]}||v r|#|||  q|j$D ]}||v r|%|||  q	qt&|D ]#}||v s/J d!| d"||| krB| j	'|(  | j)|= q |   t&|D ]}| j	'|(  | j)|= qL|   | jD ]}|*|j	 r||j	+| j	 |j	,| j	 qc|rt-| |||d# dS t | t.j/r| D ]}t-||||d# qdS t0)$z^The operators in block which satisfy the filter condition will be decomposite into primitives.c                   s   t t| D ]8}t| | tr | | || t| | tjjjtjj	fs&q| | d ur>| | j
|v r>||| | j
  | |< qd S r%   )r   re   r]   rD   r^   r_   r   r`   ra   rb   rM   r   r   r-   r.   r     s   z_lower_composite.<locals>.bindc                   r   r%   r   r   r   r-   r.   r     r   z#_lower_composite.<locals>.bind_namec                   r   r%   r   r   r   r-   r.   r     r   z,_lower_composite.<locals>.expand_nested_listz,Atomize composite op to primitive ops begin.Nr   z expect -1 <= backward_length <= z, but got backward_length: zexpect -1 <= start_idx <= z, but got start_idx: zgot start_idx: z and backward_length: FTZcomposite_ops_recordzwhen replace origin op z[ with composite rule, num of origin outs should be equal to new outs, but len(orig_outs) = z and len(new_outs) = zop z2 should not contain any None value. original outs=z and its composite rule outs=zW with composite rule, origin out dtype should be equal to new out dtype, but orig_out: z.dtype=z and new_out: z1 with composite rule, composite out shape has -1.zW with composite rule, origin out shape should be equal to new out shape, but orig_out: z.shape=r   r   r   r   )	start_idxbackward_length)1r]   r^   r_   r   r   logginginfor   r   r   r   rF   rM   r   re   rA   r   rB   rd   r   r   rX   r   r   r   rf   r   
ValueErrorZdtypeshaper   Z	copy_fromrC   r   r   r   r   r   r   r   r   rJ   Z_has_kernelZinfer_var_typeZinfer_shape_lower_compositetypingr   rc   )r   r   r   r   r   r   r   r   r   rF   r   r   Znone_vars_to_removeZchangelengthZidx_listlowerZ	lower_prer   r4   Zop_namer   Z	orig_outsZnew_outsr   r   Zop_descr   r   r   itemr-   r   r.   r     s@  		










#







r   rR   c                 C  s>   | du r	t   n| } | t   ksJ dt| dg d dS )a-  
    Note:
        **This API is ONLY available in the static graph mode.**
        **Args block must be None or current block of main program.**

    All operators in the target block are processed as follows.
    If it is an original operator, it will be transformed into
    one or a series of automatic differential basic operators with
    equivalent function.

    Args:
        block(paddle.static.Block|None, optional): The
            target block to process on. Default None, and will
            process on the current block of main program.
    N7block is neither None nor current block of main programFr   r   r
   r@   r   )r   r-   r-   r.   	orig2primk  s
   r   r   list[str] | Nonec                 C  sN   | du r	t   n| } | t   ksJ d|du rg n|}t| d|d dS )a  
    Note:
        **ONLY available in the static graph mode.**
        **Args block must be None or current block of main program.**

    All operators in the target block are processed as follows.
    If it is an automatic differential basic operator, it will be
    transformed into one or a series of original operators with
    equivalent function to support execution.

    Args:
        block(paddle.static.Block|None, optional): The
            target block to process on. Default None, and will
            process on the current block of main program.
        blacklist(list[string]|None, optional): The names of automatic
            differential basic operator that will not be transformed
            into original operators. Default None, and the blacklist
            is treated as empty list.

    Examples:

        .. code-block:: python

            >>> import paddle
            >>> from paddle.incubate.autograd import enable_prim, prim_enabled, prim2orig

            >>> paddle.enable_static()
            >>> enable_prim()

            >>> x = paddle.ones(shape=[2, 2], dtype='float32')
            >>> x.stop_gradient = False
            >>> y = x * x
            >>> dy_dx = paddle.static.gradients(y, x)
            >>> if prim_enabled():
            ...     prim2orig()
    Nr   Tr   r   )r   r   r-   r-   r.   	prim2orig  s   )r   r%   )r   r   r   r   r   r    r!   r"   )rE   rH   r!   rI   )r   r   )r   r    r!   rR   )NN)r   r    r   r   r!   rR   )0
__future__r   r   r   collectionsr   r   r   r^   Zpaddle.baser   Zpaddle.base.corer   r   Zpaddle.base.frameworkr	   r
   Zpaddle.incubate.autograd.utilsr   Zcomposite_rulesr   Zprimregr   r   r   Z	primrulesr   r   utilsr   r   r   r   r   collections.abcr   r   r   r   rG   rK   rL   r~   r   r   Zstatic_onlyr   r   r-   r-   r-   r.   <module>   sF   
@ITs V