
    ^j                        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ZmZmZ ddlmZmZ ddlmZ ddlmZ dd	lmZmZmZmZ dd
lmZ ddlm Z  ddl!m"Z"m#Z#m$Z$m%Z%m&Z&  e$jN                  e(      Z)dee*   de*de*dee*   de	ee*   ejV                  f   f
dZ,deee-      dee
ee*   e	e*df   f      dee-   de	ee-   ee*   f   fdZ.deee-      dee
ee*   e	e*df   f      dee-   de	ee-   ee*   f   fdZ/dZ0 G d dee      Z1 G d dejd                        Z3 G d dejd                        Z4 G d d ejd                        Z5 G d! d"e5      Z6 G d# d$ejd                        Z7 G d% d&ejd                        Z8 G d' d(e8      Z9 G d) d*ejd                        Z:dId+ejv                  d,e<d-e=dejv                  fd.Z> G d/ d0ejd                        Z? G d1 d2ejd                        Z@ G d3 d4ejd                        ZAe8e9d5ZB G d6 d7ejd                        ZC G d8 d9ejd                        ZD G d: d;e      ZEd<ZFd=ZG e"d>eF       G d? d@eE             ZHdAZI e"dBeF       G dC dDeE             ZJ e"dEeF       G dF dGeEe             ZKg dHZLy)Ja  DINOv2-with-Registers backbone with windowed self-attention.

This module is a local copy of the HuggingFace Transformers DINOv2-with-Registers implementation, extended with windowed
attention support for RF-DETR.  It targets the transformers v5 API (``transformers>=5.0.0``).

Transformers v5 API changes vs v4
----------------------------------
``head_mask`` removed:
    The ``head_mask`` parameter that appeared on every ``forward()`` in v4 has been
    dropped in v5.  It defaulted to ``None`` throughout the call chain and callers universally passed ``None``, so
    removing it produces **identical numerics**. Permanent head pruning is still available via ``model._prune_heads()``.

``BackboneMixin._init_transformers_backbone`` signature:
    In v4 this method accepted ``(self, config)``.  In v5 it accepts only ``(self)``;
    the config is accessed via ``self.config`` internally.

