a
    d,                     @   s8  d dl Zd dlZd dlZd dlZd dlZd dlmZ d dlm	Z	 d dlm
Z
 d dlmZ d dlmZ d dlmZ d dlmZmZ d d	lmZ e d,ddZdd ZG dd de
jZG dd de
jZd-ddZd.ddZdd ZG dd deZ dd  Z!d/d%d&Z"d'd( Z#e#d
Z$e#d)Z%e#d*Z&e#d+Z'e#Z(dS )0    N)LooseVersion)repeat)nn)
functional)init)
_BatchNorm)ModulatedDeformConvPackmodulated_deform_conv)get_root_logger   c                 K   s   t | ts| g} | D ]}| D ]}t |tjrntj|jfi | |j j|9  _|j	dur|j	j
| q t |tjrtj|jfi | |j j|9  _|j	dur|j	j
| q t |tr t|jd |j	dur |j	j
| q qdS )ae  Initialize network weights.

    Args:
        module_list (list[nn.Module] | nn.Module): Modules to be initialized.
        scale (float): Scale initialized weights, especially for residual
            blocks. Default: 1.
        bias_fill (float): The value to fill bias. Default: 0
        kwargs (dict): Other arguments for initialization function.
    Nr   )
isinstancelistmodulesr   Conv2dr   Zkaiming_normal_weightdatabiasZfill_ZLinearr   Z	constant_)Zmodule_listscaleZ	bias_fillkwargsmodulem r   `/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/basicsr/archs/arch_util.pydefault_init_weights   s$    




r   c                 K   s0   g }t |D ]}|| f i | qtj| S )zMake layers by stacking the same blocks.

    Args:
        basic_block (nn.module): nn.module class for basic block.
        num_basic_block (int): number of blocks.

    Returns:
        nn.Sequential: Stacked blocks in nn.Sequential.
    )rangeappendr   
Sequential)Zbasic_blockZnum_basic_blockkwargZlayers_r   r   r   
make_layer0   s    
r   c                       s*   e Zd ZdZd	 fdd	Zdd Z  ZS )
ResidualBlockNoBNa  Residual block without BN.

    It has a style of:
        ---Conv-ReLU-Conv-+-
         |________________|

    Args:
        num_feat (int): Channel number of intermediate features.
            Default: 64.
        res_scale (float): Residual scale. Default: 1.
        pytorch_init (bool): If set to True, use pytorch default init,
            otherwise, use default_init_weights. Default: False.
    @   r   Fc                    sl   t t|   || _tj||ddddd| _tj||ddddd| _tjdd| _	|sht
| j| jgd d S )N   r   T)r   )Zinplaceg?)superr    __init__	res_scaler   r   conv1conv2ZReLUrelur   )selfnum_featr%   Zpytorch_init	__class__r   r   r$   O   s    zResidualBlockNoBN.__init__c                 C   s(   |}|  | | |}||| j  S N)r'   r(   r&   r%   )r)   xidentityoutr   r   r   forwardY   s    zResidualBlockNoBN.forward)r!   r   F)__name__
__module____qualname____doc__r$   r1   __classcell__r   r   r+   r   r    @   s   
r    c                       s    e Zd ZdZ fddZ  ZS )UpsamplezUpsample module.

    Args:
        scale (int): Scale factor. Supported scales: 2^n and 3.
        num_feat (int): Channel number of intermediate features.
    c              
      s   g }||d @ dkr\t tt|dD ]0}|t|d| ddd |td q(nF|dkr|t|d| ddd |td ntd| dt	t
| j|  d S )	Nr   r         r"   	   zscale z/ is not supported. Supported scales: 2^n and 3.)r   intmathlogr   r   r   ZPixelShuffle
ValueErrorr#   r7   r$   )r)   r   r*   r   r   r+   r   r   r$   g   s    zUpsample.__init__)r2   r3   r4   r5   r$   r6   r   r   r+   r   r7   _   s   r7   bilinearzerosTc                 C   s  |   dd |  dd ks$J |   \}}}}ttd|| td|| \}}	t|	|fd }
d|
_|
| }d|dddddddf  t|d d d	 }d|dddddddf  t|d d d	 }tj||fdd
}t	j
| ||||d}|S )ak  Warp an image or feature map with optical flow.

    Args:
        x (Tensor): Tensor with size (n, c, h, w).
        flow (Tensor): Tensor with size (n, h, w, 2), normal value.
        interp_mode (str): 'nearest' or 'bilinear'. Default: 'bilinear'.
        padding_mode (str): 'zeros' or 'border' or 'reflection'.
            Default: 'zeros'.
        align_corners (bool): Before pytorch 1.3, the default value is
            align_corners=True. After pytorch 1.3, the default value is
            align_corners=False. Here, we use the True as default.

    Returns:
        Tensor: Warped image or feature map.
    Nr   r"   r   r8   F       @      ?Zdim)modepadding_modealign_corners)sizetorchZmeshgridZarangeZtype_asstackfloatZrequires_gradmaxFZgrid_sample)r.   flowinterp_moderF   rG   r   hwZgrid_yZgrid_xZgridZvgridZvgrid_xZvgrid_yZvgrid_scaledoutputr   r   r   	flow_warpu   s    $,22rS   Fc                 C   s   |   \}}}}|dkr<t||d  t||d   }}	n,|dkrX|d |d  }}	ntd| d|  }
|| }|	| }|
dddddddf  |9  < |
dddddddf  |9  < tj|
||	f||d}|S )	a  Resize a flow according to ratio or shape.

    Args:
        flow (Tensor): Precomputed flow. shape [N, 2, H, W].
        size_type (str): 'ratio' or 'shape'.
        sizes (list[int | float]): the ratio for resizing or the final output
            shape.
            1) The order of ratio should be [ratio_h, ratio_w]. For
            downsampling, the ratio should be smaller than 1.0 (i.e., ratio
            < 1.0). For upsampling, the ratio should be larger than 1.0 (i.e.,
            ratio > 1.0).
            2) The order of output_size should be [out_h, out_w].
        interp_mode (str): The mode of interpolation for resizing.
            Default: 'bilinear'.
        align_corners (bool): Whether align corners. Default: False.

    Returns:
        Tensor: Resized flow.
    Zratior   r   shapez1Size type should be ratio or shape, but got type .N)inputrH   rE   rG   )rH   r;   r>   clonerM   Zinterpolate)rN   Z	size_typesizesrO   rG   r   Zflow_hZflow_wZoutput_hZoutput_wZ
input_flowZratio_hZratio_wZresized_flowr   r   r   resize_flow   s    $$$rY   c           
      C   s|   |   \}}}}||d  }|| dkr4|| dks8J || }|| }| ||||||}	|	dddddd||||S )z Pixel unshuffle.

    Args:
        x (Tensor): Input feature with shape (b, c, hh, hw).
        scale (int): Downsample ratio.

    Returns:
        Tensor: the pixel unshuffled feature.
    r8   r   r   r"      r9   )rH   viewZpermuteZreshape)
r.   r   bchhZhwZout_channelrP   rQ   Zx_viewr   r   r   pixel_unshuffle   s    
r_   c                   @   s   e Zd ZdZdd ZdS )	DCNv2PackaN  Modulated deformable conv for deformable alignment.

    Different from the official DCNv2Pack, which generates offsets and masks
    from the preceding features, this DCNv2Pack takes another different
    features to generate offsets and masks.

    Ref:
        Delving Deep into Deformable Alignment in Video Super-Resolution.
    c           
      C   s   |  |}tj|ddd\}}}tj||fdd}t|}tt|}|dkrlt }	|	d| d t	t
jt	dkrt
j||| j| j| j| j| j|S t|||| j| j| j| j| j| j| j
S d S )Nr"   r   rD   2   zOffset abs mean is z, larger than 50.z0.9.0)Zconv_offsetrI   chunkcatZsigmoidmeanabsr
   warningr   torchvision__version__opsZdeform_conv2dr   r   ZstridepaddingZdilationr	   groupsZdeformable_groups)
r)   r.   Zfeatr0   Zo1Zo2maskoffsetZoffset_absmeanloggerr   r   r   r1      s    

zDCNv2Pack.forwardN)r2   r3   r4   r5   r1   r   r   r   r   r`      s   
r`   c                 C   s   dd }||d|  k s(||d|  kr6t jddd t  ||| | }||| | }| d| d d| d  |   | |td  | 	| | j
||d | W  d    S 1 s0    Y  d S )	Nc                 S   s   dt | t d  d S )NrC   rB   )r<   erfsqrtr.   r   r   r   norm_cdf   s    z(_no_grad_trunc_normal_.<locals>.norm_cdfr8   zjmean is more than 2 std from [a, b] in nn.init.trunc_normal_. The distribution of values may be incorrect.)
stacklevelr   rB   )minrL   )warningswarnrI   no_gradZuniform_Zerfinv_Zmul_r<   rp   Zadd_Zclamp_)tensorrd   stdar\   rr   lowZupr   r   r   _no_grad_trunc_normal_   s     

r|           rC          rB   c                 C   s   t | ||||S )a?  Fills the input Tensor with values drawn from a truncated
    normal distribution.

    From: https://github.com/rwightman/pytorch-image-models/blob/master/timm/models/layers/weight_init.py

    The values are effectively drawn from the
    normal distribution :math:`\mathcal{N}(\text{mean}, \text{std}^2)`
    with values outside :math:`[a, b]` redrawn until they are within
    the bounds. The method used for generating the random values works
    best when :math:`a \leq \text{mean} \leq b`.

    Args:
        tensor: an n-dimensional `torch.Tensor`
        mean: the mean of the normal distribution
        std: the standard deviation of the normal distribution
        a: the minimum cutoff value
        b: the maximum cutoff value

    Examples:
        >>> w = torch.empty(3, 5)
        >>> nn.init.trunc_normal_(w)
    )r|   )rx   rd   ry   rz   r\   r   r   r   trunc_normal_  s    r   c                    s    fdd}|S )Nc                    s    t | tjjr| S tt|  S r-   )r   collectionsabcIterabletupler   rq   nr   r   parse2  s    z_ntuple.<locals>.parser   )r   r   r   r   r   _ntuple0  s    r   r8   r"   r9   )r   r   )r?   r@   T)r?   F)r}   rC   r~   rB   ))collections.abcr   r<   rI   rg   ru   Zdistutils.versionr   	itertoolsr   r   Ztorch.nnr   rM   r   Ztorch.nn.modules.batchnormr   Zbasicsr.ops.dcnr   r	   Zbasicsr.utilsr
   rw   r   r   Moduler    r   r7   rS   rY   r_   r`   r|   r   r   Z	to_1tupleZ	to_2tupleZ	to_3tupleZ	to_4tupleZ	to_ntupler   r   r   r   <module>   s:   
"
'&

