o
    ߥi                     @   s   d dl Zd dlZd dlZd dlm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 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dS )    N)repeat)nn)
functional)init)
_BatchNorm   c                 K   s   t | ts| g} | D ]k}| D ]d}t |tjr7tj|jfi | |j j|9  _|j	dur6|j	j
| qt |tjr\tj|jfi | |j j|9  _|j	dur[|j	j
| qt |trtt|jd |j	durt|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   kaiming_normal_weightdatabiasfill_Linearr   	constant_)module_listscale	bias_fillkwargsmodulem r   c/home/ubuntu/.local/lib/python3.10/site-packages/modelscope/models/cv/super_resolution/arch_util.pydefault_init_weights   s.   




r   c                 K   s0   g }t |D ]}|| d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.
    Nr   )rangeappendr   
Sequential)basic_blocknum_basic_blockkwarglayers_r   r   r   
make_layer/   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                    sp   t t|   || _tj||ddddd| _tj||ddddd| _tjdd| _	|s6t
| j| jgd d S d S )N   r   T)r   )inplaceg?)superr%   __init__	res_scaler   r   conv1conv2ReLUrelur   )selfnum_featr+   pytorch_init	__class__r   r   r*   N   s   zResidualBlockNoBN.__init__c                 C   s(   |}|  | | |}||| j  S )N)r-   r/   r,   r+   )r0   xidentityoutr   r   r   forwardX   s   zResidualBlockNoBN.forward)r&   r   F)__name__
__module____qualname____doc__r*   r8   __classcell__r   r   r3   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 ]}|t|d| ddd |td qn#|dkrI|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   PixelShuffle
ValueErrorr)   r>   r*   )r0   r   r1   r   r#   r3   r   r   r*   f   s   
zUpsample.__init__)r9   r:   r;   r<   r*   r=   r   r   r3   r   r>   ^   s    r>   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   r?   Fg       @g      ?)dim)modepadding_modealign_corners)sizetorchmeshgridarangetype_asstackfloatrequires_gradmaxFgrid_sample)r5   flowinterp_moderL   rM   r#   hwgrid_ygrid_xgridvgridvgrid_xvgrid_yvgrid_scaledoutputr   r   r   	flow_warpv   s(   $22re   Fc                 C   s   |   \}}}}|dkrt||d  t||d  }}	n|dkr,|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.
    ratior   r   shapez1Size type should be ratio or shape, but got type .N)inputrN   rK   rM   )rN   rB   rF   clonerW   interpolate)rY   	size_typesizesrZ   rM   r#   flow_hflow_woutput_houtput_w
input_flowratio_hratio_wresized_flowr   r   r   resize_flow   s(   $
$$rv   c           
      C   s|   |   \}}}}||d  }|| dkr|| dksJ || }|| }| ||||||}	|	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.
    r?   r   r   r'      r@   )rN   viewpermutereshape)
r5   r   bchhhwout_channelr[   r\   x_viewr   r   r   pixel_unshuffle   s   
 r   )r   r   )rG   rH   T)rG   F)collections.abccollectionsrC   warnings	itertoolsr   rO   torchvisionr   torch.nnr   rW   r   torch.nn.modules.batchnormr   no_gradr   r$   Moduler%   r   r>   re   rv   r   r   r   r   r   <module>   s.   
0
/