Helper functions copied locally:
    ``get_aligned_output_features_output_indices`` and ``find_pruneable_heads_and_indices`` were removed
    from the transformers v5 public API.  Private copies (``_get_aligned_output_features_output_indices``
    and ``_find_pruneable_heads_and_indices``) are kept in this module.
    N)DictListOptionalSetTupleUnion)nn)BCEWithLogitsLossCrossEntropyLossMSELoss)BackboneConfigMixinBackboneMixin)ACT2FN)PretrainedConfig)BackboneOutputBaseModelOutputBaseModelOutputWithPoolingImageClassifierOutput)PreTrainedModel)prune_linear_layer)add_start_docstrings%add_start_docstrings_to_model_forwardloggingreplace_return_docstrings	torch_intheadsn_heads	head_sizealready_pruned_headsreturnc                 T   t        j                  ||      }t        |       |z
  } | D ]  t        fd|D              z  d|<     |j	                  d      j                         j                  d      }t        j                  t        |            |   j                         }| |fS )al  Return the set of pruneable heads and their index mask for weight pruning.

    Copied from transformers.pytorch_utils.find_pruneable_heads_and_indices (removed from public API in transformers
    v5.0).
    Source: https://github.com/huggingface/transformers/blob/v4.49.0/src/transformers/pytorch_utils.py#L127
    MAINTENANCE: if this function is moved to another module or deleted, update the
    "Copyright 2022 The HuggingFace Team" line in the file header accordingly.

    Args:
        heads: Indices of heads to prune.
        n_heads: Total number of heads in the layer.
        head_size: Size of each attention head.
        already_pruned_heads: Heads that have already been pruned.

    Returns:
        A tuple of (heads, index) where heads is the adjusted set of head indices and index is a LongTensor boolean mask
        selecting the remaining weights.
    c              3   0   K   | ]  }|k  rd nd  yw)   r   N ).0hheads     {/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/rfdetr/models/backbone/dinov2_with_windowed_attn.py	<genexpr>z4_find_pruneable_heads_and_indices.<locals>.<genexpr>W   s     GQTAq(Gs   r   r#   )
torchonessetsumview
contiguouseqarangelenlong)r   r   r   r   maskindexr'   s         @r(   !_find_pruneable_heads_and_indicesr7   ?   s    * ::gy)DJ--E G2FGGGT
 99R=##%((+DLLT#D)..0E%<    out_featuresout_indices.stage_namesc                     || t        |      dz
  g}|d   g} | |fS |$| "| D cg c]  }|j                  |       }}| |fS | ||D cg c]  }||   	 } }| |fS c c}w c c}w )Nr#   r*   )r3   r6   )r9   r:   r;   layeridxs        r(   %_align_output_features_output_indicesr?   ^   s    
 |3;'!+,#B(
 $$	 
	!9=IJE{((/JJ $$ 
	+"94?@SC(@@$$ K@s   AA#c                 J    |t        |      nd}t        | ||      \  } }| |fS )a  Align out_features and out_indices against stage_names, filling in defaults when either is None.

    Copied from transformers.utils.backbone_utils.get_aligned_output_features_output_indices (removed from public API in
    transformers v5.0).
    Source: https://github.com/huggingface/transformers/blob/v4.49.0/src/transformers/utils/backbone_utils.py#L30
    MAINTENANCE: if this function is moved to another module or deleted, update the
    "Copyright 2023 The HuggingFace Inc. team" line in the file header accordingly.

    Args:
        out_features: Names of the backbone stages to return features from, or None to derive from out_indices.
        out_indices: Integer indices of the stages to return features from, or None to derive from out_features.
        stage_names: Ordered list of all stage names defined by the backbone config.

    Returns:
        A tuple of (out_features, out_indices) with both fields populated consistently.
    Nr9   r:   r;   )listr?   rA   s      r(   +_get_aligned_output_features_output_indicesrC   m   s8    * (3'>${#DK E!{!L+ $$r8   !WindowedDinov2WithRegistersConfigc                   X     e Zd ZdZdZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d fd	Z xZS )rD   aS  
    This is the configuration class to store the configuration of a [`Dinov2WithRegistersModel`].
    It is used to instantiate a Dinov2WithRegisters model according to the specified arguments,
    defining the model architecture. Instantiating a configuration with the defaults will yield a
    similar configuration to that of the DINOv2 with Registers
    [facebook/dinov2-with-registers-base](https://huggingface.co/facebook/dinov2-with-registers-base) architecture.

    Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the
    documentation from [`PretrainedConfig`] for more information.

    Args:
        hidden_size (`int`, *optional*, defaults to 768):
            Dimensionality of the encoder layers and the pooler layer.
        num_hidden_layers (`int`, *optional*, defaults to 12):
            Number of hidden layers in the Transformer encoder.
        num_attention_heads (`int`, *optional*, defaults to 12):
            Number of attention heads for each attention layer in the Transformer encoder.
        mlp_ratio (`int`, *optional*, defaults to 4):
            Ratio of the hidden size of the MLPs relative to the `hidden_size`.
        hidden_act (`str` or `function`, *optional*, defaults to `"gelu"`):
            The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`,
            `"relu"`, `"selu"` and `"gelu_new"` are supported.
        hidden_dropout_prob (`float`, *optional*, defaults to 0.0):
            The dropout probability for all fully connected layers in the embeddings, encoder, and pooler.
        attention_probs_dropout_prob (`float`, *optional*, defaults to 0.0):
            The dropout ratio for the attention probabilities.
        initializer_range (`float`, *optional*, defaults to 0.02):
            The standard deviation of the truncated_normal_initializer for initializing all weight matrices.
        layer_norm_eps (`float`, *optional*, defaults to 1e-06):
            The epsilon used by the layer normalization layers.
        image_size (`int`, *optional*, defaults to 224):
            The size (resolution) of each image.
        patch_size (`int`, *optional*, defaults to 16):
            The size (resolution) of each patch.
        num_channels (`int`, *optional*, defaults to 3):
            The number of input channels.
        qkv_bias (`bool`, *optional*, defaults to `True`):
            Whether to add a bias to the queries, keys and values.
        layerscale_value (`float`, *optional*, defaults to 1.0):
           Initial value to use for layer scale.
        drop_path_rate (`float`, *optional*, defaults to 0.0):
            Stochastic depth rate per sample (when applied in the main path of residual layers).
        use_swiglu_ffn (`bool`, *optional*, defaults to `False`):
            Whether to use the SwiGLU feedforward neural network.
        num_register_tokens (`int`, *optional*, defaults to 4):
            Number of register tokens to use.
        out_features (`List[str]`, *optional*):
            If used as backbone, list of features to output. Can be any of `"stem"`, `"stage1"`, `"stage2"`, etc.
            (depending on how many stages the model has). If unset and `out_indices` is set, will default to the
            corresponding stages. If unset and `out_indices` is unset, will default to the last stage. Must be in the
            same order as defined in the `stage_names` attribute.
        out_indices (`List[int]`, *optional*):
            If used as backbone, list of indices of features to output. Can be any of 0, 1, 2, etc. (depending on how
            many stages the model has). If unset and `out_features` is set, will default to the corresponding stages.
            If unset and `out_features` is unset, will default to the last stage. Must be in the
            same order as defined in the `stage_names` attribute.
        apply_layernorm (`bool`, *optional*, defaults to `True`):
            Whether to apply layer normalization to the feature maps in case the model is used as backbone.
        reshape_hidden_states (`bool`, *optional*, defaults to `True`):
            Whether to reshape the feature maps to 4D tensors of shape `(batch_size, hidden_size, height, width)` in
            case the model is used as backbone. If `False`, the feature maps will be 3D tensors of shape `(batch_size,
            seq_len, hidden_size)`.

    Example:

    >>> from rfdetr.models.backbone.dinov2_with_windowed_attn import WindowedDinov2WithRegistersConfig

    >>> # Initializing a tiny configuration suitable for doctests
    >>> configuration = WindowedDinov2WithRegistersConfig(
    ...     image_size=32,
    ...     patch_size=16,
    ...     hidden_size=32,
    ...     num_hidden_layers=2,
    ...     num_attention_heads=4,
    ...     num_register_tokens=2,
    ... )

    >>> configuration.hidden_size
    32

    dinov2_with_registersc                 *   t        |   di | || _        || _        || _        || _        || _        || _        || _        || _	        |	| _
        |
| _        || _        || _        || _        || _        || _        || _        || _        dgt'        d|dz         D cg c]  }d| 	 c}z   | _        t+        ||| j(                        \  | _        | _        || _        || _        || _        |t7        t'        |            n|| _        || _        y c c}w )Nstemr#   stagerA   r$   )super__init__hidden_sizenum_hidden_layersnum_attention_heads	mlp_ratio
hidden_acthidden_dropout_probattention_probs_dropout_probinitializer_rangelayer_norm_eps
image_size
patch_sizenum_channelsqkv_biaslayerscale_valuedrop_path_rateuse_swiglu_ffnnum_register_tokensranger;   rC   _out_features_out_indicesapply_layernormreshape_hidden_statesnum_windowsrB   window_block_indexesgradient_checkpointing)selfrL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r9   r:   r`   ra   rb   rc   rd   kwargsr>   	__class__s                              r(   rK   z*WindowedDinov2WithRegistersConfig.__init__   s0   8 	"6"&!2#6 "$#6 ,H)!2,$$(  0,,#6 "8aIZ]^I^@_&`se}&``0[%;DL\L\1
-D-  /%:"&.B.JD()*Pd 	! '=# 'as   D)i      rh      gelu        rk   g{Gz?gư>         T      ?rk   Fri   NNTTr#   NF)__name__
__module____qualname____doc__
model_typerK   __classcell__rg   s   @r(   rD   rD      se    Pd )J %("!$39= 9=r8   c                   Z     e Zd ZdZ fdZdej                  dej                  fdZ xZS )"Dinov2WithRegistersPatchEmbeddingszThis class turns `pixel_values` of shape `(batch_size, num_channels, height, width)` into the initial
    `hidden_states` (patch embeddings) of shape `(batch_size, seq_length, hidden_size)` to be consumed by a
    Transformer.c                    t         |           |j                  |j                  }}|j                  |j
                  }}t        |t        j                  j                        r|n||f}t        |t        j                  j                        r|n||f}|d   |d   z  |d   |d   z  z  }|| _        || _        || _        || _
        t        j                  ||||      | _        y )Nr#   r   )kernel_sizestride)rJ   rK   rU   rV   rW   rL   
isinstancecollectionsabcIterablenum_patchesr	   Conv2d
projection)re   configrU   rV   rW   rL   r   rg   s          r(   rK   z+Dinov2WithRegistersPatchEmbeddings.__init__#  s    !'!2!2F4E4EJ
$*$7$79K9Kk#-j+//:R:R#SZZdfpYq
#-j+//:R:R#SZZdfpYq
!!}
15*Q-:VW=:XY$$(&))L+:^hir8   pixel_valuesr    c                     |j                   d   }|| j                  k7  rt        d| j                   d| d      | j                  |      j	                  d      j                  dd      }|S )Nr#   zoMake sure that the channel dimension of the pixel values match with the one set in the configuration. Expected z	 but got .   )shaperW   
ValueErrorr   flatten	transpose)re   r   rW   
embeddingss       r(   forwardz*Dinov2WithRegistersPatchEmbeddings.forward2  sz    #))!,4,,,!../yaI  __\2::1=GG1M
r8   )	rp   rq   rr   rs   rK   r+   Tensorr   ru   rv   s   @r(   rx   rx     s)    jELL U\\ r8   rx   c                        e Zd ZdZdeddf fdZdej                  dededej                  fd	Z	dd
ej                  de
ej                     dej                  fdZ xZS )%WindowedDinov2WithRegistersEmbeddingszTConstruct the CLS token, mask token, register tokens, position and patch embeddings.r   r    Nc                    t         |           t        j                  t	        j
                  dd|j                              | _        t        j                  t	        j                  d|j                              | _	        |j                  dkD  r>t        j                  t	        j                  d|j                  |j                              nd | _        t        |      | _        | j                  j                  }t        j                  t	        j
                  d|dz   |j                              | _        t        j                   |j"                        | _        |j&                  | _        || _        y )Nr#   r   )rJ   rK   r	   	Parameterr+   randnrL   	cls_tokenzeros
