a
    d.                     @   st   d dl Z d dlmZ d dlm  mZ d dlmZ G dd dejZ	G dd dejZ
e G dd dejZdS )	    N)ARCH_REGISTRYc                       s2   e Zd ZdZd	 fdd	Zdd Zdd Z  ZS )

SeqConv3x3a  The re-parameterizable block used in the ECBSR architecture.

    Paper: Edge-oriented Convolution Block for Real-time Super Resolution on Mobile Devices
    Ref git repo: https://github.com/xindongzhang/ECBSR

    Args:
        seq_type (str): Sequence type, option: conv1x1-conv3x3 | conv1x1-sobelx | conv1x1-sobely | conv1x1-laplacian.
        in_channels (int): Channel number of input.
        out_channels (int): Channel number of output.
        depth_multiplier (int): Width multiplier in the expand-and-squeeze conv. Default: 1.
       c           
         s<  t t|   || _|| _|| _| jdkrt|| | _tj	j
| j| jddd}|j| _|j| _tj	j
| j| jdd}|j| _|j| _n| jdkrtj	j
| j| jddd}|j| _|j| _tj| jdddfdd	 }t	|| _t| jd	 }t|| jf}t	|| _tj| jdddftjd
| _t| jD ]r}	d| j|	dddf< d| j|	dddf< d| j|	dddf< d| j|	dddf< d| j|	dddf< d| j|	dddf< q6t	j| jdd| _nx| jdkrtj	j
| j| jddd}|j| _|j| _tj| jdddfdd	 }t	t|| _t| jd	 }t|| jf}t	t|| _tj| jdddftjd
| _t| jD ]r}	d| j|	dddf< d| j|	dddf< d| j|	dddf< d| j|	dddf< d| j|	dddf< d| j|	dddf< qxt	j| jdd| _n6| jdkr0tj	j
| j| jddd}|j| _|j| _tj| jdddfdd	 }t	t|| _t| jd	 }t|| jf}t	t|| _tj| jdddftjd
| _t| jD ]`}	d| j|	dddf< d| j|	dddf< d| j|	dddf< d| j|	dddf< d| j|	dddf< qt	j| jdd| _ntdd S )Nconv1x1-conv3x3r   r   kernel_sizepadding   )r   conv1x1-sobelx)sizegMbP?)Zdtype      ?       @   g      g       F)dataZrequires_gradconv1x1-sobelyconv1x1-laplaciang      z%The type of seqconv is not supported!)superr   __init__seq_typein_channelsout_channelsint
mid_planestorchnnConv2dweightk0biasb0k1b1Zrandn	ParameterscaleZreshapezerosfloat32maskrangeZFloatTensor
ValueError)
selfr   r   r   depth_multiplierZconv0Zconv1r#   r   i	__class__ a/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/basicsr/archs/ecbsr_arch.pyr      s    
zSeqConv3x3.__init__c                 C   s  | j dkrtj|| j| jdd}t|ddd}| jdddd}||d d d d ddd d f< ||d d d d dd d d f< ||d d d d d d ddf< ||d d d d d d dd f< tj|| j| jdd}ntj|| j| jdd}t|ddd}| jdddd}||d d d d ddd d f< ||d d d d dd d d f< ||d d d d d d ddf< ||d d d d d d dd f< tj|| j	| j
 | jd| jd}|S )	Nr   r   )inputr   r   stride)r   r   r   r   Zconstantr   )r0   r   r   r1   groups)r   Fconv2dr   r   padviewr    r!   r#   r&   r   r   )r)   xZy0Zb0_pady1r.   r.   r/   forwardh   s$    
         zSeqConv3x3.forwardc                 C   sP  | j  }|dk rd }| jdkrtj| j| j ddddd}tjd| j	dd|d| j
dddd }tj|| jdd| j }n| j| j }tj| j| jddf|d}t| jD ]0}||dd d d d f |||d d d d f< q| j}tj|| j ddddd}tjd| jdd|d| j
dddd }tj||dd| }||fS )	Nr   r   r   r   r	   )r0   r   devicer2   )r   
get_devicer   r4   r5   r    Zpermuter   Zonesr   r   r7   r!   r#   r&   r$   r   r'   r   )r)   r<   
rep_weightrep_biastmpr    r+   r!   r.   r.   r/   
rep_params   s     

(.(zSeqConv3x3.rep_params)r   __name__
__module____qualname____doc__r   r:   rA   __classcell__r.   r.   r,   r/   r      s   Sr   c                       s2   e Zd ZdZd
 fdd	Zdd Zdd	 Z  ZS )ECBaQ  The ECB block used in the ECBSR architecture.

    Paper: Edge-oriented Convolution Block for Real-time Super Resolution on Mobile Devices
    Ref git repo: https://github.com/xindongzhang/ECBSR

    Args:
        in_channels (int): Channel number of input.
        out_channels (int): Channel number of output.
        depth_multiplier (int): Width multiplier in the expand-and-squeeze conv. Default: 1.
        act_type (str): Activation type. Option: prelu | relu | rrelu | softplus | linear. Default: prelu.
        with_idt (bool): Whether to use identity connection. Default: False.
    preluFc                    s.  t t|   || _|| _|| _|| _|r>| j| jkr>d| _nd| _tj	j
| j| jddd| _td| j| j| j| _td| j| j| _td| j| j| _td	| j| j| _| jd
krt	j| jd| _nd| jdkrt	jdd| _nJ| jdkrt	jddd| _n.| jdkrt	 | _n| jdkr"ntdd S )NTFr	   r   r   r   r
   r   r   rI   )Znum_parametersZrelu)ZinplaceZrrelugg?)lowerupperZsoftpluslinearz&The type of activation if not support!)r   rH   r   r*   r   r   act_typewith_idtr   r   r   conv3x3r   conv1x1_3x3conv1x1_sbxconv1x1_sbyconv1x1_lplZPReLUactZReLUZRReLUZSoftplusr(   )r)   r   r   r*   rM   rN   r,   r.   r/   r      s0    


zECB.__init__c                 C   s   | j rH| || | | | | | | | }| jrh||7 }n |  \}}tj	|||ddd}| j
dkr|| |}|S )Nr   )r0   r   r   r1   r   rL   )ZtrainingrO   rP   rQ   rR   rS   rN   rA   r4   r5   rM   rT   )r)   r8   yr>   r?   r.   r.   r/   r:      s    2


zECB.forwardc                 C   s   | j j| j j }}| j \}}| j \}}| j \}}| j \}	}
|| | | |	 || | | |
  }}| jr|	 }|dk rd }t
j| j| jdd|d}t| jD ]}d|||ddf< qd}|| ||  }}||fS )Nr   r	   r;   r   r   g        )rO   r   r   rP   rA   rQ   rR   rS   rN   r=   r   r$   r   r'   )r)   Zweight0Zbias0Zweight1Zbias1Zweight2Zbias2Zweight3Zbias3Zweight4Zbias4r>   r?   r<   Z
weight_idtr+   Zbias_idtr.   r.   r/   rA      s$    zECB.rep_params)rI   FrB   r.   r.   r,   r/   rH      s    rH   c                       s(   e Zd ZdZ fddZdd Z  ZS )ECBSRa  ECBSR architecture.

    Paper: Edge-oriented Convolution Block for Real-time Super Resolution on Mobile Devices
    Ref git repo: https://github.com/xindongzhang/ECBSR

    Args:
        num_in_ch (int): Channel number of inputs.
        num_out_ch (int): Channel number of outputs.
        num_block (int): Block number in the trunk network.
        num_channel (int): Channel number.
        with_idt (bool): Whether use identity in convolution layers.
        act_type (str): Activation type.
        scale (int): Upsampling factor.
    c           
   	      s   t t|   || _|| _g }|t||d||dg7 }t|D ]}	|t||d||dg7 }q>|t||| | dd|dg7 }tj| | _	t
|| _d S )Nr   )r*   rM   rN   rL   )r   rV   r   	num_in_chr#   rH   r'   r   Z
SequentialbackboneZPixelShuffle	upsampler)
r)   rW   Z
num_out_chZ	num_blockZnum_channelrN   rM   r#   rX   _r,   r.   r/   r      s    zECBSR.__init__c                 C   sD   | j dkr$tj|| j| j dd}n|}| || }| |}|S )Nr   )Zdim)rW   r   Zrepeat_interleaver#   rX   rY   )r)   r8   ZshortcutrU   r.   r.   r/   r:     s    

zECBSR.forward)rC   rD   rE   rF   r   r:   rG   r.   r.   r,   r/   rV      s   rV   )r   Ztorch.nnr   Ztorch.nn.functionalZ
functionalr4   Zbasicsr.utils.registryr   Moduler   rH   registerrV   r.   r.   r.   r/   <module>   s    O