o
    piUL                  	   @   s   d dl Z d dlmZ d dlZd dlmZ ddlmZmZ ddl	m
Z
 zd dlmZ W n$ eyN   d dlZeed Zejeed	 d dlmZ Y nw G d
d dZG dd dZdi fddZdS )    N)path)framework_pb2   )coreunique_name)OpProtoHolder)pass_desc_pb2z/../../baseprotoc                   @   sN   e Zd Zg Zdi fddZdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dS )RegisterPassHelper c                 C   s"   || _ || _|| _tj|  d S N)
_pass_type_pass_pairs_input_specsr
   _register_helpersappend)self
pass_pairs	pass_typeinput_specs r   `/home/app/PaddleOCR-VL/.venv_paddleocr/lib/python3.10/site-packages/paddle/incubate/passes/ir.py__init__%   s   zRegisterPassHelper.__init__c                 C   s   g }t |}|jD ]5}| j|}t|tjjr&|	t
||j|j q
t|tjr5|	t| q
|	t
|dg q
|S )N)inspectgetfullargspecargsr   get
isinstancepaddlestaticZ	InputSpecr   PassDesc	VarHelpershapeZdtypeZ	ParamAttr)r   funcr   Z	arg_specsZarg_nameZ
input_specr   r   r   _get_args_from_func+   s   


z&RegisterPassHelper._get_args_from_funcc           	      C   s   |D ]D}t |j }g }|jD ])}|jdvr5| }t|dkr5| d d }||j}||kr5q|	| q|D ]}|j
| q=qd S )N)Zop_namescopeZop_callstackZ	op_devicer   r   )r   Zget_op_attrs_default_valuetypeencodeattrsnameZ
ListFieldslenr   r   remove)	r   opsZop_descZdefault_attrsZremove_attrsattrZattr_list_fields
attr_valueZdefault_attr_valuer   r   r   _prune_program_desc<   s$   

z&RegisterPassHelper._prune_program_descc                 C   s"  g }t j }t j }t j||P | |}|| || }t|ttfs,|g}|D ]-}t|t	j
rV| }	t|	dkrItd|j d|	 D ]}
||
 qMq.|| q.W d    n1 sfw   Y  | j}t| D ]}| ||  qv| | || jfS )N   
Operator 'z;' has multiple outputs, please specify one output variable.)r   r    ZProgramZprogram_guardr%   extendr   listtupler!   OpHelperOutputsr*   
ValueError_typevaluesr   current_blockdescrangeZop_sizeaddZParseFromStringopZserialize_to_stringr/   r,   )r   r$   r,   varsprogramZstartup_programr   Zoutsoutop_outsop_outZ
block_descir   r   r   _func_to_program_descU   s6   





z(RegisterPassHelper._func_to_program_descc           
         s    fdd t ||D ]S\}}|j }|j|_|j|_|j}|j| jv rJ| }|d	|j
 d|j_tjj|j_|jj|j tjjj|_tj|jkr^|j D ]}	 ||	g qUqd S )Nc                    s,   |D ]}|j r| |j   | |j qd S r   )
_conditionr   	_elements)
conditionselementselement_add_element_conditionsr   r   rL   q   s
   zNRegisterPassHelper._convert_vars_to_pass_desc.<locals>._add_element_conditionsr#   r   )zipZvar_mapsr=   r)   Zpattern_varZreplace_varZvar_attr_conditionsr   Attr_to_pass_desc_attrr-   condition_valuer   AttrTypeZLONGSr&   Zlongsr2   r#   r   r!   ConditionTypekEQr"   	__class___attrsr9   )
r   patternsreplacesr;   patternreplaceZvar_maprH   	conditionr-   r   rK   r   _convert_vars_to_pass_descp   s$   
z-RegisterPassHelper._convert_vars_to_pass_descc                 C   s|   |D ]9}t |tjr;|j D ]+}|j}t|r||}|j	 }|
|j |
|j |jd ur:|j|j qqd S r   )r   r!   r5   rU   r9   _mappedr   
isfunctionZop_attr_mapsr=   rO   Zpattern_attrZreplace_attr
_operation	operationCopyFrom)r   rV   rW   r;   rY   r-   ZmappedZattr_mapr   r   r   _convert_ops_to_pass_desc   s   


z,RegisterPassHelper._convert_ops_to_pass_descc           
      C   s   t  }|r
t   t }| j|_| jD ])\}}|j	 }| 
||j\}}| 
||j\}}	| ||| | ||	| q|rEt   | S r   )r   Zin_dynamic_modeZenable_staticr   ZMultiPassDescr   r   r   Z
pass_descsr=   rE   rX   rY   r[   ra   Zdisable_staticZSerializeToString)
r   Zswitch_static_modeZmulti_pass_descrX   rY   Z	pass_descZpattern_varspattern_opsZreplace_varsZreplace_opsr   r   r   SerializeMultiPassDesc   s(   
z)RegisterPassHelper.SerializeMultiPassDescN)__name__
__module____qualname__r   r   r%   r/   rE   r[   ra   rc   r   r   r   r   r
   "   s    r
   c                   @   sB   e Zd ZG dd dZG dd dejjZG dd dZe Z	dS )r!   c                   @   st   e Zd ZdddZdd Zdd Zdd	 Zdd
dZdd Zdd Z	dd Z
dd Zdd Zdd Z	dddZdS )zPassDesc.AttrHelperNc                 C   s4   || _ || _d | _|| _g | _d | _d | _d | _d S r   )_obj_name_operation_type_element_indexrG   r^   rF   r\   )r   objr)   element_indexr   r   r   r      s   
zPassDesc.AttrHelper.__init__c                 C   s$   t j| j| j|d}| j| |S )Nrl   )r!   
AttrHelperrg   rh   rG   r   )r   indexrJ   r   r   r   __getitem__   s
   
zPassDesc.AttrHelper.__getitem__c                 C   sp   t | jtjrtjjj|_| jj|_	ntjjj
|_| jj|_| j|_| jd ur+| j|_| jd ur6| j|_d S d S r   )r   rg   r!   r"   r   ZRoleTypeZ	kVariableZroler)   var_nameZ	kOperator_indexZop_indexrh   ri   r_   rj   rl   )r   Zpass_desc_attrr   r   r   rO      s   


z&PassDesc.AttrHelper._to_pass_desc_attrc                 C   s,   d|_ t|trtjj|_||_d S td)Nr   z"Unimplemented transform operation.)	r)   r   intr   rQ   INTr&   rD   NotImplementedError)r   valueZop_desc_attrr   r   r   _to_op_desc_attr   s
   


z$PassDesc.AttrHelper._to_op_desc_attrc                 C   s|   t | j| j| j}| j| |d u r||_|S tj 	 }||_
t|t jr.||j n| ||j ||_| j|_|S r   )r!   rn   rg   rh   rj   rG   r   ri   r   Z	Operationr&   r   rO   r-   rw   rv   r^   )r   r&   rv   r-   r_   r   r   r   _clone_with_operation   s   
z)PassDesc.AttrHelper._clone_with_operationc                 C      |  tjjj|S r   )rx   r   r!   OperationTypeZkSubr   rv   r   r   r   __sub__      
zPassDesc.AttrHelper.__sub__c                 C   ry   r   )rx   r   r!   rz   ZkAddr{   r   r   r   __add__   r}   zPassDesc.AttrHelper.__add__c                 C   ry   r   )rx   r   r!   rz   ZkModr{   r   r   r   Mod   r}   zPassDesc.AttrHelper.Modc                 C   s   |  tjjjS r   )rx   r   r!   rz   ZkSizer   r   r   r   Size   s   zPassDesc.AttrHelper.Sizec                 C   sb   t j }| |j ||_t|tjr||j n| 	||j
 | jr,|j| j || _d S r   )r   r!   ZAttrConditionrO   r-   r&   r   rn   Zcondition_attrrw   rP   r^   r_   r`   rF   )r   r&   rv   rZ   r   r   r   _set_with_condition   s   