mask_tokenr\   register_tokensrx   patch_embeddingsr   position_embeddingsDropoutrQ   dropoutrV   r   )re   r   r   rg   s      r(   rK   z.WindowedDinov2WithRegistersEmbeddings.__init__@  s   ekk!Q8J8J&KL,,u{{1f6H6H'IJ ))A- LLQ(B(BFDVDVWX 	
 !C6 J++77#%<<A{QPVPbPb0c#d zz&"<"<= ++r8   r   heightwidthc                 n   |j                   d   dz
  }| j                  j                   d   dz
  }t        j                  j	                         s||k(  r||k(  r| j                  S | j                  dddf   }| j                  ddddf   }|j                   d   }|| j
                  j                  z  }|| j
                  j                  z  }t        |dz        }	|j                  d|	|	|      }|j                  dddd      }|j                  }
t        j                  j                  |j                  t        j                        t        |      t        |      fd	d
|j                   j"                  dk7        j                  |
      }t        j                  j	                         sAt%        |      |j                   d   k7  st%        |      |j                   d   k7  rt'        d      |j                  dddd      j)                  dd|      }t        j*                  |j-                  d      |fd      S )a  This method allows to interpolate the pre-trained position encodings, to be able to use the model on higher
        resolution images. This implementation supports torch.jit tracing while maintaining backwards compatibility with
        the original implementation.

        Adapted from:
        - https://github.com/facebookresearch/dino/blob/main/vision_transformer.py
        - https://github.com/facebookresearch/dinov2/blob/main/dinov2/models/vision_transformer.py
        r#   Nr   r*   g      ?rn   r   dtypebicubicFmps)sizemodealign_corners	antialiaszHWidth or height does not match with the interpolated position embeddingsdim)r   r   r+   jit
is_tracingr   rV   r   reshapepermuter   r	   
functionalinterpolatetofloat32devicetypeintr   r/   cat	unsqueeze)re   r   r   r   r   num_positionsclass_pos_embedpatch_pos_embedr   sqrt_num_positionstarget_dtypes              r(   interpolate_pos_encodingz>WindowedDinov2WithRegistersEmbeddings.interpolate_pos_encodingQ  s    !&&q)A-0066q9A= yy##%+*F6UZ?+++ 221a48221ab59r" 4;;111/// '}c'9:)11!5GI[]`a)11!Q1= ',, --33U]]3F#Yu%56%,,11U: 4 
 "<"
  	 yy##%6{o33B773u:I^I^_aIb;b !kll *11!Q1=BB1b#N yy/33A6HaPPr8   r   bool_masked_posc                 N   |j                   \  }}}}| j                  | j                  j                  z  }||z  dk7  s||z  dk7  r9t	        d| j                   d| j                  j                   d| d| d| d      | j
                  j                  j                  j                  }| j                  |j                  |            }	|Xt        j                  |j                  d
      | j                  j                  |	j                        j                  d      |	      }	| j                  j                  |d
d
      }
t        j                   |
|	fd      }	|	| j#                  |	||      z   }	| j                  j                  dkD  r|| j                  j                  z  }|| j                  j                  z  }|	d	d	d	df   }|	d	d	dd	f   }|j%                  |||d
      }|| j                  j                  z  }|| j                  j                  z  }| j                  j                  }|j'                  ||z  |||d
      }|j)                  ddddd      }|j'                  ||dz  z  ||z  d
      }|j+                  |dz  dd      }t        j                   ||fd      }	| j                  j,                  dkD  rTt        j                   |	d	d	d	df   | j.                  j                  |	j                   d   d
d
      |	d	d	dd	f   fd      n|	}	| j1                  |	      }	|	S )a"  Compute windowed patch embeddings for the given pixel values.

        Args:
            pixel_values: Image tensor of shape ``(B, C, H, W)``. Both ``H`` and
                ``W`` must be divisible by ``patch_size * num_windows``.
            bool_masked_pos: Optional boolean mask of shape ``(B, num_patches)``.
                Masked positions are replaced with the learnable ``mask_token``.

        Returns:
            Patch embedding tensor. When ``num_windows > 1`` the batch dimension is expanded to ``B * num_windows ** 2``
            and the sequence length corresponds to patches within a single window (plus CLS token and any register
            tokens).

        Raises:
            ValueError: If ``H`` or ``W`` is not divisible by
                ``patch_size * num_windows``.
        r   zHInput spatial dimensions must be divisible by patch_size * num_windows (z * z = z), but got height=z, width=r   r   Nr*   r#   r   r   rn   ri   )r   rV   r   rb   r   r   r   weightr   r   r+   wherer   r   r   expandr   r   r/   r   r   repeatr\   r   r   )re   r   r   
batch_size_r   r   divisorr   r   
cls_tokensnum_h_patchesnum_w_patchescls_token_with_pos_embedpixel_tokens_with_pos_embednum_w_patches_per_windownum_h_patches_per_windowrb   windowed_pixel_tokens!windowed_cls_token_with_pos_embeds                       r(   r   z-WindowedDinov2WithRegistersEmbeddings.forward  sA   $ (4'9'9$
Avu//DKK$;$;;Gq EGOq$8OO$C(?(?'@G9 M""(%; 
 ,,77>>DD**<???+NO
&))"-t/A/A*BRBR/S/]/]^_/`blJ
 ^^**:r2>
YY
J7Q?
  $"?"?
FTY"ZZ
;;""Q&"dkk&<&<<M!T[[%;%;;M'1!RaR%'8$*4QU*;'*E*J*J:Wdfsuw*x''48O8O'O$'48O8O'O$++11K$?$G$G[(*BKQikm%! %:$A$A!Q1a$P!$9$A$A[!^+-EH`-`bd%! 1I0O0OP[]^P^`acd0e-$EG\#]cdeJ {{..2 IIArrE"D$8$8$?$?
@P@PQR@SUWY[$\^hijlmlnin^opvw  	 \\*-
r8   N)rp   rq   rr   rs   rD   rK   r+   r   r   r   r   r   ru   rv   s   @r(   r   r   =  s    ^@ T "3Q5<< 3Q 3QUX 3Q]b]i]i 3QjHELL H8ELLCY Hejeqeq Hr8   r   c            
            e Zd Zdeddf fdZdej                  dej                  fdZ	 d
dej                  dede	e
ej                  ej                  f   e
ej                     f   fd	Z xZS ) Dinov2WithRegistersSelfAttentionr   r    Nc                    t         |           |j                  |j                  z  dk7  r3t	        |d      s't        d|j                  f d|j                   d      |j                  | _        t        |j                  |j                  z        | _        | j                  | j                  z  | _        t        j                  |j                  | j                  |j                        | _        t        j                  |j                  | j                  |j                        | _        t        j                  |j                  | j                  |j                        | _        t        j                  |j                         | _        y )Nr   embedding_sizezThe hidden size z4 is not a multiple of the number of attention heads r   bias)rJ   rK   rL   rN   hasattrr   r   attention_head_sizeall_head_sizer	   LinearrX   querykeyvaluer   rR   r   re   r   rg   s     r(   rK   z)Dinov2WithRegistersSelfAttention.__init__  s1    : ::a?PVXhHi"F$6$6#8"9 :334A7 
 $*#=#= #&v'9'9F<V<V'V#W !558P8PPYYv1143E3EFOO\
