
    |2g                     d    d dl mZmZmZmZ d dlmZ d dlmZ d Z	 G d dej                        Zy)    )CallableOptionalTupleUnion)TensorNc                 r    t        | t              rt        |       dk(  sJ | S t        | t              sJ | | fS )N   )
isinstancetuplelenint)xs    O/home/cameronsmith/repos/FeatUp/featup/featurizers/dinov2/layers/patch_embed.pymake_2tupler      s5    !U1v{aq6M    c                        e Zd ZdZ	 	 	 	 	 	 ddeeeeef   f   deeeeef   f   dededee   de	d	df fd
Z
ded	efdZd	efdZ xZS )
PatchEmbeda%  
    2D image to patch embedding: (B,C,H,W) -> (B,N,D)

    Args:
        img_size: Image size.
        patch_size: Patch token size.
        in_chans: Number of input image channels.
        embed_dim: Number of linear projection output channels.
        norm_layer: Normalization layer.
    Nimg_size
patch_sizein_chans	embed_dim
norm_layerflatten_embeddingreturnc                 |   t         
|           t        |      }t        |      }|d   |d   z  |d   |d   z  f}	|| _        || _        |	| _        |	d   |	d   z  | _        || _        || _        || _	        t        j                  ||||      | _        |r ||      | _        y t        j                         | _        y )Nr      )kernel_sizestride)super__init__r   r   r   patches_resolutionnum_patchesr   r   r   nnConv2dprojIdentitynorm)selfr   r   r   r   r   r   image_HWpatch_HWpatch_grid_size	__class__s             r   r    zPatchEmbed.__init__%   s     	x(z*QK8A;&QK8A;&

 !""1*1-0BB "!2IIh	xPXY	-7Jy)	R[[]	r   r   c                    |j                   \  }}}}| j                  \  }}||z  dk(  sJ d| d|        ||z  dk(  sJ d| d|        | j                  |      }|j                  d      |j                  d      }}|j	                  d      j                  dd      }| j                  |      }| j                  s|j                  d	||| j                        }|S )
Nr   zInput image height z# is not a multiple of patch height zInput image width z# is not a multiple of patch width: r	      r   )
shaper   r%   sizeflatten	transposer'   r   reshaper   )r(   r   _HWpatch_Hpatch_Ws          r   forwardzPatchEmbed.forwardD   s    WW
1a??7{af#6qc9\]d\e!ff7{ae#5aS8[\c[d!eeIIaLvvay!&&)1IIaL""1a(IIaL%%		"aDNN3Ar   c                     | j                   \  }}||z  | j                  z  | j                  z  | j                  d   | j                  d   z  z  }| j                  |||z  | j                  z  z  }|S )Nr   r   )r!   r   r   r   r'   )r(   HoWoflopss       r   r>   zPatchEmbed.flopsS   sr    ((BR$..(4==8DOOA<NQUQ`Q`abQc<cd99 R"Wt~~--Er   )      r.   i   NT)__name__
__module____qualname____doc__r   r   r   r   r   boolr    r   r:   floatr>   __classcell__)r,   s   @r   r   r      s    	 1424)-"&KU38_,-K #uS#X./K 	K
 K X&K  K 
K> F u r   r   )typingr   r   r   r   torchr   torch.nnr#   r   Moduler    r   r   <module>rM      s(    4 3  ? ?r   