o
    Me2[                  
   @   s   d dl Z d dlZd dlmZ d dlZddlmZmZ ddlm	Z	m
Z
 ddlmZ zddlmZ W n  eyP   d dlZejeeed ddlmZ Y nw d	d
 Zdd Zdd ZG dd deZG dd deZde fddZdS )    N)path   )coreunique_name)_apply_passOpProtoHolder)framework_pb2)pass_desc_pb2protoc                 C   s0   g }|   j D ]\}}|jr|| q	|S N)Zglobal_blockvarsitemsZis_dataappend)programZ	data_varsvar_namevar r   ?D:\Projects\ConvertPro\env\Lib\site-packages\paddle/fluid/ir.pyget_data_vars   s   
r   c                 C   s   d}t j }d}d}g }t| jD ]=}| |}|jD ]2}||jv r%d}||jvr+q||}	|	dd d D ]}
|	|
}|d u rCq7|
| |jrMd}q7qq|r\|r^|D ]	}d|_qVd S d S d S )NZgrad_merge_cond_nameFTr      )r   Zop_proto_and_checker_makerZkOpRoleVarAttrNamerangeZ
num_blocksblockopsZ
attr_namesattrZ_find_var_recursiver   Zpersistable)main_programZgrad_merge_attr_nameZop_role_var_attr_nameZhas_grad_mergeZhas_persistable_grad_varZ	grad_varsZblock_idr   opZp_ggZg_varr   r   r   _update_grad_persistable'   s8   







r   c                    s8  ddd fdd}t   dd}| }|jr&|d d|_|jr2|r2|d d|_|jr>|r>|d	 d|_|jrJ|rJ|d
 d|_|jrV|rV|d d|_|jr`|d d|_|j	rj|d d|_	|j
rv|g d d|_
|jr|d d|_|jr|r|d d|_|jr|d d|_|  |S )Nc                 S   s$   || vr|| |< |r|||< d S d S r   r   )attrs
attr_typesnamevaluetypr   r   r   update_attrG   s
   z)apply_build_strategy.<locals>.update_attrc                    sT   t }i }||ddd ||ddd ||dt d t | || d S )	NZnranksr   Zsize_tuse_cudaFboolZmem_opt_skip_varsz	list[str])dictr   r   )r    r   r   r   
pass_attrsstartup_programr#   r   r   
apply_passM   s   z(apply_build_strategy.<locals>.apply_passr$   FZsync_batch_norm_passZfuse_relu_depthwise_conv_passZfuse_bn_act_passZfuse_bn_add_act_passZfusion_group_passZfuse_gemm_epilogue_passZfuse_elewise_add_act_pass)Zcoalesce_grad_tensor_passZfuse_adam_op_passZfuse_sgd_op_passZfuse_momentum_op_passZruntime_context_cache_passZinplace_addto_op_passZbuffer_shared_inplace_passr   )r   getZ_copyZsync_batch_normZfuse_relu_depthwise_convZfuse_bn_act_opsZfuse_bn_add_act_opsZenable_auto_fusionZfuse_gemm_epilogueZfuse_elewise_add_act_opsZfuse_all_optimizer_opsZcache_runtime_contextZenable_addtoZenable_inplaceZ_clear_finalized)r   r)   Zbuild_strategyr(   r*   r$   r   r'   r   apply_build_strategyD   sP   






r,   c                   @   sT   e Zd Ze Ze e fddZdd Zdd Z	dd Z
d	d
 Zdd Zdd ZdS )RegisterPassHelperc                 C   s"   || _ || _|| _tj|  d S r   )
_pass_type_pass_pairs_input_specsr-   _register_helpersr   )self
pass_pairs	pass_typeinput_specsr   r   r   __init__   s   zRegisterPassHelper.__init__c                 C   s   t  }t|}|jD ]5}| j|}t|tjj	r'|
t||j|j qt|tjr6|
t| q|
t|dg q|S )N)listinspectgetfullargspecargsr0   r+   
isinstancepaddlestaticZ	InputSpecr   PassDesc	VarHelpershapeZdtypeZ	ParamAttr)r2   funcr;   Z	arg_specsZarg_nameZ
input_specr   r   r   _get_args_from_func   s   


z&RegisterPassHelper._get_args_from_funcc           	      C   s   |D ]G}t tj|j}t }|jD ])}|jdvr8|	 }t
|dkr8|	 d d }||j}||kr8q|| q|D ]}|j| q@qd S )N)Zop_namescopeZop_callstackZ	op_device   r7   )r   Zget_op_attrs_default_valuer=   compatto_bytestyper8   r   r    Z
ListFieldslenr+   r   remove)	r2   r   Zop_descZdefault_attrsZremove_attrsr   Zattr_list_fieldsZ
attr_valueZdefault_attr_valuer   r   r   _prune_program_desc   s$   

z&RegisterPassHelper._prune_program_descc                 C   s"  t  }tj }tj }tj||O | |}|| || }t|t tfs-|g}|D ],}t|t	j
rV| }	t|	dkrItd|j|	 D ]}
||
 qMq/|| q/W d    n1 sfw   Y  | j}t| D ]}| ||  qv| | || jfS )Nr   zGOperator '{}' has multiple outputs, please specify one output variable.)r8   r=   r>   ZProgramZprogram_guardrC   extendr<   tupler?   OpHelperOutputsrH   
ValueErrorformat_typevaluesr   current_blockdescr   Zop_sizeaddZParseFromStringr   Zserialize_to_stringrJ   r   )r2   rB   r   r   r   r)   r;   Zoutsoutop_outsop_outZ
block_descir   r   r   _func_to_program_desc   s8   





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   ra      s
   zNRegisterPassHelper._convert_vars_to_pass_desc.<locals>._add_element_conditionsrA    )zipZvar_mapsrU   r    Zpattern_varZreplace_varZvar_attr_conditionsr0   Attr_to_pass_desc_attrr   condition_valuer   AttrTypeZLONGSrG   ZlongsrK   rA   r	   r?   ConditionTypekEQr@   	__class___attrsrR   )
r2   patternsreplacesrT   patternreplaceZvar_mapr]   	conditionr   r   r`   r   _convert_vars_to_pass_desc   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?   rM   rk   rR   _mappedr9   
isfunctionZop_attr_mapsrU   re   Zpattern_attrZreplace_attr
_operation	operationCopyFrom)r2   rl   rm   rT   ro   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.   r4   r/   Z
pass_descsrU   rZ   rn   ro   rq   rw   Zdisable_staticZSerializeToString)
r2   Zswitch_static_modeZmulti_pass_descrn   ro   Z	pass_descZpattern_varspattern_opsZreplace_varsZreplace_opsr   r   r   SerializeMultiPassDesc   s(   
z)RegisterPassHelper.SerializeMultiPassDescN)__name__
__module____qualname__r8   r1   strr&   r6   rC   rJ   rZ   rq   rw   ry   r   r   r   r   r-      s    r-   c                   @   sF   e Zd ZG dd deZG dd dejjZG dd deZ	e	 Z
dS )r?   c                   @   s|   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   s6   || _ || _d | _|| _t | _d | _d | _d | _d S r   )	_obj_name_operation_type_element_indexr8   r\   rt   r[   rr   )r2   objr    element_indexr   r   r   r6     s   
zPassDesc.AttrHelper.__init__c                 C   s$   t j| j| j|d}| j| |S )Nr   )r?   
AttrHelperr~   r   r\   r   )r2   indexr_   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<   r~   r?   r@   r	   ZRoleTypeZ	kVariableZroler    r   Z	kOperator_indexZop_indexr   r   ru   r   r   )r2   Zpass_desc_attrr   r   r   re   $  s   


