
    ^jfb                        d Z ddlZddlZddlmZmZmZmZmZm	Z	 ddl
Z
ddl
mZ ddlmc mZ ddlmZmZ ddlmZ ddlmZ  ej,                  e      Z G d	 d
ej2                        Z G d de      Z	 	 	 d"dee   dededefdZe
j@                  Z!e!fdeeef   deeef   dedede
jD                  de
jF                  de
jH                  fdZ%e!fde
jH                  de
jH                  deeef   de
jF                  de
jF                  de
jH                  fdZ&	 	 	 d"de
jH                  dee   dededef
dZ' G d dej2                        Z( G d  d!ej2                        Z)y)#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DictListOptionalTupleUnion)nn   )Formatnchw_to)	to_2tuple)_assertc                       e Zd ZU dZeed<   ej                  j                  e	   ed<   	 	 	 	 	 	 	 	 	 	 	 	 dde
eeeeef   f      dededede
e   d	e	de
e   d
e	de	de	f fdZdeeeeef   f   fdZ	 	 dde
eeeeef   f      de
eeeeef   f      fdZddeeeef   ef   fdZdeeef   deeef   fdZd Z xZS )
PatchEmbed! 2D Image to Patch Embedding
    
output_fmtdynamic_img_padimg_size
patch_sizein_chans	embed_dim
norm_layerflattenbiasstrict_img_sizec                    ||d}t         |           t        |      | _        | j	                  |      \  | _        | _        | _        |d| _        t        |      | _
        n|| _        t        j                  | _
        |	| _        |
| _        t        j                  ||f|||d|| _        |r ||fi || _        y t        j"                         | _        y )NdevicedtypeF)kernel_sizestrider   )super__init__r   r   _init_img_sizer   	grid_sizenum_patchesr   r   r   NCHWr   r   r	   Conv2dprojIdentitynorm)selfr   r   r   r   r   r   r   r   r   r   r   r   dd	__class__s                 b/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/timm/layers/patch_embed.pyr#   zPatchEmbed.__init__    s     /#J/:>:M:Mh:W7t~t'7! DL$Z0DO #DL$kkDO..IIh	nzR\cgnkmn	3=Jy/B/	2;;=	    c                     | j                   sJ |yt        |      }t        t        || j                         D cg c]
  \  }}||z   c}}      }|d   |d   z  }|||fS c c}}w )N)NNNr   r
   )r   r   tuplezip)r,   r   spr%   r&   s         r/   r$   zPatchEmbed._init_img_sizeA   sn    #X&c(DOO.LMda16MN	lYq\1K// Ns   A"
c           
      n   d }|t        |      }|Q|| j                  k7  rAt        j                         5  t	        j
                  | j                  j                  | j                  j                  ||| j                  j                  d u| j                  j                  j                  | j                  j                  j                        }|j                  j                  t        | j                  j                  |d             | j                  j                  /|j                  j                  | j                  j                         || _        d d d        || _        |xs | j                  }|| j                  k7  s|%| j!                  |      \  | _        | _        | _        y y # 1 sw Y   WxY w)N)r    r!   r   r   r   T)verbose)r   r   torchno_gradr	   r(   r)   in_channelsout_channelsr   weightr   r   copy_resample_patch_embedr   r$   r%   r&   )r,   r   r   new_patch_sizenew_projs        r/   set_input_sizezPatchEmbed.set_input_sizeJ   sQ   
 !&z2N%.DOO*K %99II))II** .)t399++22))**00 %%&:499;K;K^ei&jk99>>-MM''		7$	% -DO,t}}t}}$(B>B>Q>QRZ>[;DM4>4+; )C!% %s   DF++F4returnc                 H    |rt        | j                        S | j                  S N)maxr   )r,   	as_scalars     r/   
