a
    d&                     @   s   d dl mZ d dlZd dlmZ G dd dejZeeejdddZdeeeeejdddZG dd dejZ	G dd dejZ
G dd dejZG dd dejZG dd dejZG dd dejZG dd dejZdS )    )TupleN)nnc                   @   s$   e Zd ZdZejejdddZdS )SiLUzModule SiLU (Sigmoid Linear Units)

    This implementation is to support pytorch < 1.8, and will be deprecated after 1.8.

    Paper: https://arxiv.org/abs/1702.03118
    xreturnc                 C   s   |t | S N)torchZsigmoidselfr    r   b/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/kornia/contrib/vit_mobile.pyforward   s    zSiLU.forwardN)__name__
__module____qualname____doc__r	   Tensorr   r   r   r   r   r      s   r   )inpoupr   c              
   C   s(   t t j| |dddddt |t S )N   r   Fbiasr   
SequentialConv2dBatchNorm2dr   )r   r   r   r   r   conv_1x1_bn   s    r      r   )r   r   kernal_sizestrider   c              
   C   s(   t t j| |||dddt |t S )Nr   Fr   r   )r   r   r   r    r   r   r   conv_nxn_bn   s    r!   c                       s<   e Zd Zeejdd fddZejejdddZ	  Z
S )PreNormN)dimfnr   c                    s    t    t|| _|| _d S r   )super__init__r   Z	LayerNormnormr$   )r   r#   r$   	__class__r   r   r&      s    
zPreNorm.__init__r   c                 K   s   | j | |fi |S r   )r$   r'   )r   r   kwargsr   r   r   r   !   s    zPreNorm.forward)r   r   r   intr   Moduler&   r	   r   r   __classcell__r   r   r(   r   r"      s   r"   c                       s>   e Zd Zd	eeedd fddZejejdddZ  Z	S )
FeedForward        N)r#   
hidden_dimdropoutr   c              	      s@   t    tt||t t|t||t|| _d S r   )r%   r&   r   r   Linearr   Dropoutnet)r   r#   r0   r1   r(   r   r   r&   &   s    
(zFeedForward.__init__r   c                 C   s
   |  |S r   )r4   r
   r   r   r   r   ,   s    zFeedForward.forward)r/   
r   r   r   r+   floatr&   r	   r   r   r-   r   r   r(   r   r.   %   s   r.   c                       s@   e Zd Zdeeeedd fddZejejdd	d
Z  Z	S )	Attention   @   r/   N)r#   headsdim_headr1   r   c                    s   t    || }|dko ||k }|| _|d | _tjdd| _tj||d dd| _|rvt	t||t
|nt | _d S )Nr   g      r#   r   Fr   )r%   r&   r:   scaler   ZSoftmaxattendr2   to_qkvr   r3   ZIdentityto_out)r   r#   r:   r;   r1   Z	inner_dimZproject_outr(   r   r   r&   1   s    

zAttention.__init__r   c                    s    |jddd}|d j\ t fdd|\}}}t||ddj }|}t||}|j\ }	}
|	 |	|
 }
|S )Nr   r<   r=   r   c                    s   |    jj S r   )
contiguousviewr:   )tBZHDNPr   r   r   <lambda>B       z#Attention.forward.<locals>.<lambda>)r@   chunkshapemapr	   matmulZ	transposer>   r?   rC   rA   )r   r   ZqkvqkvdotsattnoutHDr   rE   r   r   >   s     
zAttention.forward)r8   r9   r/   r5   r   r   r(   r   r7   0   s   r7   c                	       sH   e Zd ZdZd
eeeeeedd fddZejejddd	Z	  Z
S )Transformera  Transformer block described in ViT.

    Paper: https://arxiv.org/abs/2010.11929
    Based on: https://github.com/lucidrains/vit-pytorch

    Args:
        dim: input dimension.
        depth: depth for transformer block.
        heads: number of heads in multi-head attention layer.
        dim_head: head size.
        mlp_dim: dimension of the FeedForward layer.
        dropout: dropout ratio, defaults to 0.
    r/   N)r#   depthr:   r;   mlp_dimr1   r   c                    s\   t    tg | _t|D ]8}| jtt|t||||t|t	|||g qd S r   )
r%   r&   r   
ModuleListlayersrangeappendr"   r7   r.   )r   r#   rY   r:   r;   rZ   r1   _r(   r   r   r&   [   s    
zTransformer.__init__r   c                 C   s,   | j D ] \}}||| }||| }q|S r   )r\   )r   r   rT   ffr   r   r   r   h   s    zTransformer.forward)r/   )r   r   r   r   r+   r6   r&   r	   r   r   r-   r   r   r(   r   rX   L   s    rX   c                       sD   e Zd ZdZdeeeedd fddZejejdd	d
Z  Z	S )MV2Blockap  MV2 block described in MobileNetV2.

    Paper: https://arxiv.org/pdf/1801.04381
    Based on: https://github.com/tonylins/pytorch-mobilenet-v2

    Args:
        inp: input channel.
        oup: output channel.
        stride: stride for convolution, defaults to 1, set to 2 if down-sample.
        expansion: expansion ratio for hidden dimension, defaults to 4.
    r      N)r   r   r    	expansionr   c                    s   t    || _t|| }| jdko,||k| _|dkrttj||d|d|ddt|t	 tj||dddddt|| _
