a
    dD!                     @   s   d Z ddlZddlmZmZmZmZmZ ddlZddlm	Z	 ddl
m	  mZ ddlmZmZ ddlmZ ddlmZ eeZG d	d
 d
e	jZG dd deZdee eeedddZdS )a?   Image to Patch Embedding using Conv2d

A convolution based approach to patchifying a 2D image w/ embedding projection.

Based on code in:
  * https://github.com/google-research/vision_transformer
  * https://github.com/google-research/big_vision/tree/main/big_vision

Hacked together by / Copyright 2020 Ross Wightman
    N)CallableListOptionalTupleUnion)nn   )Formatnchw_to)	to_2tuple)_assertc                
       sT   e Zd ZU dZeed< dee eeeee e	ee
 e	d	 fd
dZdd Z  ZS )
PatchEmbed! 2D Image to Patch Embedding
    
output_fmt            NTimg_size
patch_sizein_chans	embed_dim
norm_layerflattenr   biasc	           	         s   t    t|| _|d ur\t|| _tdd t| j| jD | _| jd | jd  | _nd | _d | _d | _|d urd| _	t
|| _n|| _	t
j| _tj|||||d| _|r||nt | _d S )Nc                 S   s   g | ]\}}|| qS  r   ).0spr   r   `/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/timm/layers/patch_embed.py
<listcomp>-       z'PatchEmbed.__init__.<locals>.<listcomp>r   r   F)Zkernel_sizeZstrider   )super__init__r   r   r   tuplezip	grid_sizeZnum_patchesr   r	   r   NCHWr   ZConv2dprojZIdentitynorm	selfr   r   r   r   r   r   r   r   	__class__r   r    r$      s     


zPatchEmbed.__init__c                 C   s   |j \}}}}| jd urht|| jd kd| d| jd  d t|| jd kd| d| jd  d | |}| jr|ddd}n| jtjkrt	|| j}| 
|}|S )Nr   Input image height (z) doesn't match model ().r   Input image width (   )shaper   r   r)   r   	transposer   r	   r(   r
   r*   )r,   xBCHWr   r   r    forward?   s    
((

zPatchEmbed.forward)r   r   r   r   NTNT)__name__
__module____qualname____doc__r	   __annotations__r   intr   boolstrr$   r:   __classcell__r   r   r-   r    r      s*   
        !r   c                
       sh   e Zd ZU dZeed< dee eeeee e	ee
 e	d	 fd
dZeejee f dddZ  ZS )PatchEmbedWithSizer   r   r   r   r   r   NTr   c	           	   
      s    t  j||||||||d d S )Nr   )r#   r$   r+   r-   r   r    r$   S   s    zPatchEmbedWithSize.__init__)returnc                 C   s   |j \}}}}| jd urpt|| jd  dkd| d| jd  d t|| jd  dkd| d| jd  d | |}|j dd  }| jr|ddd}n| jtj	krt
|| j}| |}||fS )	Nr   r/   z#) must be divisible by patch size (r0   r   r1   r2   )r3   r   r   r   r)   r   r4   r   r	   r(   r
   r*   )r,   r5   r6   r7   r8   r9   r'   r   r   r    r:   i   s    
,,

zPatchEmbedWithSize.forward)r   r   r   r   NTNT)r;   r<   r=   r>   r	   r?   r   r@   r   rA   rB   r$   r   torchTensorr   r:   rC   r   r   r-   r    rD   N   s*   
        rD   bicubicTF)new_sizeinterpolation	antialiasverbosec              	      s   ddl zddl}|j}W n0 tyJ   ttdr:tj}ndsFJ dY n0 t| jdksbJ dtdksvJ d	| jd
d }t|tkr| S |rt	
d| j d d d  fddfdd}||}	tj|	jfdd}
|||
dddd}|| S )a/  Resample the weights of the patch embedding kernel to target resolution.
    We resample the patch embedding kernel by approximately inverting the effect
    of patch resizing.

    Code based on:
      https://github.com/google-research/big_vision/blob/b00544b81f8694488d5f36295aeb7972f3755ffe/big_vision/models/proj/flexi/vit.py

    With this resizing, we can for example load a B/8 filter into a B/16 model
    and, on 2x larger input image, the result will match.

    Args:
        patch_embed: original parameter to be resized.
        new_size (tuple(int, int): target shape (height, width)-only.
        interpolation (str): interpolation for resize
        antialias (bool): use anti-aliasing filter in resize
        verbose (bool): log operation
    Returns:
        Resized patch embedding kernel.
    r   NvmapFzLfunctorch or a version of torch with vmap is required for FlexiViT resizing.   zFour dimensions expectedr2   zNew shape should only be hwrF   zResize patch embedding z to z, w/ z interpolation.c                    s,   t | d }tj|| dd  }|S )N)NN.)sizemoderL   )r   r   .)rG   rH   FZinterpolatenumpy)Zx_np	_new_sizeZx_tfZx_upsampled)rL   rK   r   r    resize   s    z$resample_patch_embed.<locals>.resizec                    sT   g }t  | D ]4} | }d| || < |||d q |jS )Ng      ?)rangeprodzerosZunravel_indexappendreshapestackT)Z	_old_sizerT   matiZ	basis_vec)nprU   r   r    get_resize_mat   s    
z,resample_patch_embed.<locals>.get_resize_matc                    s   |  d }|  S )NrV   )r[   )kernelZresampled_kernel)rJ   resize_mat_pinvr   r    resample_kernel   s    z-resample_patch_embed.<locals>.resample_kernelr   )rS   	functorchrN   ImportErrorhasattrrG   lenr3   r%   _loggerinforH   ZlinalgZpinvr]   )Zpatch_embedrJ   rK   rL   rM   re   rN   Zold_sizera   Z
resize_matrd   Zv_resample_kernelr   )rL   rK   rJ   r`   rU   rc   r    resample_patch_embedy   s,    

 
rk   )rI   TF)r>   loggingtypingr   r   r   r   r   rG   r   Ztorch.nn.functionalZ
functionalrR   formatr	   r
   Zhelpersr   Ztrace_utilsr   	getLoggerr;   ri   Moduler   rD   r@   rB   rA   rk   r   r   r   r    <module>   s(   

5.   