99V//1C1C&//ZYYv1143E3EFOO\
zz&"E"EFr8   xc                     |j                         d d | j                  | j                  fz   }|j                  |      }|j	                  dddd      S )Nr*   r   r   r#   rn   )r   rN   r   r/   r   )re   r   new_x_shapes      r(   transpose_for_scoresz5Dinov2WithRegistersSelfAttention.transpose_for_scores  sL    ffhsmt'?'?AYAY&ZZFF;yyAq!$$r8   hidden_statesoutput_attentionsc                    | j                  |      }| j                  | j                  |            }| j                  | j                  |            }| j                  |      }t	        j
                  ||j                  dd            }|t        j                  | j                        z  }t        j                  j                  |d      }| j                  |      }t	        j
                  ||      }	|	j                  dddd      j                         }	|	j!                         d d | j"                  fz   }
|	j%                  |
      }	|r|	|f}|S |	f}|S )Nr*   r   r   r   r   r#   rn   )r   r   r   r   r+   matmulr   mathsqrtr   r	   r   softmaxr   r   r0   r   r   r/   )re   r   r   mixed_query_layer	key_layervalue_layerquery_layerattention_scoresattention_probscontext_layernew_context_layer_shapeoutputss               r(   r   z(Dinov2WithRegistersSelfAttention.forward  sB    !JJ}5--dhh}.EF	//

=0IJ//0AB !<<Y5H5HR5PQ+dii8P8P.QQ --//0@b/I ,,7_kB%--aAq9DDF"/"4"4"6s";t?Q?Q>S"S%**+BC6G=/2 O\M]r8   F)rp   rq   rr   rD   rK   r+   r   r   boolr   r   r   ru   rv   s   @r(   r   r     s    G@ GT G$%ell %u|| % FK!"\\!>B!	uU\\5<</0%2EE	F!r8   r   c            
            e Zd Zdeddf fdZ	 ddej                  dedee	ej                  ej                  f   e	ej                     f   f fdZ
 xZS )	$Dinov2WithRegistersSdpaSelfAttentionr   r    Nc                 F    t         |   |       |j                  | _        y r   )rJ   rK   rR   r   s     r(   rK   z-Dinov2WithRegistersSdpaSelfAttention.__init__  s     ,2,O,O)r8   r   r   c           	      X   |r&t         j                  d       t        	|   ||      S | j	                  |      }| j                  | j                  |            }| j                  | j                  |            }| j                  |      }t        j                  j                  j                  |||d | j                  r| j                  nddd       }|j                  dddd	      j                         }|j!                         d d
 | j"                  fz   }|j%                  |      }|d fS )Nah  Dinov2WithRegistersModel is using Dinov2WithRegistersSdpaSelfAttention, but `torch.nn.functional.scaled_dot_product_attention` does not support `output_attentions=True`. Falling back to the manual attention implementation. To avoid this fallback, call `model.set_attn_implementation('eager')` or pass `attn_implementation="eager"` when instantiating the model.)r   r   rk   F)	is_causalscaler   r   r#   rn   r   )loggerwarning_oncerJ   r   r   r   r   r   r+   r	   r   scaled_dot_product_attentiontrainingrR   r   r0   r   r   r/   )
re   r   r   r   r   r   r   r   r   rg   s
            r(   r   z,Dinov2WithRegistersSdpaSelfAttention.forward  s(    V 7?Rc?dd JJ}5--dhh}.EF	//

=0IJ//0AB++HH15D--C I 
 &--aAq9DDF"/"4"4"6s";t?Q?Q>S"S%**+BCd""r8   r   )rp   rq   rr   rD   rK   r+   r   r   r   r   r   ru   rv   s   @r(   r   r     sl    P@ PT P
 FK!#"\\!#>B!#	uU\\5<</0%2EE	F!# !#r8   r   c                   |     e Zd ZdZdeddf fdZdej                  dej                  dej                  fdZ xZ	S )	Dinov2WithRegistersSelfOutputzThe residual connection is defined in Dinov2WithRegistersLayer instead of here (as is the case with other
    models), due to the layernorm applied before each block.r   r    Nc                     t         |           t        j                  |j                  |j                        | _        t        j                  |j                        | _        y r   )	rJ   rK   r	   r   rL   denser   rQ   r   r   s     r(   rK   z&Dinov2WithRegistersSelfOutput.__init__:  sB    YYv1163E3EF
zz&"<"<=r8   r   input_tensorc                 J    | j                  |      }| j                  |      }|S r   )r  r   )re   r   r  s      r(   r   z%Dinov2WithRegistersSelfOutput.forward?  s$    

=1]3r8   )
rp   rq   rr   rs   rD   rK   r+   r   r   ru   rv   s   @r(   r   r   6  sF    @>@ >T >
U\\  RWR^R^ r8   r   c            
            e Zd Zdeddf fdZdee   ddfdZ	 d
dej                  de
deeej                  ej                  f   eej                     f   fd	Z xZS )Dinov2WithRegistersAttentionr   r    Nc                     t         |           t        |      | _        t	        |      | _        t               | _        y r   )rJ   rK   r   	attentionr   outputr-   pruned_headsr   s     r(   rK   z%Dinov2WithRegistersAttention.__init__G  s0    9&A3F;Er8   r   c                 >   t        |      dk(  ry t        || j                  j                  | j                  j                  | j
                        \  }}t        | j                  j                  |      | j                  _        t        | j                  j                  |      | j                  _        t        | j                  j                  |      | j                  _	        t        | j                  j                  |d      | j                  _        | j                  j                  t        |      z
  | j                  _        | j                  j                  | j                  j                  z  | j                  _        | j
                  j                  |      | _        y )Nr   r#   r   )r3   r7   r  rN   r   r	  r   r   r   r   r  r  r   union)re   r   r6   s      r(   prune_headsz(Dinov2WithRegistersAttention.prune_headsM  s   u:?84>>55t~~7Y7Y[_[l[l