nhttj||dddddt|t	 tj||d|d|ddt|t	 tj||dddddt|| _
d S )Nr   r   F)groupsr   r   r   )r%   r&   r    r+   use_res_connectr   r   r   r   r   conv)r   r   r   r    rc   r0   r(   r   r   r&   |   s,    

zMV2Block.__init__r   c                 C   s"   | j r|| | S | |S d S r   )re   rf   r
   r   r   r   r      s    zMV2Block.forward)r   rb   )
r   r   r   r   r+   r&   r	   r   r   r-   r   r   r(   r   ra   o   s    ra   c                
       sR   e Zd ZdZd
eeeeeeef eedd fddZej	ej	ddd	Z
  ZS )MobileViTBlockax  MobileViT block mentioned in MobileViT.

    Args:
        dim: input dimension of Transformer.
        depth: depth of Transformer.
        channel: input channel.
        kernel_size: kernel size.
        patch_size: patch size for folding and unfloding.
        mlp_dim: dimension of the FeedForward layer in Transformer.
        dropout: dropout ratio, defaults to 0.
    r/   N)r#   rY   channelkernel_size
patch_sizerZ   r1   r   c                    sf   t    |\| _| _t|||| _t||| _t||dd||| _	t||| _
td| ||| _d S )Nrb   r8      )r%   r&   phpwr!   conv1r   conv2rX   transformerconv3conv4)r   r#   rY   rh   ri   rj   rZ   r1   r(   r   r   r&      s    

zMobileViTBlock.__init__r   c                 C   s   |  }| |}| |}|j\}}}}||| j| j || j || j  |}| |}|||||}| |}t	
||fd}| |}|S )Nr   )clonern   ro   rM   rC   rl   rm   rp   rq   r	   catrr   )r   r   ybdhwr   r   r   r      s    

(


zMobileViTBlock.forward)r/   )r   r   r   r   r+   r   r6   r&   r	   r   r   r-   r   r   r(   r   rg      s    
rg   c                       sL   e Zd ZdZdeeeeef edd fdd	Ze	j
e	j
d
ddZ  ZS )	MobileViTa=  Module MobileViT. Default arguments is for MobileViT XXS.

    Paper: https://arxiv.org/abs/2110.02178
    Based on: https://github.com/chinhsuanwu/mobilevit-pytorch

    Args:
        mode: 'xxs', 'xs' or 's', defaults to 'xxs'.
        in_channels: the number of channels for the input image.
        patch_size: image_size must be divisible by patch_size.
        dropout: dropout ratio in Transformer.

    Example:
        >>> img = torch.rand(1, 3, 256, 256)
        >>> mvit = MobileViT(mode='xxs')
        >>> mvit(img).shape
        torch.Size([1, 320, 8, 8])
    xxsr   rk   rk   r/   N)modein_channelsrj   r1   r   c           
         s&  t    |dkr(d}g d}g d}n:|dkrFd}g d}g d}n|d	krbd}g d
}g d}d}g d}	t||d dd| _tg | _| jt|d |d d| | jt|d |d d| | jt|d |d d| | jt|d |d d| | jt|d |d d| | jt|d |d d| | jt|d |d d| tg | _	| j	t
|d |	d |d ||t|d d |d | j	t
|d |	d |d ||t|d d |d | j	t
|d |	d |d ||t|d d |d t|d |d | _d S )Nr{   rk   )r9   P   `   )   r      r   0   r   r9   r9   r   r   i@  xsrb   )r   x      )r       r   r   r9   r9   r   r   r   r   i  s)r         )r   r   r9   r9   r   r      r      r   i  r   )rk   rb   r   r   )r    r            r8   )r1   	   rK   r<   )r%   r&   r!   rn   r   r[   mv2r^   ra   mvitrg   r+   r   ro   )
r   r}   r~   rj   r1   rc   dimsZchannelsri   rY   r(   r   r   r&      sF    


,,,zMobileViT.__init__r   c                 C   s   |  |}| jd |}| jd |}| jd |}| jd |}| jd |}| jd |}| jd |}| jd |}| jd |}| jd |}| |}|S )Nr   r   rk   r   rb   r   r   )rn   r   r   ro   r
   r   r   r   r     s    

zMobileViT.forward)r{   r   r|   r/   )r   r   r   r   strr+   r   r6   r&   r	   r   r   r-   r   r   r(   r   rz      s    ,rz   )r   r   )typingr   r	   r   r,   r   r+   r   r!   r"   r.   r7   rX   ra   rg   rz   r   r   r   r   <module>   s   
#46