
    {-jh                         d dl Z d dlZd dlmZ ddlmZ  G d dej                  Zd Zdd	Zd
 Z	d Z
d Zd Zd Zd Zd Zd Zej        ej        feej        ej        feiZdS )    N)nn   )utilsc                   (     e Zd ZdZ fdZd Z xZS )Identityz$a layer to replace bn or relu layersc                 H    t                                                       d S N)super__init__)selfargskwargs	__class__s      i/var/www/html/banglarbhumi/venv/lib/python3.11/site-packages/paddle/quantization/imperative/fuse_utils.pyr   zIdentity.__init__   s        c                     |S r	    )r   inputs     r   forwardzIdentity.forward   s    r   )__name__
__module____qualname____doc__r   r   __classcell__)r   s   @r   r   r      sM        ..          r   r   c                    d}| j         r|                                  d}g }d d g}|                                 D ]\  }}t          |t          j                  r||d<   t          |t          j                  r||d<   |d         r4|d         r,t          |          dk    r|                    |           d d g}t          | |          } |r| 
                                 d S d S )NFTr   r      )trainingevalnamed_sublayers
isinstancer   Conv2DBatchNorm2Dlenappendfuse_layerstrain)modelis_train	fuse_listtmp_pairnamelayers         r   fuse_conv_bnr-   !   s   H~ 

Id|H,,.. $ $eeRY'' 	HQKeR^,, 	HQKA; 	$8A; 	$3x==A+=+=X&&&d|Hy))E  r   Fc                 `    |du rt          j        |           } |D ]}t          | |           | S )a1  
    fuse layers in layers_to_fuse

    Args:
        model(paddle.nn.Layer): The model to be fused.
        layers_to_fuse(list): The layers' names to be fused. For
            example,"fuse_list = [["conv1", "bn1"], ["conv2", "bn2"]]".
            A TypeError would be raised if "fuse" was set as
            True but "fuse_list" was None.
                              Default: None.
        inplace(bool): Whether apply fusing to the input model.
                       Default: False.

    Return
        fused_model(paddle.nn.Layer): The fused model.
    F)copydeepcopy_fuse_layers)r'   layers_to_fuseinplacelayerss       r   r%   r%   6   sE    " %e$$  $ $UF####Lr   c                 0   g }|D ]=}t          j        | |          \  }}|                    t          ||                     >t	          |          }t          |          D ]4\  }}t          j        | |          \  }}t          ||||                    5dS )z"fuse all the layers in layers_listN)r   find_parent_layer_and_sub_namer$   getattr
_fuse_func	enumeratesetattr)	r'   layers_list
layer_list
layer_nameparent_layersub_name
new_layersiitems	            r   r1   r1   N   s    J! ; ;
!&!E:"
 "
h 	',99::::J''J[)) 7 74!&!E4"
 "
h 	h
16666	7 7r   c                 R   t          d | D                       }t                              |d          }dgt          |           z  } ||  }| d         j                                        D ](\  }}|                    |           | d         j        |= )| d         j                                        D ](\  }}|                    |           | d         j        |= )||d<   t          dt          |                     D ]'}t                      }	| d         j        |	_        |	||<   (|S )z&choose the fuse method and fuse layersc              3   4   K   | ]}t          |          V  d S r	   )type).0ms     r   	<genexpr>z_fuse_func.<locals>.<genexpr>`   s(      ..a$q''......r   Nr   r   )tupletypes_to_fusion_methodgetr#   _forward_pre_hooksitemsregister_forward_pre_hook_forward_post_hooksregister_forward_post_hookranger   r   )
r<   typesfusion_methodr@   fused_layer	handle_idpre_hook_fnhook_fnrA   identitys
             r   r8   r8   ^   s<   ..:.....E*..ud;;M#j//)J-,K",Q-"B"H"H"J"J 8 8	;--k:::qM,Y77(n@FFHH : :	7..w777rN.y99JqM1c*oo&& ! !::&qM2 
1r   c                     | j         |j         k    s
J d            | j         r!|j        | j        k    s
J d            t          t	          | |          S )z"fuse conv and bn for train or evalz:Conv and BN both must be in the same mode (train or eval).z?Output channel of Conv2d must match num_features of BatchNorm2d)r   _num_features_out_channelsNotImplementedError_fuse_conv_bn_eval)convbns     r   _fuse_conv_bnra   r   sh    =BK'''D ('' } ,4#5555M 655 "!!$+++r   c           	         | j         s|j         r
J d            t          j        |           }t          |j        |j        |j        |j        |j        |j        |j                  \  }}|j        	                    |           |j        ,t          j        |j        gd|j        j                  |_        |j        	                    |           |S )zfuse conv and bn for evalFusion only for eval!NTshapeis_biasdtype)r   r/   r0   _fuse_conv_bn_weightsweightbias_mean	_variance_epsilon	set_valuepaddlecreate_parameterr\   rg   )r_   r`   
fused_convfused_weight
fused_biass        r   r^   r^      s    FFF/FFF-t$$J4



	
   L* --- 1+,d"'-
 
 

 Oj)))r   c                 H   |t          j        |          }|t          j        |          }|t          j        |          }t          j        ||z             }| ||z                      dgdgt          | j                  dz
  z  z             z  } ||z
  |z  |z  |z   }| |fS )z$fuse weights and bias of conv and bnNrI   r   )ro   
zeros_like	ones_likersqrtreshaper#   re   )conv_wconv_bbn_rmbn_rvbn_epsbn_wbn_bbn_var_rsqrts           r   rh   rh      s    ~"5))|&&| ''<//Ltl*33	sc&,''!+,,  F un,t3d:F6>r   c                     | j         |j         k    s
J d            | j         r,|j        | j        j        d         k    s
J d            t          t          | |          S )zfuse linear and bnz<Linear and BN both must be in the same mode (train or eval).r   z=Output channel of Linear must match num_features of BatchNorm)r   r[   ri   re   r]   _fuse_linear_bn_eval)linearr`   s     r   _fuse_linear_bnr      so    ?bk)))F *))  06=#6q#9999K :99 "!#FB///r   c           	         | j         s|j         r
J d            t          j        |           }t          |j        |j        |j        |j        |j        |j        |j                  \  }}|j        	                    |           |j        7t          j        |j        j        d         gd|j        j                  |_        |j        	                    |           |S )zfuse linear and bn for evalrc   Nr   Trd   )r   r/   r0   _fuse_linear_bn_weightsri   rj   rk   rl   rm   rn   ro   rp   re   rg   )r   r`   fused_linearrr   rs   s        r   r   r      s    H2;HH1HHH/=((L6



	
   L* !!,/// "3&,Q/0'-
 
 

 
+++r   c                     |t          j        |          }|t          j        ||z             z  }| |                    d          z  }||z
  |z  |z   }	||	fS )z&fuse weights and bias of linear and bnNrI   )ro   ru   rw   	unsqueeze)
linear_wlinear_br{   r|   r}   r~   r   bn_scalefused_wfused_bs
             r   r   r      si     $U++fl56>222H++B///G%8+d2GGr   )F)r/   ro   r    r   Layerr   r-   r%   r1   r8   ra   r^   rh   r   r   r   r!   r"   LinearBatchNorm1DrK   r   r   r   <module>r      s0                    rx     *   07 7 7   (, , ,  .   0 0 0  2	 	 	 YY   r   