feat_ratiozPatchEmbed.feat_ratiof   s    t''??"r0   c                    | j                   rPt        j                  |d   | j                  d   z        t        j                  |d   | j                  d   z        fS |d   | j                  d   z  |d   | j                  d   z  fS )z Get grid (feature) size for given image size taking account of dynamic padding.
        NOTE: must be torchscript compatible so using fixed tuple indexing
        r   r
   )r   mathceilr   )r,   r   s     r/   dynamic_feat_sizezPatchEmbed.dynamic_feat_sizel   s     99Xa[4??1+==>		(ST+X\XgXghiXjJj@kkkA;$//!"44hqkT__UVEW6WWWr0   c                    |j                   \  }}}}| j                  | j                  rat        || j                  d   k(  d| d| j                  d    d       t        || j                  d   k(  d| d| j                  d    d       nr| j                  sft        || j
                  d   z  dk(  d| d| j
                  d    d       t        || j
                  d   z  dk(  d| d| j
                  d    d       | j                  r~| j
                  d   || j
                  d   z  z
  | j
                  d   z  }| j
                  d   || j
                  d   z  z
  | j
                  d   z  }t        j                  |d|d|f      }| j                  |      }| j                  r"|j                  d      j                  dd      }n3| j                  t        j                  k7  rt        || j                        }| j                  |      }|S )	Nr   zInput height (z) doesn't match model ().r
   zInput width (z%) should be divisible by patch size (   )shaper   r   r   r   r   Fpadr)   r   	transposer   r   r'   r   r+   )r,   xBCHWpad_hpad_ws           r/   forwardzPatchEmbed.forwardu   s   WW
1a==$##T]]1--sBYZ^ZgZghiZjYkkm/noT]]1--qcAXY]YfYfghYiXjjl/mn))**a/$QC'LT__]^M_L``bc **a/#A3&KDOO\]L^K__ab __Q'!dooa.@*@@DOOTUDVVE__Q'!dooa.@*@@DOOTUDVVEa!UAu-.AIIaL<<		!&&q!,A__+4??+AIIaLr0   )            NTNTTFNN)NN)T)__name__
__module____qualname____doc__r   __annotations__r8   jitFinalboolr   r   intr   r   strr#   r$   rA   rG   rK   rZ   __classcell__r.   s   @r/   r   r      s   YY__T** ?B  -1 (,$($)QuS%S/%9:;Q Q 	Q
 Q !*Q Q !Q Q "Q "QB0uS%S/-A'B 0 ?C@D\uS%S/%9:;\ !sE#s(O';!<=\8#E%S/32F,G #X%S/ XeCHo Xr0   r   c                        e Zd ZU dZeed<   	 	 	 	 	 	 	 	 	 	 ddeeee	eef   f      dedededee
   dedee   d	ef fd
Zde	ej                  ee   f   fdZ xZS )PatchEmbedWithSizer   r   r   r   r   r   r   r   r   c                 8    t         |   |||||||||	|

       y )N)
r   r   r   r   r   r   r   r   r   r   )r"   r#   )r,   r   r   r   r   r   r   r   r   r   r   r.   s              r/   r#   zPatchEmbedWithSize.__init__   s5     	!!! 	 	
r0   rB   c                 4   |j                   \  }}}}| j                  ft        || j                  d   z  dk(  d| d| j                  d    d       t        || j                  d   z  dk(  d| d| j                  d    d       | j	                  |      }|j                   dd  }| j
                  r"|j                  d      j                  dd      }n3| j                  t        j                  k7  rt        || j                        }| j                  |      }||fS )	Nr   zInput image height (z#) must be divisible by patch size (rM   r
   zInput image width (rN   )rO   r   r   r   r)   r   rR   r   r   r'   r   r+   )r,   rS   rT   rU   rV   rW   	feat_sizes          r/   rZ   zPatchEmbedWithSize.forward   s+   WW
