o
    e                     @   s@   d dl 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)FuseBase)PaddleGraphPaddleLayer)*c                       s4   e Zd Z fddZdd Zdd Zdd Z  ZS )	FcFuserc                    s   d| _ tt|   d S Nr   )linear_indexsuperr   __init__)self	__class__ RD:\Projects\ConvertPro\env\Lib\site-packages\x2paddle/optimizer/fusion/fc_fuser.pyr
      s   zFcFuser.__init__c                 C   s^  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i|dgdd | j dd|di|dg | j j|d | j jt| j j d  }t|d}|jdi |dgd |jdd|di|dgddgd |jdi |dgd |jd|dd|dd|dgddd d|jd< | j jd |jdd|di|dgd |	| t|d}|jdi |dgd |jdd|di|dgddgd |jd d|dd!|d"gd d|jd#< |jdi |d$gd |jd%|d"|d$d!|d&gdd' |jdd|d&i|dgd |	| | j j
ddid( d)S )*ue   描述需要替换的fc图结构。
        fc层模式python实现代码示例:
            x133 = x128.shape
            x133 = len(x133)
            x134 = x133 == 2
            if x134 :
                classifier_6_weight = self.classifier_6_weight
                x136 = paddle.transpose(x=classifier_6_weight, perm=[1, 0])
                classifier_6_bias = self.classifier_6_bias
                x137 = paddle.addmm(input=classifier_6_bias, x=x128, y=x136, beta=1, alpha=1)
                x135 = x137
            else:
                classifier_6_weight = self.classifier_6_weight
                x138 = paddle.transpose(x=classifier_6_weight, perm=[1, 0])
                x139 = paddle.matmul(x=x128, y=x138)
                classifier_6_bias = self.classifier_6_bias
                x140 = x139 + 1 * classifier_6_bias
                x135 = x140
        c                 S   s   dt |  S )Nx)str)idr   r   r   gen_name/   s   z'FcFuser.build_pattern.<locals>.gen_namez
prim.shapeinputz
fc-input-0   inputsoutputszprim.lenzprim.eqZeq0   )r   r   Zeq1zprim.if   )Zparent_layerzself.create_parameter   zpaddle.transposer         r   )r   r   perm   zpaddle.addmm)r   r   y   )r   r   betaalphazinput-0z
prim.equalzpaddle.matmul)r   r!   	   zinput-1   z	prim.add_   )r   r   r$   )r   N)patternZ	add_layerr   appendlayerslistkeysr   r   Z	add_blockbuild)r   r   Z	if_layer1Zpattern_block0Zpattern_block1r   r   r   build_pattern   s   








zFcFuser.build_patternc                 C   s4   |  ||}t| d }||j|< || d S r   )gen_new_layerr+   r,   r*   pop)r   graph
parametersmatches	new_layerZnew_layer_idr   r   r   insert_new_layerr   s   
zFcFuser.insert_new_layerc                 C   s   t | }||d  }|jd }||d  }|jd }||d  }|jd }||d  }|jd }t }	|| jd |	d< || jd |	d< d	| j}
|  jd7  _|| d
|d|
< t	
|| |d|
< t|d dfd|i|
|gd|	}|S )Nr   r   r   r   r   r   Zin_featuresZout_featureszlinear{})r   r   z	{}.weightz{}.biaszpaddle.nn.Linearr   )r+   r,   r   r   dictshapeformatr   Z	transposenpZsqueezer   )r   r2   r3   Z	layers_idlayerZ
input_nameZoutput_nameZweight_nameZ	bias_nameattrsZlinear_namer4   r   r   r   r/   x   s@   



zFcFuser.gen_new_layer)__name__
__module____qualname__r
   r.   r5   r/   __classcell__r   r   r   r   r      s
    Xr   )	numpyr9   Z"x2paddle.optimizer.pattern_matcherr   Zx2paddle.core.programr   r   Zx2paddle.core.utilr   r   r   r   r   <module>   s
   