u
  2$..2F2FN/0B0BEJ1$..2F2FN.t{{/@/@%QO .2^^-O-ORUV[R\-\*'+~~'I'IDNNLnLn'n$ --33E:r8   r   r   c                 f    | j                  ||      }| j                  |d   |      }|f|dd  z   }|S )Nr   r#   )r  r  )re   r   r   self_outputsattention_outputr   s         r(   r   z$Dinov2WithRegistersAttention.forward_  sC    
 ~~m5FG;;|AF#%QR(88r8   r   )rp   rq   rr   rD   rK   r   r   r  r+   r   r   r   r   r   ru   rv   s   @r(   r  r  F  s}    "@ "T ";S ;d ;* #(
||
  
 
uU\\5<</0%2EE	F	
r8   r  c                   (     e Zd Zdeddf fdZ xZS ) Dinov2WithRegistersSdpaAttentionr   r    Nc                 D    t         |   |       t        |      | _        y r   )rJ   rK   r   r  r   s     r(   rK   z)Dinov2WithRegistersSdpaAttention.__init__m  s     =fEr8   )rp   rq   rr   rD   rK   ru   rv   s   @r(   r  r  l  s     F@ FT F Fr8   r  c                   X     e Zd Zd fdZdej
                  dej
                  fdZ xZS )Dinov2WithRegistersLayerScaler    c                     t         |           t        j                  |j                  t        j                  |j                        z        | _        y r   )	rJ   rK   r	   r   rY   r+   r,   rL   lambda1r   s     r(   rK   z&Dinov2WithRegistersLayerScale.__init__s  s8    ||F$;$;ejjI[I[>\$\]r8   hidden_statec                      || j                   z  S r   )r  re   r  s     r(   r   z%Dinov2WithRegistersLayerScale.forwardw  s    dll**r8   r    Nrp   rq   rr   rK   r+   r   r   ru   rv   s   @r(   r  r  r  s$    ^+ELL +U\\ +r8   r  input	drop_probr   c                    |dk(  s|s| S d|z
  }| j                   d   fd| j                  dz
  z  z   }|t        j                  || j                  | j
                        z   }|j                          | j                  |      |z  }|S )aA  Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).

    Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks,
    however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... See
    discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the
    layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the
    argument.
    rk   r#   r   )r#   )r   r   )r   ndimr+   randr   r   floor_div)r  r  r   	keep_probr   random_tensorr  s          r(   	drop_pathr%  {  s     CxII[[^

Q 77E

5ELL YYMYYy!M1FMr8   c                   x     e Zd ZdZd	dee   ddf fdZdej                  dej                  fdZ	de
fdZ xZS )
Dinov2WithRegistersDropPathzXDrop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).Nr  r    c                 0    t         |           || _        y r   )rJ   rK   r  )re   r  rg   s     r(   rK   z$Dinov2WithRegistersDropPath.__init__  s    "r8   r   c                 D    t        || j                  | j                        S r   )r%  r  r   )re   r   s     r(   r   z#Dinov2WithRegistersDropPath.forward  s    FFr8   c                 8    dj                  | j                        S )Nzp={})formatr  re   s    r(   
extra_reprz&Dinov2WithRegistersDropPath.extra_repr  s    }}T^^,,r8   r   )rp   rq   rr   rs   r   floatrK   r+   r   r   strr-  ru   rv   s   @r(   r'  r'    sG    b#(5/ #T #GU\\ Gell G-C -r8   r'  c                   X     e Zd Zd fdZdej
                  dej
                  fdZ xZS )Dinov2WithRegistersMLPr    c                 ~   t         |           |j                  x}}t        |j                  |j                  z        }t        j                  ||d      | _        t        |j                  t              rt        |j                     | _        n|j                  | _        t        j                  ||d      | _        y )NTr   )rJ   rK   rL   r   rO   r	   r   fc1r|   rP   r/  r   
activationfc2re   r   in_featuresr9   hidden_featuresrg   s        r(   rK   zDinov2WithRegistersMLP.__init__  s    %+%7%77lf0063C3CCD99[/Ef''-$V%6%67DO$//DO99_lFr8   r  c                 l    | j                  |      }| j                  |      }| j                  |      }|S r   )r3  r4  r5  r  s     r(   r   zDinov2WithRegistersMLP.forward  s2    xx-|4xx-r8   r  r  rv   s   @r(   r1  r1    s$    	GELL U\\ r8   r1  c                   X     e Zd Zd fdZdej
                  dej
                  fdZ xZS )Dinov2WithRegistersSwiGLUFFNr    c                 0   t         |           |j                  x}}t        |j                  |j                  z        }t        |dz  dz        dz   dz  dz  }t        j                  |d|z  d      | _        t        j                  ||d      | _        y )Nr   rn         Tr   )	rJ   rK   rL   r   rO   r	   r   
weights_inweights_outr6  s        r(   rK   z%Dinov2WithRegistersSwiGLUFFN.__init__  s    %+%7%77lf0063C3CCD2Q67!;AAE))K_1D4P99_lNr8   r  c                     | j                  |      }|j                  dd      \  }}t        j                  j	                  |      |z  }| j                  |      S )Nr   r*   r   )r?  chunkr	   r   silur@  )re   r  x1x2hiddens        r(   r   z$Dinov2WithRegistersSwiGLUFFN.forward  sS    |4##A2#.B##B'",''r8   r  r  rv   s   @r(   r;  r;    s$    O(ELL (U\\ (r8   r;  )eagersdpac                        e Zd ZdZdeddf fdZ	 	 d
dej                  dedede	e
ej                  ej                  f   e
ej                     f   fd	Z xZS ) WindowedDinov2WithRegistersLayerzCThis corresponds to the Block class in the original implementation.r   r    Nc                 R   t         |           |j                  | _        t        j                  |j
                  |j                        | _        t        |j                     |      | _
        t        |      | _        |j                  dkD  rt        |j                        nt        j                         | _        t        j                  |j
                  |j                        | _        |j$                  rt'        |      | _        nt+        |      | _        t        |      | _        y )Nepsrk   )rJ   rK   rb   r	   	LayerNormrL   rT   norm1'DINOV2_WITH_REGISTERS_ATTENTION_CLASSES_attn_implementationr  r  layer_scale1rZ   r'  Identityr%  norm2r[   r;  mlpr1  layer_scale2r   s     r(   rK   z)WindowedDinov2WithRegistersLayer.__init__  s    !--\\&"4"4&:O:OP
@A\A\]^de9&ABHBWBWZ]B]'(=(=>cecncncp 	 \\&"4"4&:O:OP
  3F;DH-f5DH9&Ar8   r   r   run_full_attentionc                 @   |rJ d       |}|r8|j                   \  }}}| j                  dz  }|j                  ||z  ||z  |      }| j                  | j	                  |      |      }	|	d   }
|r8|j                   \  }}}| j                  dz  }|
j                  ||z  ||z  |      }
| j                  |
      }
|	dd  }| j                  |
      |z   }| j                  |      }| j                  |      }| j                  |      }| j                  |      |z   }|f|z   }|S )Nz9output_attentions is not supported for windowed attentionr   )r   r   r#   )