1a==$A**a/3GsJmnrn}n}~  oA  nB  BD  2E  FA**a/3FqcIlmqm|m|}~m  mA  AC  2D  EIIaLGGBCL	<<		!&&q!,A__+4??+AIIaL)|r0   )
r[   r\   r]   r^   NTNTNN)r_   r`   ra   rb   r   rc   r   r   rg   r   r   rf   rh   r#   r8   Tensorr   rZ   ri   rj   s   @r/   rl   rl      s     ?B  -1 (,
uS%S/%9:;
 
 	

 
 !*
 
 !
 
4E%,,S	"9: r0   rl   new_sizeinterpolation	antialiasr7   c           	         ddl 	 ddlm} t        | j                        dk(  sJ d       t              dk(  sJ d       | j                  dd }t        |      t              k(  r| S |r)t        j                  d	| j                   d
 d d       fdfd} ||      }t        j                  j                  j                  |j                        | j                        fd}	 | ||	dd      dd      }
| j                  }| j!                         }  |
|       } | j#                  |      } | S # t        $ r
 ddlm} Y Aw xY w)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)vmap   zFour dimensions expectedrN   zNew shape should only be hwro   zResize patch embedding z to z, w/ z interpolation.c                     t        j                  |       d   }t        j                  ||      d   j	                         }|S )N)NN.)sizemodert   )r   r   .)r8   rq   rP   interpolatenumpy)x_np	_new_sizex_tfx_upsampledrt   rs   s       r/   resizez(resample_patch_embed_old.<locals>.resize   sI    ||D!/2mmy}	KKTVV[V[V] 	r0   c                    g }t        j                  |             D ]O  }j                  |       }d|j                  ||       <   |j	                   ||      j                  d             Q j                  |      j                  S )Ng      ?)rangeprodzerosunravel_indexappendreshapestackT)	_old_sizer~   mati	basis_vecnpr   s        r/   get_resize_matz0resample_patch_embed_old.<locals>.get_resize_mat   s~    rwwy)* 	AA+I8:Ib&&q)45JJvi3;;B?@	A xx}r0   )r   c                 N    | j                  d      z  }|j                        S )Nr   )r   )kernelresampled_kernelrr   resize_mat_pinvs     r/   resample_kernelz1resample_patch_embed_old.<locals>.resample_kernel   s(    *V^^B-??''11r0   r
   )r|   r8   rv   ImportError	functorchlenrO   r2   _loggerinfotensorlinalgpinvr   r   r   floatto)patch_embedrr   rs   rt   r7   rv   old_sizer   
resize_matr   v_resample_kernel
orig_dtyper   r   r   s    ```        @@@r/   resample_patch_embed_oldr      sM   4 # {  !Q&B(BB&x=A<<<  %HX%/).{/@/@.AhZuUbTccrst  (3Jll299>>*,,#?HZHZ[O2 T/1a8!Q?""J##%K#K0K..,KM  #""#s   E EEr   r   r   rB   c                    | \  }}|\  }}	||z  }
||	z  }t        j                  |
||      }|j                  |
d||      }t        j                  ||||d      }|j                  d      j                  ddd      j                  ||
      }|S )zKComputes the resize matrix basis vectors and interpolates them to new_size.r   r
   F)ry   rz   rt   align_cornersrN   r   )r8   eyer   rP   r{   squeezepermute)r   rr   rs   rt   r   r   old_hold_wnew_hnew_w	old_total	new_total
eye_matrixbasis_vectors_batchresized_basis_vectors_batchresize_matrixs                   r/   _compute_resize_matrixr   
  s     LE5LE5II9V5AJ$,,Y5%H"#--# 077:BB1aKSST]_hiMr0   r   pinv_matrixnew_size_tupler   intermediate_dtypec                     | j                   ^}}}| j                  ||d      j                  |      } |j                  |      }| |z  } |j                  ||g| j                  |      }|S )zW Simplified resampling w/o vmap use.
    As proposed by https://github.com/stas-sl
    r   )r   )rO   r   r   )	r   r   r   r   r   c_outc_in_resampled_patch_embeds	            r/   _apply_resamplingr   %  s     "''OE4!%%eT2699@R9SK..'9.:K'+59199%WWZZakZl  r0   c                 ~   t        | j                        dk(  sJ d       t        |      dk(  sJ d       t        | j                  dd       }t        |      }||k(  r| S | j                  }| j                  }t        |||||t              }	t        j                  j                  |	      }
t        | |
||t              }|S )z5 Standalone function (computes matrix on each call). rw   z/Input tensor should be 4D (out_ch, in_ch, h, w)rN   z+New shape should only be hw (height, width)ro   N)r   rO   r2   r   r   r   DTYPE_INTERMEDIATEr8   r   r   r   )r   rr   rs   rt   r7   old_size_tupler   r   r   r   r   r   s               r/   r>   r>   7  s     {  !Q&Y(YY&x=ALLL&+K,=,=bc,B&CN&+HoN'F""J'y&J\J ,,##J/K-[.*>P ! r0   c            	            e Zd ZdZ	 	 ddeeef   dedef fdZe	fdeeef   de
j                  de
j                  d	e
j                  fd
Zde
j                  dee   d	e
j                  fdZ xZS ) PatchEmbedResamplerFixedOrigSizez
    Resample patch embedding weights from a fixed original size,
    caching the pseudoinverse matrix based on the target size.
    	orig_sizers   rt   c                     t         |           t        |t              rt	        |      dk(  sJ d       || _        || _        || _        i | _        y)z
        Args:
            orig_size (Tuple[int, int]): The expected original (height, width) of input patch_embed tensors.
            interpolation (str): Interpolation mode.
            antialias (bool): Use anti-aliasing filter in resize.
        rN   z.`orig_size` must be a tuple of (height, width)N)	r"   r#   
