U
    Mh                     @  s   d dl mZ d dlZd dlmZmZmZ d dlZddddgZedd	d
Z	eddd
Z
ddddddddZddddddddddd	ddZddddddZdddddddddddZdS )    )annotationsN)OptionalTupleTypeVarfuse_conv_bn_evalfuse_conv_bn_weightsfuse_linear_bn_evalfuse_linear_bn_weightsConvTztorch.nn.modules.conv._ConvNd)boundLinearTztorch.nn.LinearFz%torch.nn.modules.batchnorm._BatchNormbool)convbn	transposereturnc              	   C  sf   | j s|j rtdt| }|jdk	r2|jdk	s6tt|j|j|j|j|j	|j|j|\|_|_|S )a+  Fuse a convolutional module and a BatchNorm module into a single, new convolutional module.

    Args:
        conv (torch.nn.modules.conv._ConvNd): A convolutional module.
        bn (torch.nn.modules.batchnorm._BatchNorm): A BatchNorm module.
        transpose (bool, optional): If True, transpose the convolutional weight. Defaults to False.

    Returns:
        torch.nn.modules.conv._ConvNd: The fused convolutional module.

    .. note::
        Both ``conv`` and ``bn`` must be in eval mode, and ``bn`` must have its running buffers computed.
    Fusion only for eval!N)
trainingAssertionErrorcopydeepcopyrunning_meanrunning_varr   weightbiaseps)r   r   r   Z
fused_conv r   G/var/www/html/venv/lib/python3.8/site-packages/torch/nn/utils/fusion.pyr      s    
      ztorch.TensorzOptional[torch.Tensor]floatz-Tuple[torch.nn.Parameter, torch.nn.Parameter])	conv_wconv_bbn_rmbn_rvbn_epsbn_wbn_br   r   c                 C  s   | j }|dk	r|j n|}	|dkr*t|}|dkr<t|}|dkrNt|}t|| }
|r~ddgdgt| jd   }nddgdgt| jd   }| ||
 | j|d}|| |
 | | j|	d}tj	
|| jtj	
||jfS )a  Fuse convolutional module parameters and BatchNorm module parameters into new convolutional module parameters.

    Args:
        conv_w (torch.Tensor): Convolutional weight.
        conv_b (Optional[torch.Tensor]): Convolutional bias.
        bn_rm (torch.Tensor): BatchNorm running mean.
        bn_rv (torch.Tensor): BatchNorm running variance.
        bn_eps (float): BatchNorm epsilon.
        bn_w (Optional[torch.Tensor]): BatchNorm weight.
        bn_b (Optional[torch.Tensor]): BatchNorm bias.
        transpose (bool, optional): If True, transpose the conv weight. Defaults to False.

    Returns:
        Tuple[torch.nn.Parameter, torch.nn.Parameter]: Fused convolutional weight and bias.
    N      )dtype)r)   torch
zeros_likeZ	ones_likersqrtlenshapeZreshapetonn	Parameterrequires_grad)r   r    r!   r"   r#   r$   r%   r   Zconv_weight_dtypeZconv_bias_dtypeZbn_var_rsqrtr.   Zfused_conv_wZfused_conv_br   r   r   r   %   s"    


 )linearr   r   c                 C  s   | j s|j rtdt| }| j|jks<|jdks<td|jdk	rP|jdk	sTtt|j	|j
|j|j|j|j	|j
\|_	|_
|S )a  Fuse a linear module and a BatchNorm module into a single, new linear module.

    Args:
        linear (torch.nn.Linear): A Linear module.
        bn (torch.nn.modules.batchnorm._BatchNorm): A BatchNorm module.

    Returns:
        torch.nn.Linear: The fused linear module.

    .. note::
        Both ``linear`` and ``bn`` must be in eval mode, and ``bn`` must have its running buffers computed.
    r   r&   zGTo fuse, linear.out_features == bn.num_features or bn.num_features == 1N)r   r   r   r   Zout_featuresZnum_featuresr   r   r	   r   r   r   )r3   r   Zfused_linearr   r   r   r   T   s&    

     )linear_wlinear_br!   r"   r#   r$   r%   r   c           
      C  sb   |dkrt |}|t ||  }| |d }|| | | }	t j|| jt j|	|jfS )a  Fuse linear module parameters and BatchNorm module parameters into new linear module parameters.

    Args:
        linear_w (torch.Tensor): Linear weight.
        linear_b (Optional[torch.Tensor]): Linear bias.
        bn_rm (torch.Tensor): BatchNorm running mean.
        bn_rv (torch.Tensor): BatchNorm running variance.
        bn_eps (float): BatchNorm epsilon.
        bn_w (torch.Tensor): BatchNorm weight.
        bn_b (torch.Tensor): BatchNorm bias.
        transpose (bool, optional): If True, transpose the conv weight. Defaults to False.

    Returns:
        Tuple[torch.nn.Parameter, torch.nn.Parameter]: Fused linear weight and bias.
    Nr'   )r*   r+   r,   Z	unsqueezer0   r1   r2   )
r4   r5   r!   r"   r#   r$   r%   Zbn_scaleZfused_wZfused_br   r   r   r	   y   s    
)F)F)
__future__r   r   typingr   r   r   r*   __all__r
   r   r   r   r   r	   r   r   r   r   <module>   s      /%