r   rb   r/   r  rO  rR  r%  rT  rU  rV  )re   r   r   rW  shortcutbatch_windowstokens_per_windowchannelsnum_windows_squaredself_attention_outputsr  r   layer_outputs                r(   r   z(WindowedDinov2WithRegistersLayer.forward  sm    %a&aa$ 9F9L9L6M,h"&"2"2A"5)..!446IL]6]_gM "&JJ}%/ "0 "
 2!49F9L9L6M,h"&"2"2A"5/44 335FJ]5]_g   ,,-=>(, '788C zz-0xx-((6 ~~l3mC/G+r8   )FF)rp   rq   rr   rs   rD   rK   r+   r   r   r   r   r   ru   rv   s   @r(   rJ  rJ    sy    MB@ BT B. #(#(	/||/  / !	/
 
uU\\5<</0%2EE	F/r8   rJ  c                   j     e Zd Zdeddf fdZ	 	 	 d
dej                  dedededee	e
f   f
d	Z xZS )"WindowedDinov2WithRegistersEncoderr   r    Nc                     t         |           || _        t        j                  t        |j                        D cg c]  }t        |       c}      | _        |j                  | _	        y c c}w r   )
rJ   rK   r   r	   
ModuleListr]   rM   rJ  r=   rd   re   r   r   rg   s      r(   rK   z+WindowedDinov2WithRegistersEncoder.__init__  sX    ]]V[\b\t\tVu#vQR$DV$L#vw
&,&C&C# $ws   A-r   r   output_hidden_statesreturn_dictc                    |rdnd }|rdnd }t        | j                        D ]  \  }}|r||fz   }|t        | j                  j                  d   dd        kD  r nl|| j                  j
                  v}	| j                  r+| j                  r| j                  |j                  |||	      }
n
 ||||	      }
|
d   }|s||
d   fz   } |r||fz   }|st        d |||fD              S t        |||      S )Nr$   r*      r   r#   c              3   &   K   | ]	  }||  y wr   r$   )r%   vs     r(   r)   z=WindowedDinov2WithRegistersEncoder.forward.<locals>.<genexpr>=  s     mq_`_lms   )last_hidden_stater   
attentions)	enumerater=   r   r   r9   rc   rd   r   _gradient_checkpointing_func__call__tupler   )re   r   r   re  rf  all_hidden_statesall_self_attentionsilayer_modulerW  layer_outputss              r(   r   z*WindowedDinov2WithRegistersEncoder.forward  s+    #7BD$5b4(4 	POA|#$58H$H!3t{{//3AB788!"$++*J*J!J**t}} $ A A ))!%&	! !-]<MOa b)!,M &9]1=M<O&O#/	P2   1]4D Dm]4EGZ$[mmm++*
 	
r8   )FFT)rp   rq   rr   rD   rK   r+   r   r   r   rp  r   r   ru   rv   s   @r(   ra  ra    sh    D@ DT D #(%* ,
||,
  ,
 #	,

 ,
 
uo%	&,
r8   ra  c                       e Zd ZdZeZdZdZdZdgZ	dZ
deej                  ej                  ej                  f   ddfd	Zy)
*WindowedDinov2WithRegistersPreTrainedModelz|An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained
    models.rF   r   Tr;  moduler    Nc                 >   t        |t        j                  t        j                  f      rt        j                  j                  |j                  j                  j                  t        j                        d| j                  j                        j                  |j                  j                        |j                  _        |j                  %|j                  j                  j                          yyt        |t        j                         rJ|j                  j                  j                          |j                  j                  j#                  d       yt        |t$              r3t        j                  j                  |j&                  j                  j                  t        j                        d| j                  j                        j                  |j&                  j                        |j&                  _        t        j                  j                  |j(                  j                  j                  t        j                        d| j                  j                        j                  |j(                  j                        |j(                  _        yy)zInitialize the weights.rk   )meanstdNro   )r|   r	   r   r   inittrunc_normal_r   datar   r+   r   r   rS   r   r   zero_rN  fill_r   r   r   )re   rx  s     r(   _init_weightsz8WindowedDinov2WithRegistersPreTrainedModel._init_weightsP  s   fryy"))45 "$!6!6""%%emm43DKKDaDa "7 "b$$% MM {{&  &&( '-KK""$MM$$S) EF.0gg.C.C**//225==AKK11 /D / b++112	 &&+ %'GG$9$9  %%((7KK11 %: % b!!''(	 ! Gr8   )rp   rq   rr   rs   rD   config_classbase_model_prefixmain_input_namesupports_gradient_checkpointing_no_split_modules_supports_sdpar   r	   r   r   rN  r  r$   r8   r(   rw  rw  E  sY     5L/$O&*#78N)E"))RYY*L$M )RV )r8   rw  aU  
    This model is a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. Use it
    as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage and
    behavior.

    Parameters:
        config ([`Dinov2WithRegistersConfig`]): Model configuration class with all the parameters of the model.
            Initializing with a config file does not load the weights associated with the model, only the
            configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights.