z'PassDesc.AttrHelper._set_with_conditionc                 C   s   |  tjjj| d S r   )r   r   r!   rR   rS   r{   r   r   r   EQ  s   
zPassDesc.AttrHelper.EQr   c                    sJ   t |gr
tddd } fdd}|d u r || _d S || _d S )Nz#Only mapped one of which var or op.c                 S   s   t d)Nz'Mapping to variable is not implemented.)ru   )rb   r   r   r   
mapped_var  s   z5PassDesc.AttrHelper.MappedPattern.<locals>.mapped_varc                    sH   fdd| D }t |krtd d dtj|  dS )Nc                    s   g | ]	}|j  kr|qS r   r8   .0o)r>   r   r   
<listcomp>  s    zHPassDesc.AttrHelper.MappedPattern.<locals>.mapped_op.<locals>.<listcomp>zIndex '' of operator 'z' is incorrect.rm   )r*   r7   r!   rn   )rb   r,   rl   ro   r)   r>   r   r   	mapped_op  s   
z4PassDesc.AttrHelper.MappedPattern.<locals>.mapped_op)allr7   r\   )r   varr>   ro   r)   rl   r   r   r   r   r   MappedPattern  s
   
z!PassDesc.AttrHelper.MappedPatternr   )NNr   NN)rd   re   rf   r   rp   rO   rw   rx   r|   r~   r   r   r   r   r   r   r   r   r   rn      s    