z&PassDesc.AttrHelper._to_pass_desc_attrc                 C   s,   d|_ t|trtjj|_||_d S td)Nrb   z"Unimplemented transform operation.)	r    r<   intr   rg   INTrG   rY   NotImplementedError)r2   r!   Zop_desc_attrr   r   r   _to_op_desc_attr1  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?   r   r~   r   r   r\   r   r   r	   Z	OperationrG   r<   re   r   r   r!   rt   )r2   rG   r!   r   ru   r   r   r   _clone_with_operation9  s   
z)PassDesc.AttrHelper._clone_with_operationc                 C      |  tjjj|S r   )r   r	   r?   OperationTypeZkSubr2   r!   r   r   r   __sub__J     
zPassDesc.AttrHelper.__sub__c                 C   r   r   )r   r	   r?   r   ZkAddr   r   r   r   __add__N  r   zPassDesc.AttrHelper.__add__c                 C   r   r   )r   r	   r?   r   ZkModr   r   r   r   ModR  r   zPassDesc.AttrHelper.Modc                 C   s   |  tjjjS r   )r   r	   r?   r   ZkSizer2   r   r   r   SizeV  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AttrConditionre   r   rG   r<   r   Zcondition_attrr   rf   rt   ru   rv   r[   )r2   rG   r!   rp   r   r   r   _set_with_conditionZ  s   

z'PassDesc.AttrHelper._set_with_conditionc                 C   s   |  tjjj| d S r   )r   r	   r?   rh   ri   r   r   r   r   EQf  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.)r   )rx   r   r   r   
mapped_vars  s   z5PassDesc.AttrHelper.MappedPattern.<locals>.mapped_varc                    sB   fdd| D }t |krtdtj|  dS )Nc                    s   g | ]	}|j  kr|qS r   rQ   .0o)r   r   r   
<listcomp>x  s    zHPassDesc.AttrHelper.MappedPattern.<locals>.mapped_op.<locals>.<listcomp>z)Index '{}' of operator '{}' is incorrect.r   )rH   rO   rP   r?   r   )rx   r   r   r   r    r   r   r   	mapped_opw  s   
z4PassDesc.AttrHelper.MappedPattern.<locals>.mapped_op)allrO   rr   )r2   r   r   r   r    r   r   r   r   r   r   MappedPatternj  s
   