isinstancer2   r   r   rs   rt   _pinv_cache_map)r,   r   rs   rt   r.   s       r/   r#   z)PatchEmbedResamplerFixedOrigSize.__init__Z  sS     	)U+I!0C 	=<	=C"*";=r0   rr   r   r   rB   c                    |}| j                   j                  |      }|r8t        | |      r,t        | |      }|j                  |k(  r|j
                  |k(  r|S t        | j                  || j                  | j                  ||      }t        j                  j                  |      }d|d    d|d    }t        | |      rt        | |       | j                  ||       || j                   |<   |S )zRRetrieves the cached pinv matrix or computes and caches it for the given new_size.pinv_r   rS   r
   )r   gethasattrgetattrr   r   r   r   rs   rt   r8   r   r   delattrregister_buffer)r,   rr   r   r   	cache_keybuffer_namer   r   s           r/   _get_or_create_pinv_matrixz;PatchEmbedResamplerFixedOrigSize._get_or_create_pinv_matrixo  s     	**..y9745!$4K!!V+0A0AU0J## ,NNHd&8&8$..&RW

 ll''
3 hqk]!HQK=94%T;'[+6*5Y'r0   r   c                 ~   t        |j                        dk(  sJ t        |      dk(  sJ t        |j                  dd       }|| j                  k(  sJ d| d| j                          t        |      }| j                  |k(  r|S |j                  }|j
                  }| j                  ||      }t        ||||      }|S )a   Resamples the patch embedding weights to new_size.

        Args:
            patch_embed (torch.Tensor): Original weights (out_ch, in_ch, H_orig, W_orig).
            new_size (List[int]): Target [height, width].

        Returns:
            torch.Tensor: Resampled weights.
        rw   rN   ro   NzInput patch_embed spatial size z0 does not match module's expected original size )r   rO   r2   r   r   r   r   r   )	r,   r   rr   
input_sizer   r   r   r   r   s	            r/   rZ   z(PatchEmbedResamplerFixedOrigSize.forward  s     ;$$%***8}!!! ;,,RS12
T^^+ 	@-j\ ://3~~.>@	@+ +0/ >>^+## &&
 55nfM !2+{N\f g$$r0   )bicubicT)r_   r`   ra   rb   r   rg   rh   rf   r#   r   r8   r   r   rq   r   r   rZ   ri   rj   s   @r/   r   r   U  s     "+"	>S#X> > 	>2 "4	CHo LL ;;	
 
<"%5<< "%49 "% "%r0   r   c                   l    e Zd ZdZ	 	 	 	 	 ddeeef   dededededef fdZd	e	j                  d
eeef   de	j                  fdZd	e	j                  d
eeef   de	j                  fdZ	 	 	 dde	j                  de	j                  dee	j                     deeeef      dede	j                  fdZ xZS )PatchEmbedInterpolatora  Dynamically interpolates patch embedding weights for variable patch sizes.

    This module wraps patch embedding weight resampling functionality to support
    on-the-fly patch size variation during training. It handles both Conv2d and
    Linear patch embeddings.

    Args:
        base_patch_size: The original patch size the model was initialized with
        in_chans: Number of input channels
        embed_dim: Embedding dimension
        interpolation: Interpolation mode for resampling
        antialias: Whether to use antialiasing during interpolation
        channels_last: Per-patch flat layout of the linear weight / patches:
            True -> (ph, pw, C) [NaFlex default], False -> (C, ph, pw).
    base_patch_sizer   r   rs   rt   channels_lastc                 v    t         |           || _        || _        || _        || _        || _        || _        y rD   )r"   r#   r   r   r   rs   rt   r   )r,   r   r   r   rs   rt   r   r.   s          r/   r#   zPatchEmbedInterpolator.__init__  s=     	. "*"*r0   r<   target_patch_sizerB   c                    || j                   k(  r|S |j                  d   }| j                   \  }}|\  }}| j                  r1|j                  |||| j                        j                  dddd      }n|j                  || j                  ||      }t        |||g| j                  | j                  d      }	| j                  r&|	j                  dddd      j                  |d      }
|
S |	j                  |d      }
|
S )a/  Resample linear patch embedding weights for a new patch size.

        Args:
            weight: Linear weight tensor of shape [embed_dim, patch_h * patch_w * in_chans]
            target_patch_size: Target (patch_h, patch_w) to resample to

        Returns:
            Resampled weight tensor
        r   r]   r
   rN   Frr   rs   rt   r7   r   )	r   rO   r   r   r   r   r>   rs   rt   )r,   r<   r   r   base_phbase_pw	target_ph	target_pwweight_convweight_conv_resampledweight_resampleds              r/   resample_linear_weightz-PatchEmbedInterpolator.resample_linear_weight  s     4 44MLLO	//0	9  ..GWdmmT\\]^`acdfghK ..DMM7GTK !5+,,nn!
 4<<Q1aHPPQZ\^_    5<<YKr0   c                     || j                   k(  r|S t        |t        |      | j                  | j                  d      }|S )a-  Resample conv2d patch embedding weights for a new patch size.

        Args:
            weight: Conv2d weight tensor of shape [embed_dim, in_chans, patch_h, patch_w]
            target_patch_size: Target (patch_h, patch_w) to resample to

        Returns:
            Resampled weight tensor
        Fr   )r   r>   listrs   rt   )r,   r<   r   r   s       r/   resample_conv_weightz+PatchEmbedInterpolator.resample_conv_weight  sK      4 44M 0+,,,nn
  r0   patchesproj_weight	proj_biasr   	is_linearc                    || j                   }|r|| j                   k7  rz|j                  dk(  sJ d       |j                  dd \  }}| j                  ||      }|j	                  ||d      }	t
        j                  j                  j                  |	||      }