rn   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )zPassDesc.VarHelperc                 O   s,   t j  }t jj|i || _i | _d S r   )r   r    default_main_programr:   data_varrU   )r   r   kwargsblockr   r   r   r   )  s   
zPassDesc.VarHelper.__init__c                 C   s   t | j|S r   )getattrr   )r   r)   r   r   r   __getattr__.  s   zPassDesc.VarHelper.__getattr__c                 C   .   | j |}|d u rt| |}|| j |< |S r   rU   r   r!   rn   r   r)   r-   r   r   r   rN   1  
   
zPassDesc.VarHelper.AttrN)rd   re   rf   r   r   rN   r   r   r   r   r"   (  s    r"   c                   @   s`   e Zd ZdddZdddZdd Zd	d
 Zdd Zdd Zdd Z	dd Z
dd Zdd ZdS )zPassDesc.OpHelperTc                 C   s   t |tsJ dt| d}|ddd | j D 7 }|d7 }d}|ddd | j D 7 }|d7 }d}|ddd | j D 7 }|d7 }| d	| j d
| d| d}|S )NzCskip_op_callstack parameter's type is error, expect bool, received {z, c                 S      g | ]\}}| d | qS =r   r   kvr   r   r   r   ?      z7PassDesc.OpHelper._to_readable_code.<locals>.<listcomp>}c                 S   r   r   r   r   r   r   r   r   E  r   c                 S   r   r   r   r   r   r   r   r   J  r   z = z(inputs=))	r   boolr&   join_outputsitems_inputsrU   r8   )r   Zskip_op_callstackZoutputs_strZ
inputs_strZ	attrs_strZop_strr   r   r   _to_readable_code9  s$   z#PassDesc.OpHelper._to_readable_codeNc                 C   s
   || _ d S r   r   )r   r&   r   r   r   r   P  s   
zPassDesc.OpHelper.__init__c                 C   s   t |}|  |S r   )r!   r5   Init)r   r)   r>   r   r   r   r   S  s   
zPassDesc.OpHelper.__getattr__c                 O   sX  t |dkr
td| D ]s\}}| j|}|d u r(td| j d| dt|ttfrBt |dkrAtd| d| j dn|g}|D ]-}t|t	j
ro| }t |d	krbtd
|j d| D ]}|| qfqG|| qG| j|dd |D  qtj  }	| j D ]\}
}t| j}||	j|d | j|
|g q| S )Nr   z6Each input argument needs to specify a parameter name.r1   z' does not have input named ''.zInput 'r   z' cannot be empty.r0   z!The size of outputs of operator 'z5' is not equal 1, please specify one output variable.c                 S   s   g | ]}|j qS r   r)   r   rD   r   r   r   r   u  s    z.PassDesc.OpHelper.__call__.<locals>.<listcomp>r   )r*   r7   r   r   r   r8   r   r3   r4   r!   r5   r6   r9   r2   r   _descZ	set_inputr   r    r   r:   r   r   generateZ
create_var
set_output)r   r   r   Zin_nameZin_argsZop_inputZin_argrB   rC   r   Zout_nameZ	op_outputZop_output_namer   r   r   __call__X  sF   zPassDesc.OpHelper.__call__c                 C   s   t j  }t j| j| _	| j	d u rt
d| j dt|j| _|j | _| j| j i | _dd | j	jD | _dd | j	jD | _|j|  d S )Nz)type object 'OpHelper' has no attribute ''c                 S      i | ]}|j g qS r   r   r   r   r   r   
<dictcomp>      z*PassDesc.OpHelper.Init.<locals>.<dictcomp>c                 S   r   r   r   r   r   r   r   r     r   )r   r    r   r:   r   instanceZop_proto_mapr   r8   _protoAttributeErrorr*   r,   rr   r;   Z	append_opr   set_typerU   Zinputsr   Zoutputsr   r   )r   r   r   r   r   r   }  s   
zPassDesc.OpHelper.Initc                 C   r   r   r   r   r   r   r   rN     r   zPassDesc.OpHelper.Attrc                 C   s.   t |tjr|| |_d S | j|| d S r   )r   r!   rn   rN   r\   r   Z	_set_attr)r   r)   rv   r   r   r   SetAttr  s   zPassDesc.OpHelper.SetAttrc                 C   s0   | j |}|d u rtd| j d| d|S )Nr1   z' does not have output named 'r   )r   r   r7   r8   )r   r)   outputr   r   r   Output  s   zPassDesc.OpHelper.Outputc                 C   s   | j S r   )r   r   r   r   r   r6     s   zPassDesc.OpHelper.Outputsc                 K   s>   |  D ]\}}|d u r| j| q| j||jg qd S r   )r   r   Zremove_outputr   r)   )r   r   paramargr   r   r   
SetOutputs  s
   zPassDesc.OpHelper.SetOutputs)Tr   )rd   re   rf   r   r   r   r   r   rN   r   r   r6   r   r   r   r   r   r5   8  s    

%r5   N)
rd   re   rf   rn   r   r    Variabler"   r5   OPr   r   r   r   r!      s
    u
sr!   c                    s,   dd   fdd}t | r|| S |S )a  
    The function decorator of Register Pass. Decorator @RegisterPass handles
    the function and register it into a core.Pass instance. Use name of function
    as Pass type.

    Args:
        function (callable): The function with return of callable pair(s) that
            represents the pattern subgraph and the replace subgraph.
        input_specs (dict[str, InputSpec]): Dict of InputSpec to specific the shape/dtype
            information of Tensor. Some operators limit the shape and dtype of datas when
            create subgraph with Paddle APIs. So user need specify InputSpec of data to
            ensure create a correctly subgraph. Of course, this argument is not limited to
            matching subgraph. The default is dict().

    Returns:
        callables: Callable pair(s).

    Examples:
        .. code-block:: python

            >>> import paddle
            >>> from paddle.incubate.passes.ir import RegisterPass

            >>> @RegisterPass
            >>> def multi_add_to_addn():
            ...    def pattern(x, y, z):
            ...        return paddle.add(paddle.add(x, y), z)
            ...    def replace(x, y, z):
            ...        return paddle.add_n([x, y, z])
            ...    return pattern, replace
    c                 S   s2   t | ttfrt| dkrtttj| rdS dS )N   TF)r   r3   r4   r*   r   mapr   r]   )Z
check_pairr   r   r   _is_pass_pair  s
   z#RegisterPass.<locals>._is_pass_pairc                    s~   | j }t| }t|jdkrtdt|jdkr=|  } |r%|g}ntt |s0tdt	||}t
||j | S )Nr   z2Pass function with parameter is not supported now.z;Return value of Pass function must be (callable, callable).)rd   r   	signaturer*   
parametersru   r   r   r7   r
   r   Zregister_passrc   )Zpython_funcr   r   r   helperr   r   r   r   	decorated  s"   
zRegisterPass.<locals>.decorated)r   r]   )functionr   r   r   r   r   RegisterPass  s
   !
r   )r   osr   r   Zpaddle.base.protor   baser   r   Zbase.frameworkr   r   ModuleNotFoundErrorsysdirname__file__	base_pathr   r   r
   r!   r   r   r   r   r   <module>   s&     }