a  
    Args:
        pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`):
            Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See
            [`BitImageProcessor.preprocess`] for details.

        bool_masked_pos (`torch.BoolTensor` of shape `(batch_size, sequence_length)`):
            Boolean masked positions. Indicates which patches are masked (1) and which aren't (0). Only relevant for
            pre-training.

        output_attentions (`bool`, *optional*):
            Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned
            tensors for more detail.
        output_hidden_states (`bool`, *optional*):
            Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for
            more detail.
        return_dict (`bool`, *optional*):
            Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple.
zmThe bare Dinov2WithRegisters Model transformer outputting raw hidden-states without any specific head on top.c                       e Zd Zdef fdZdefdZdeee	e   f   ddfdZ
deddfd	Z ee       eee
      	 	 	 	 	 ddeej(                     deej(                     dee   dee   dee   deeef   fd              Z xZS ) WindowedDinov2WithRegistersModelr   c                     t         |   |       || _        t        |      | _        t        |      | _        t        j                  |j                  |j                        | _        | j                          y )NrL  )rJ   rK   r   r   r   ra  encoderr	   rN  rL   rT   	layernorm	post_initr   s     r(   rK   z)WindowedDinov2WithRegistersModel.__init__  sY     ?G9&Af&8&8f>S>ST 	r8   r    c                 .    | j                   j                  S r   r   r   r,  s    r(   get_input_embeddingsz5WindowedDinov2WithRegistersModel.get_input_embeddings      ///r8   heads_to_pruneNc                     |j                         D ]7  \  }}| j                  j                  |   j                  j	                  |       9 y)zPrunes heads of the model.

        heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base
        class PreTrainedModel
        N)itemsr  r=   r  r  )re   r  r=   r   s       r(   _prune_headsz-WindowedDinov2WithRegistersModel._prune_heads  sE     +002 	CLE5LLu%//;;EB	Cr8   attn_implementationc                     |t         vrt        d|dt        t                d      || j                  _        | j
                  j                  D ]  }t        |   | j                        |_        ! y)uD  Switch the attention implementation without reloading the model.

        This is useful when you want to change the attention implementation after the model has been instantiated — for
        example, to use ``"eager"`` (manual) attention when inspecting attention weights, without having to reconstruct
        the entire model from scratch.

        Args:
            attn_implementation: One of ``"eager"`` (manual attention) or ``"sdpa"``
                (:func:`torch.nn.functional.scaled_dot_product_attention`).

        Raises:
            ValueError: If *attn_implementation* is not a supported key.

        Example::

            >>> from rfdetr.models.backbone.dinov2_with_windowed_attn import (
            ...     WindowedDinov2WithRegistersConfig,
            ...     WindowedDinov2WithRegistersModel,
            ... )
            >>> config = WindowedDinov2WithRegistersConfig(
            ...     image_size=32,
            ...     patch_size=16,
            ...     hidden_size=32,
            ...     num_hidden_layers=1,
            ...     num_attention_heads=4,
            ...     num_register_tokens=2,
            ... )
            >>> model = WindowedDinov2WithRegistersModel(config)
            >>> model.set_attn_implementation("eager")
            >>> model.config._attn_implementation
            'eager'
        zUnknown attn_implementation z. Choose from r   N)rP  r   sortedr   rQ  r  r=   r  )re   r  r=   s      r(   set_attn_implementationz8WindowedDinov2WithRegistersModel.set_attn_implementation  s    B &MM./B.E F%&MNOqR  ,?(\\'' 	hEEFYZ[_[f[fgEO	hr8   output_typer  r   r   r   re  rf  c                    ||n| j                   j                  }||n| j                   j                  }||n| j                   j                  }|t	        d      | j                  ||      }| j                  ||||      }|d   }| j                  |      }|dddddf   }	|s||	f}
|
|dd z   S t        ||	|j                  |j                        S )a  
        Returns:

        Examples:

        >>> import torch
        >>> from rfdetr.models.backbone.dinov2_with_windowed_attn import (
        ...     WindowedDinov2WithRegistersConfig,
        ...     WindowedDinov2WithRegistersModel,
        ... )
        >>> config = WindowedDinov2WithRegistersConfig(
        ...     image_size=32,
        ...     patch_size=16,
        ...     hidden_size=32,
        ...     num_hidden_layers=2,
        ...     num_attention_heads=4,
        ...     num_register_tokens=2,
        ... )
        >>> model = WindowedDinov2WithRegistersModel(config)
        >>> pixel_values = torch.randn(1, 3, 32, 32)
        >>> outputs = model(pixel_values)
        >>> list(outputs.last_hidden_state.shape)
        [1, 7, 32]
        Nz You have to specify pixel_values)r   r   re  rf  r   r#   )rk  pooler_outputr   rl  )r   r   re  rf  r   r   r  r  r   r   rl  )re   r   r   r   re  rf  embedding_outputencoder_outputssequence_outputpooled_outputhead_outputss              r(   r   z(WindowedDinov2WithRegistersModel.forward  s   D 2C1N-TXT_T_TqTq$8$D $++JjJj 	 &1%<k$++BYBY?@@??<?Y,,/!5#	 ' 
 *!,..9'1a0+];L/!""555)-')77&11	
 	
r8   NNNNN)rp   rq   rr   rD   rK   rx   r  r   r   r   r  r/  r  r   +DINOV2_WITH_REGISTERS_BASE_INPUTS_DOCSTRINGr   r   _CONFIG_FOR_DOCr   r+   r   r   r   r   r   ru   rv   s   @r(   r  r    s    

@ 
0&H 0C4T#Y+? CD C(h3 (h4 (hT ++VW+ETcd 0426,0/3&*>
u||,>
 "%,,/>
 $D>	>

 'tn>
 d^>
 
u00	1>
 e X>
r8   r  a  
    Args:
        pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`):
            Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See
            [`BitImageProcessor.preprocess`] for details.

        output_attentions (`bool`, *optional*):
            Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned
            tensors for more detail.
        output_hidden_states (`bool`, *optional*):
            Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for
            more detail.
        return_dict (`bool`, *optional*):
            Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple.
zDinov2WithRegisters Model transformer with an image classification head on top (a linear layer on top of the final hidden state of the [CLS] token) e.g. for ImageNet.c                        e Zd Zdeddf fdZ ee       eee	      	 	 	 	 	 dde
ej                     de
ej                     de
e   d	e
e   d
e
e   deeef   fd              Z xZS )1WindowedDinov2WithRegistersForImageClassificationr   r    Nc                 0   t         |   |       |j                  | _        t        |      | _        |j                  dkD  r-t        j                  |j                  dz  |j                        nt        j                         | _	        | j                          y )Nr   r   )rJ   rK   
num_labelsr  rF   r	   r   rL   rS  
classifierr  r   s     r(   rK   z:WindowedDinov2WithRegistersForImageClassification.__init__.  sz      ++%Ef%M" EKDUDUXYDYBIIf((1,f.?.?@_a_j_j_l 	
 	r8   r  r   labelsr   re  rf  c                    ||n| j                   j                  }| j                  ||||      }|d   }|dddf   }|ddddf   }	t        j                  ||	j                  d      gd      }