z!PassDesc.AttrHelper.MappedPatternr   )NNr   NN)rz   r{   r|   r6   r   re   r   r   r   r   r   r   r   r   r   r   r   r   r   r     s$    


r   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 || _t | _d S r   )r=   r>   default_main_programrS   data_varr&   rk   )r2   r;   kwargsr   r   r   r   r6     s   zPassDesc.VarHelper.__init__c                 C   s   t | j|S r   )getattrr   )r2   r    r   r   r   __getattr__  s   zPassDesc.VarHelper.__getattr__c                 C   .   | j |}|d u rt| |}|| j |< |S r   rk   r+   r?   r   r2   r    r   r   r   r   rd     
   
zPassDesc.VarHelper.AttrN)rz   r{   r|   r6   r   rd   r   r   r   r   r@     s    r@   c                   @   sV   e Z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.OpHelperNc                 C   s
   || _ d S r   r   )r2   rG   r   r   r   r6     s   
zPassDesc.OpHelper.__init__c                 C   s   t |}|  |S r   )r?   rM   Init)r2   r    r   r   r   r   r     s   
zPassDesc.OpHelper.__getattr__c                 O   sJ  t |dkr
td| D ]l\}}| j|}|d u r%td| j|t|tt	fr<t |dkr;td|| jn|g}|D ],}t|t
jrh| }t |dkr[td|j| D ]}|| q_qA|| qA| 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.z-Operator '{}' does not have input named '{}'.z,Input '{}' of operator '{}' cannot be empty.r   zXThe size of outputs of operator '{}' is not equal 1, please specify one output variable.c                 S   s   g | ]}|j qS r   r    r   rY   r   r   r   r     s    z.PassDesc.OpHelper.__call__.<locals>.<listcomp>r   )rH   rO   r   _inputsr+   rP   rQ   r<   r8   rL   r?   rM   rN   rR   rK   r   _descZ	set_inputr=   r>   r   rS   _outputsr   generateZ
create_var
set_output)r2   r;   r   Zin_nameZin_argsZop_inputZin_argrW   rX   r   Zout_nameZ	op_outputZop_output_namer   r   r   __call__  sN   
zPassDesc.OpHelper.__call__c                 C   s   t j  }t j| j| _	| j	d u rt
d| jt|j| _|j | _| j| j t | _dd | j	jD | _dd | j	jD | _|j|  d S )Nz,type object 'OpHelper' has no attribute '{}'c                 S      i | ]}|j t qS r   r    r8   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   rS   r   instanceZop_proto_mapr+   rQ   _protoAttributeErrorrP   rH   r   r   rT   Z	append_opr   set_typer&   rk   Zinputsr   Zoutputsr   r   )r2   r   r   r   r   r     s   
zPassDesc.OpHelper.Initc                 C   r   r   r   r   r   r   r   rd     r   zPassDesc.OpHelper.Attrc                 C   s.   t |tjr|| |_d S | j|| d S r   )r<   r?   r   rd   rr   r   Z	_set_attr)r2   r    r!   r   r   r   SetAttr  s   zPassDesc.OpHelper.SetAttrc                 C   s*   | j |}|d u rtd| j||S )Nz.Operator '{}' does not have output named '{}'.)r   r+   rO   rP   rQ   )r2   r    outputr   r   r   Output  s   zPassDesc.OpHelper.Outputc                 C   s   | j S r   )r   r   r   r   r   rN     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    )r2   r   paramargr   r   r   
SetOutputs  s
   zPassDesc.OpHelper.SetOutputsr   )rz   r{   r|   r6   r   r   r   rd   r   r   rN   r   r   r   r   r   rM     s    
$rM   N)rz   r{   r|   objectr   r=   r>   Variabler@   rM   OPr   r   r   r   r?     s
    r
\r?   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.fluid.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 )Nr   TF)r<   r8   rL   rH   r   mapr9   rs   )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).)rz   r9   	signaturerH   
parametersr   r   r   rO   r-   r   Zregister_passry   )Zpython_funcr4   r   r3   helperr   r5   r   r   	decorated  s"   
zRegisterPass.<locals>.decorated)r9   rs   )functionr5   r   r   r   r   RegisterPass  s
   !
r   )copyr9   osr   r=   rb   r   r   Z	frameworkr   r   r
   r   r	   ModuleNotFoundErrorsysr   joindirname__file__r   r   r,   r   r-   r?   r&   r   r   r   r   r   <module>   s,   B 
 e