|
S |j                  dk(  r-|j	                  |j                  d   |j                  d   d      }t
        j                  j                  j                  |||      }
|
S || j                   k7  rB| j                  ||      }t
        j                  j                  j                  ||||d      }
|
S t
        j                  j                  j                  ||||d      }
|
S )	aW  Apply patch embedding with dynamic weight resampling.

        Args:
            patches: Input patches
                - For linear mode with resampling: [B, N, Ph, Pw, C]
                - For linear mode without resampling: [B, N, Ph*Pw*C]
                - For conv mode: [B, C, H, W]
            proj_weight: Original projection weight
            proj_bias: Optional projection bias
            patch_size: Current patch size (if None, uses base_patch_size)
            is_linear: Whether using linear (True) or conv2d (False) projection

        Returns:
            Embedded patches
        N   zKPatches must be 5-D ([B, N, Ph, Pw, C] or [B, N, C, Ph, Pw]) for resamplingrN   r   r   r
   )r!   padding)r   ndimrO   r   r   r8   r	   
functionallinearr   conv2d)r,   r   r   r   r   r   rT   Nr   patches_flatoutputs              r/   rZ   zPatchEmbedInterpolator.forward  s   . --JT111 ||q( bab(}}Ra(1 $(#>#>{J#W   'q!R8,,33LBRT]^( # <<1$%oogmmA.>a@PRTUG,,33G[)T  T111#'#<#<[*#U ,,33-y%q 4   ,,33[)%q 4 
 r0   )r]   r^   r   TT)NNT)r_   r`   ra   rb   r   rg   rh   rf   r#   r8   rq   r   r   r   rZ   ri   rj   s   @r/   r   r     s0   &  !*""&+"38_+ + 	+
 + +  +"+ LL+   %S#X+  
	+ Z LL   %S#X  
	 @ 1548"<\\< <  -	<
 !sCx1< < 
<r0   r   )r   TF)*rb   loggingrI   typingr   r   r   r   r   r   r8   r	   torch.nn.functionalr   rP   formatr   r   helpersr   trace_utilsr   	getLoggerr_   r   Moduler   rl   rg   rh   rf   r   float32r   r   r   rq   r   r   r>   r   r    r0   r/   <module>r     s  	   ? ?     #   
'

H
%t tn, ,f 'Cs)C C 	C
 CL ]]  0S/S/  	
  {{ \\@ +=!\\!\\! c3h! KK	!
 "KK! \\!* '!\\!s)! ! 	!
 !<Z%ryy Z%zgRYY gr0   