| j                  |
      }d}||j                  |j                        }| j                   j                  | j                  dk(  rd| j                   _	        nl| j                  dkD  rL|j                  t        j                  k(  s|j                  t        j                  k(  rd| j                   _	        nd| j                   _	        | j                   j                  dk(  rIt               }| j                  dk(  r& ||j                         |j                               }n |||      }n| j                   j                  dk(  r=t!               } ||j#                  d	| j                        |j#                  d	            }n,| j                   j                  dk(  rt%               } |||      }|s|f|d
d z   }||f|z   S |S t'        |||j(                  |j*                        S )a  Labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):

            Labels for computing the image classification/regression loss. Indices should be in `[0, ...,
            config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
            `config.num_labels > 1` a classification loss is computed (Cross-Entropy).

        Returns:

        Example:

        >>> import torch
        >>> from rfdetr.models.backbone.dinov2_with_windowed_attn import (
        ...     WindowedDinov2WithRegistersConfig,
        ...     WindowedDinov2WithRegistersForImageClassification,
        ... )
        >>> config = WindowedDinov2WithRegistersConfig(
        ...     image_size=32,
        ...     patch_size=16,
        ...     hidden_size=32,
        ...     num_hidden_layers=2,
        ...     num_attention_heads=4,
        ...     num_register_tokens=2,
        ...     num_labels=3,
        ... )
        >>> model = WindowedDinov2WithRegistersForImageClassification(config)
        >>> pixel_values = torch.randn(1, 3, 32, 32)
        >>> outputs = model(pixel_values)
        >>> list(outputs.logits.shape)
        [1, 3]
        Nr  r   r#   r   
regressionsingle_label_classificationmulti_label_classificationr*   r   )losslogitsr   rl  )r   rf  rF   r+   r   rz  r  r   r   problem_typer  r   r4   r   r   squeezer   r/   r
   r   r   rl  )re   r   r  r   re  rf  r   r  r   patch_tokenslinear_inputr  r  loss_fctr  s                  r(   r   z9WindowedDinov2WithRegistersForImageClassification.forward<  s!   V &1%<k$++BYBY,,/!5#	 - 
 "!*#AqD)	&q!"u-yy)\->->1->-E!FAN.YYv}}-F{{''/??a'/;DKK,__q(fllejj.HFLL\a\e\eLe/LDKK,/KDKK,{{''<7"9??a'#FNN$4fnn6FGD#FF3D))-JJ+-B @&++b/R))-II,./Y,F)-)9TGf$EvE$!//))	
 	
r8   r  )rp   rq   rr   rD   rK   r   &DINOV2_WITH_REGISTERS_INPUTS_DOCSTRINGr   r   r  r   r+   r   r   r   rp  r   ru   rv   s   @r(   r  r  &  s    @ T  ++QR)$ 04)-,0/3&*Z
u||,Z
 &Z
 $D>	Z

 'tnZ
 d^Z
 
u++	,Z
	 S
Z
r8   r  zRDinov2WithRegisters backbone, to be used with frameworks like DETR and MaskFormer.c                        e Zd Zdef fdZdefdZ ee       e	e
e      	 	 	 ddej                  dee   dee   d	ee   de
f
d
              Z xZS )#WindowedDinov2WithRegistersBackboner   c                    t         |   |       | j                          t        |j                  dz         D cg c]  }|j
                   c}| _        t        |      | _        t        |      | _
        t        j                  |j
                  |j                        | _        |j                  | _        | j!                          y c c}w )Nr#   rL  )rJ   rK   _init_transformers_backboner]   rM   rL   num_featuresr   r   ra  r  r	   rN  rT   r  r\   r  rd  s      r(   rK   z,WindowedDinov2WithRegistersBackbone.__init__  s     ((*9>v?W?WZ[?[9\]AV//]?G9&Af&8&8f>S>ST#)#=#=  	 ^s   Cr    c                 .    | j                   j                  S r   r  r,  s    r(   r  z8WindowedDinov2WithRegistersBackbone.get_input_embeddings  r  r8   r  r   re  r   rf  c                 T   ||n| j                   j                  }||n| j                   j                  }||n| j                   j                  }| j	                  |      }| j                  |d||      }|r|j                  n|d   }d}t        | j                  |      D ]  \  }	}
|	| j                  v s| j                   j                  r| j                  |
      }
| j                   j                  rd|
dd| j                  dz   df   }
|j                  \  }}}}| j                   j                  }||z  }||z  }| j                   j                   dkD  r| j                   j                   dz  }|
j                  \  }}}|| j                   j                   z  }|| j                   j                   z  }|
j#                  ||z  ||z  |      }
|
j#                  ||z  | j                   j                   z  | j                   j                   |||      }
|
j%                  ddddd	      }
|
j#                  |||d
      }
|
j%                  dddd      j'                         }
||
fz  } |s|r|f|dd z   }|S |f|dd z   }|S t)        ||r|j                  nd|r|j*                        S d      S )aV  
        Returns:

        Examples:

        >>> import torch
        >>> from rfdetr.models.backbone.dinov2_with_windowed_attn import (
        ...     WindowedDinov2WithRegistersBackbone,
        ...     WindowedDinov2WithRegistersConfig,
        ... )
        >>> config = WindowedDinov2WithRegistersConfig(
        ...     image_size=32,
        ...     patch_size=16,
        ...     hidden_size=32,
        ...     num_hidden_layers=2,
        ...     num_attention_heads=4,
        ...     num_register_tokens=2,
        ...     out_indices=[2],
        ... )
        >>> model = WindowedDinov2WithRegistersBackbone(config)
        >>> pixel_values = torch.randn(1, 3, 32, 32)
        >>> outputs = model(pixel_values)
        >>> len(outputs.feature_maps)
        1
        >>> list(outputs.feature_maps[0].shape)
        [1, 32, 2, 2]

        NT)re  r   rf  r#   r$   r   r   rn   ri   r*   )feature_mapsr   rl  )r   rf  re  r   r   r  r   zipr;   r9   r`   r  ra   r\   r   rV   rb   r   r   r0   r   rl  )re   r   re  r   rf  r  r   r   r  rI   r  r   r   r   r   rV   r   r   r]  rZ  r[  r\  r   r   r  s                            r(   r   z+WindowedDinov2WithRegistersBackbone.forward  s   J &1%<k$++BYBY$8$D $++JjJj 	 2C1N-TXT_T_TqTq??<8,,4K\ju  
 2=--'!*#&t'7'7#G %	0E<)));;..#'>>,#?L;;44#/43K3Ka3O3Q0Q#RL 4@3E3E0J65!%!7!7J$*j$8M$)Z$7M{{..2.2kk.E.Eq.H+EQEWEWB'8(3@DKKD[D[3[03@DKKD[D[3[0'3';';)-@@/2CC$(
 (4';';*.AAT[[E\E\\ KK3344$( (4';';Aq!Q'J#/#7#7
MS`bd#eL#/#7#71a#C#N#N#PL/K%	0N #&712;6 M '712;6M%3G'//T->w))
 	
 EI
 	
r8   )NNN)rp   rq   rr   rD   rK   rx   r  r   r  r   r   r  r+   r   r   r   r   ru   rv   s   @r(   r  r    s    
@ 0&H 0 ++QR>X 04,0&*d
lld
 'tnd
 $D>	d

 d^d
 
d
 Y Sd
r8   r  )rw  r  r  r  )rk   F)Mrs   collections.abcr}   r   typingr   r   r   r   r   r   r+   r	   torch.nnr
   r   r   transformersr   r   transformers.activationsr    transformers.configuration_utilsr   transformers.modeling_outputsr   r   r   r   transformers.modeling_utilsr   transformers.pytorch_utilsr   transformers.utilsr   r   r   r   r   
get_loggerrp   r   r   
LongTensorr7   r/  r?   rC   r  rD   Modulerx   r   r   r   r   r  r  r  r   r.  r   r%  r'  r1  r;  rP  rJ  ra  rw  %DINOV2_WITH_REGISTERS_START_DOCSTRINGr  r  r  r  r  __all__r$   r8   r(   <module>r     sM  ,   : :   A A ; + =  8 9  
		H	%s8!.1ILS
3s8U%%%&>%49%%%S	5c? :;<% c% 49d3i 	%%49%%%S	5c? :;<% c% 49d3i 	%: 6N=(;=M N=b >QBII Qh9ryy 9x&#+K &#RBII  #299 #LF'C F+BII +U\\ e T V[VbVb &-")) -RYY &(299 ($ *,+ 'Fryy FR3
 3
l#) #)L	) %/ +* s)C
'Q C
	C
L* &" 	b *n
8b n
n
b X)x
*TVc x
	x
vr8   