o
    e                     @   sT   d dl Z d dlZd dlmZ d dlmZ d dlmZm	Z	 d dl
T G dd deZdS )    N)OrderedDict)FuseBase)PaddleGraphPaddleLayer)*c                       s4   e Zd Z fddZdd Zdd Zdd Z  ZS )	
PReLUFuserc                    s   d| _ tt|   d S )Nr   )prelu_indexsuperr   __init__)self	__class__ UD:\Projects\ConvertPro\env\Lib\site-packages\x2paddle/optimizer/fusion/prelu_fuser.pyr
      s   zPReLUFuser.__init__c                 C   s   dd }| j jdi |dgd | j jdi |dgdgdd	 | j jd
ddi|dgd | j jdddi|dgd | j jdd|dd|dgd | j jd|d|dd|dgd | j jd|d|dd|dgd | j jd|d|dd|dgd | j jddid dS )uh   描述需要替换的prelu图结构。
        prelu层模式python实现代码示例:
            conv2_alphas = self.conv2_alphas
            conv2_mul_1_y = paddle.full(dtype='float32', shape=[1], fill_value=0.5)
            conv2_Relu = self.relu1(conv2_Conv2D)
            conv2_Abs = paddle.abs(x=conv2_Conv2D)
            conv2_sub = paddle.subtract(x=conv2_Conv2D, y=conv2_Abs)
            conv2_mul = paddle.multiply(x=conv2_alphas, y=conv2_sub, axis=1)
            conv2_mul_1 = paddle.multiply(x=conv2_mul, y=conv2_mul_1_y, axis=1)
            conv2_add = paddle.add(x=conv2_Relu, y=conv2_mul_1)
        c                 S   s   dt |  S )Nx)str)idr   r   r   gen_name)   s   z*PReLUFuser.build_pattern.<locals>.gen_nameself.create_parameterr   )inputsoutputszpaddle.full   g      ?)r   r   shapeZ
fill_valuepaddle.nn.ReLUr   zprelu-input-0   z
paddle.abs   zpaddle.subtract)r   y   zpaddle.multiply      
paddle.add   zinput-0)r   N)patternZ	add_layerbuild)r   r   r   r   r   build_pattern   s`   zPReLUFuser.build_patternc                 C   s   |  |||\}}t|}| D ]\}}tdD ]}	|||	 jkr+|||	 j qqt }
t }t }d}|j D ]%\}}|rH|||< q=||kr^tdD ]}	||	 |||	 j< qPd}||
|< q=|
	| |
	| |
|_d S )Nr   FT)
gen_new_layercopydeepcopyitemsranger   popr   Zlayersupdate)r   graph
parametersmatchesZ
new_layersZlast_layer_idZmatches_copylayer_idlayeriZprefix_layersZ
mid_layersZsuffix_layersZ
is_need_idr   r   r   insert_new_layerP   s2   





zPReLUFuser.insert_new_layerc                 C   s,  t | }|jtd | D ]"\}}|jdkr|jd }|jdkr(|jd }|jdkr2|jd }	qt|d d d	d|id
	|gg dd}
d	| j
}|  j
d7  _
|| }|jd }t|d d ddd
	|i|d	|g|t|d}t|d d d	dd	|i|	gg dd}|
||g|d fS )N)keyr   r   r   r   r    Z_1zpaddle.transposez{}_transpose_for_prelu)r   r   r   r   )r   kernelr   r   permzmerge_prelu{}r   Z_2zpaddle.nn.PReLUinputz{}_prelu)r   r5   r   r   Znum_parametersZweight_attrZ_3)r   r   r   r   )listkeyssortintr(   r5   r   r   r   formatr   r   string)r   r.   r-   r,   Zlayer_id_listr/   r0   Z
input_name
param_nameZoutput_nameZ
transpose0Z
prelu_nameparamcZpreluZ
transpose1r   r   r   r%   i   sJ   










zPReLUFuser.gen_new_layer)__name__
__module____qualname__r
   r$   r2   r%   __classcell__r   r   r   r   r      s
    4r   )r&   numpynpcollectionsr   Z"x2paddle.optimizer.pattern_matcherr   Zx2paddle.core.programr   r   Zx2paddle.core.utilr   r   r   r   r   <module>   s   