ó
    ‡Ž¡j@í  ã                   ó
  • S SK Jr  S SKJr  S SKrS SKJr  SSKJr  SSK	J
r
Jr  SSKJr  SS	KJr  SS
KJr  SSKJrJr  SSKJr  SSKJr  SSKJrJrJrJrJr  SSKJ r   SSK!J"r"J#r#  SSK$J%r%  SSK&J'r'  \" SS9\ " S S\5      5       5       r(\" SS9S\RR                  S\*S\*S\*S\RR                  4
S j5       r+ " S  S!\RX                  5      r- " S" S#\RX                  5      r. " S$ S%\5      r/ " S& S'\RX                  5      r0 " S( S)\RX                  5      r1 " S* S+\RX                  5      r2S, r3S\S- jr4S.\RR                  S/\*S\RR                  4S0 jr5 S]S1\RX                  S2\RR                  S3\RR                  S4\RR                  S5\RR                  S-  S6\6S7\6S8\\   4S9 jjr7 " S: S;\RX                  5      r8 " S< S=\RX                  5      r9 " S> S?\RX                  5      r: " S@ SA\5      r; " SB SC\RX                  5      r< " SD SE\RX                  5      r= " SF SG\RX                  5      r>\ " SH SI\5      5       r?\" SJS9 " SK SL\?5      5       r@SM\RR                  SN\*S4\A\6-  \*-  S\RR                  4SO jrB   S^SP\*\RR                  -  SQ\*\RR                  -  SR\ASS\R†                  S-  ST\Rˆ                  S-  S\RR                  4SU jjrES_SV\RR                  SR\AS\RR                  4SW jjrF\" SXS9 " SY SZ\?5      5       rG/ S[QrHg)`é    )ÚCallable)Ú	dataclassN)Únné   )Úinitialization)ÚACT2CLSÚACT2FN)ÚGradientCheckpointingLayer)ÚBackboneOutput)ÚROPE_INIT_FUNCTIONS)ÚALL_ATTENTION_FUNCTIONSÚPreTrainedModel)ÚUnpack)Ú#compile_compatible_method_lru_cache)ÚModelOutputÚTransformersKwargsÚauto_docstringÚcan_return_tupleÚ	torch_int)Údeprecate_kwarg)Úmaybe_autocastÚmerge_with_config_defaults)Úcapture_outputsé   )ÚEfficientLoFTRConfigae  
    Base class for outputs of EfficientLoFTR keypoint matching models. Due to the nature of keypoint detection and matching, the number
    of keypoints is not fixed and can vary from image to image, which makes batching non-trivial. In the batch of
    images, the maximum number of matches is set as the dimension of the matches and matching scores.
    )Úcustom_introc                   ó  • \ rS rSr% SrSr\R                  S-  \S'   Sr	\R                  S-  \S'   Sr
\R                  S-  \S'   Sr\R                  S-  \S'   Sr\\R                     S-  \S'   Sr\\R                     S-  \S	'   S
rg)Ú$EfficientLoFTRKeypointMatchingOutputé)   a  
loss (`torch.FloatTensor` of shape `(1,)`, *optional*):
    Loss computed during training.
matches (`torch.FloatTensor` of shape `(batch_size, 2, num_matches)`):
    Index of keypoint matched in the other image.
matching_scores (`torch.FloatTensor` of shape `(batch_size, 2, num_matches)`):
    Scores of predicted matches.
keypoints (`torch.FloatTensor` of shape `(batch_size, num_keypoints, 2)`):
    Absolute (x, y) coordinates of predicted keypoints in a given image.
hidden_states (`tuple[torch.FloatTensor, ...]`, *optional*):
    Tuple of `torch.FloatTensor` (one for the output of each stage) of shape `(batch_size, 2, num_channels,
    num_keypoints)`, returned when `output_hidden_states=True` is passed or when
    `config.output_hidden_states=True`)
attentions (`tuple[torch.FloatTensor, ...]`, *optional*):
    Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, 2, num_heads, num_keypoints,
    num_keypoints)`, returned when `output_attentions=True` is passed or when `config.output_attentions=True`)
NÚlossÚmatchesÚmatching_scoresÚ	keypointsÚhidden_statesÚ
attentions© )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r    ÚtorchÚFloatTensorÚ__annotations__r!   r"   r#   r$   Útupler%   Ú__static_attributes__r&   ó    ÚÈC:\Users\johnn\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0\LocalCache\local-packages\Python313\site-packages\transformers/models/efficientloftr/modeling_efficientloftr.pyr   r   )   s‘   ‡ ñð$ &*€Dˆ%×
Ñ
˜dÑ
"Ó)Ø(,€GˆU×Ñ Ñ%Ó,Ø04€O�U×&Ñ&¨Ñ-Ó4Ø*.€Iˆu× Ñ  4Ñ'Ó.Ø59€M�5˜×*Ñ*Ñ+¨dÑ2Ó9Ø26€J��e×'Ñ'Ñ(¨4Ñ/Ö6r1   r   é    )ÚmaxsizeÚinv_freqÚembed_heightÚembed_widthÚhidden_sizeÚreturnc           	      óÜ  • [         R                  " XU R                  U R                  S9n[         R                  " XU R                  U R                  S9nUR	                  S5      R                  S5      nUR	                  S5      R                  S5      n[         R                  " SXUS-  U R                  U R                  S9nX@-  US S 2S S 2S S 2SS S24'   XP-  US S 2S S 2S S 2SS S24'   U$ )N)ÚdtypeÚdevicer   éÿÿÿÿr   é   )r,   Úonesr;   r<   ÚcumsumÚ	unsqueezeÚzeros)r5   r6   r7   r8   Ú	i_indicesÚ	j_indicesÚembs          r2   Úcompute_embeddingsrF   L   sÓ   € ä—
’
˜<¸H¿N¹NÐS[×SbÑSbÑc€IÜ—
’
˜<¸H¿N¹NÐS[×SbÑSbÑc€IØ× Ñ  Ó#×-Ñ-¨bÓ1€IØ× Ñ  Ó#×-Ñ-¨bÓ1€Iä
�+Š+�a˜°KÀ1Ñ4DÈHÏNÉNÐck×crÑcrÑ
s€CØ"Ñ-€CŠŠ1Ša���A�ˆÑØ"Ñ-€CŠŠ1Ša���A�ˆÑà€Jr1   c            	       ó  ^ • \ rS rSr\" SSS9SS\4U 4S jjj5       r\\" SSS9 SS\S\\	R                  \4   4S jj5       5       r\	R                  " 5       S	\	R                  S\\	R                  \	R                  4   4S
 j5       rSrU =r$ )ÚEfficientLoFTRRotaryEmbeddingéZ   r<   z5.18)ÚversionÚconfigc                 ó€  >• [         TU ]  5         Xl        U R                  R                  S   U l        U R
                  nU R                  S:w  a  [        U R                     nU" U R                  U5      u  o@l        [        R                  " USS9U l
        [        R                  " UR                  5       SS9U l        g )NÚ	rope_typeÚdefaultF)Ú
persistent)ÚsuperÚ__init__rK   Úrope_parametersrM   Úcompute_default_rope_parametersr   Úattention_scalingr   ÚBufferr5   ÚcloneÚoriginal_inv_freq)ÚselfrK   r<   Úrope_init_fnr5   Ú	__class__s        €r2   rQ   Ú&EfficientLoFTRRotaryEmbedding.__init__[   s�   ø€ ä‰ÑÔØŒàŸ™×4Ñ4°[ÑAˆŒØ!%×!EÑ!EˆØ�>‰>˜YÓ&Ü.¨t¯~©~Ñ>ˆLÙ+7¸¿¹ÀVÓ+LÑ(ˆÔ(äŸ	š	 (°uÑ=ˆŒÜ!#§¢¨8¯>©>Ó+;ÈÑ!NˆÕr1   r9   c           	      óR  • U R                   S   nU R                   R                  SS5      n[        U SS5      =(       d    U R                  U R                  -  n[        XT-  5      nSnSU[        R                  " SUS[        R                  S9U-  -  -  nUR                  U5      U4$ )	a~  
Computes the inverse frequencies according to the original RoPE implementation
Args:
    config ([`~transformers.PreTrainedConfig`]):
        The model configuration.
Returns:
    Tuple of (`torch.Tensor`, `float`), containing the inverse frequencies for the RoPE embeddings and the
    post-processing scaling factor applied to the computed cos/sin (unused in this type of RoPE).
Ú
rope_thetaÚpartial_rotary_factorg      ð?Úhead_dimNr   r>   ©r;   )
rR   ÚgetÚgetattrr8   Únum_attention_headsÚintr,   ÚarangeÚfloatÚto)	rK   r<   ÚkwargsÚbaser^   r_   ÚdimÚattention_factorr5   s	            r2   rS   Ú=EfficientLoFTRRotaryEmbedding.compute_default_rope_parametersi   s£   € ð ×%Ñ% lÑ3ˆØ &× 6Ñ 6× :Ñ :Ð;RÐTWÓ XÐÜ˜6 :¨tÓ4×h¸×8JÑ8JÈf×NhÑNhÑ8hˆÜ�(Ñ2Ó3ˆàÐà˜$¤5§<¢<°°3¸ÄÇÁÑ#MÐPSÑ#SÑTÑUˆØ�{‰{˜6Ó"Ð$4Ð4Ð4r1   Úxc                 óV  • UR                   SS  u  p#X R                  R                  -
  U R                  R                  -  S-   nX0R                  R                  -
  U R                  R                  -  S-   n[	        UR
                  R                  [        5      (       a0  UR
                  R                  S:w  a  UR
                  R                  OSn[        USS9   [        U R                  XEU R                  R                  5      nUR                  5       nUR                  5       n	S S S 5        WR                  SSS	9nW	R                  SSS	9n	UR                  UR
                  UR                   S
9nU	R                  UR
                  UR                   S
9n	X˜4$ ! , (       d  f       Ny= f)Néþÿÿÿr   ÚmpsÚcpuF)Údevice_typeÚenabledr>   r=   ©rj   ©r<   r;   )ÚshaperK   Úq_aggregation_kernel_sizeÚq_aggregation_strideÚ
isinstancer<   ÚtypeÚstrr   rF   r5   r8   ÚsinÚcosÚrepeat_interleaverg   r;   )
rX   rm   Úfeats_heightÚfeats_widthr6   r7   rr   rE   r|   r}   s
             r2   ÚforwardÚ%EfficientLoFTRRotaryEmbedding.forward�   sL  € à$%§G¡G¨B¨C LÑ!ˆØ$§{¡{×'LÑ'LÑLÐQU×Q\ÑQ\×QqÑQqÑqÐtuÑuˆØ"§[¡[×%JÑ%JÑJÈtÏ{É{×OoÑOoÑoÐrsÑsˆÜ'1°!·(±(·-±-Ä×'EÑ'EÈ!Ï(É(Ï-É-Ð[`ÓJ`�a—h‘h—m’mÐfkˆÜ¨¸UÓCÜ$ T§]¡]°LÈtÏ{É{×OfÑOfÓgˆCØ—'‘'“)ˆCØ—'‘'“)ˆC÷ Dð
 ×#Ñ# A¨2Ð#Ð.ˆØ×#Ñ# A¨2Ð#Ð.ˆà�f‰f˜AŸH™H¨A¯G©GˆfÐ4ˆØ�f‰f˜AŸH™H¨A¯G©GˆfÐ4ˆàˆxˆ÷ DÕCús   ÃAFÆ
F()rT   rK   r5   rW   rM   ©N)r'   r(   r)   r*   r   r   rQ   Ústaticmethodr/   r,   ÚTensorrf   rS   Úno_gradr�   r0   Ú__classcell__©rZ   s   @r2   rH   rH   Z   s©   ø† Ù�X vÑ.ñOÐ3÷ Oó /ðOð Ù�X vÑ.à-1ñ5Ø$ð5à	ˆu�|‰|˜UÐ"Ñ	#ô5ó /ó ð5ð, ‡]‚]ƒ_ð˜Ÿ™ð ¨%°·±¸e¿l¹lÐ0JÑ*Kó ó ör1   rH   c                   ó2   ^ • \ rS rSrSU 4S jjrS rSrU =r$ )ÚEfficientLoFTRConvNormLayeré–   c           	      ó   >• [         TU ]  5         [        R                  " UUUUUc  US-
  S-  OUSS9U l        [        R
                  " X1R                  5      U l        Uc  [        R                  " 5       U l
        g [        U   " 5       U l
        g )Nr   r>   F)ÚpaddingÚbias)rP   rQ   r   ÚConv2dÚconvÚBatchNorm2dÚbatch_norm_epsÚnormÚIdentityr   Ú
activation)	rX   rK   Úin_channelsÚout_channelsÚkernel_sizeÚstrider�   r•   rZ   s	           €r2   rQ   Ú$EfficientLoFTRConvNormLayer.__init__—   sw   ø€ Ü‰ÑÔÜ—I’IØØØØØ.5©o�[ 1‘_¨Ò*À7Øñ
ˆŒ	ô —N’N <×1FÑ1FÓGˆŒ	Ø+5Ñ+=œ"Ÿ+š+›-ˆ�Ä7È:ÒCVÓCXˆ�r1   c                 ól   • U R                  U5      nU R                  U5      nU R                  U5      nU$ rƒ   )r�   r“   r•   )rX   Úhidden_states     r2   r�   Ú#EfficientLoFTRConvNormLayer.forward¤   s2   € Ø—y‘y Ó.ˆØ—y‘y Ó.ˆØ—‘ |Ó4ˆØÐr1   )r•   r�   r“   ©NN)r'   r(   r)   r*   rQ   r�   r0   r‡   rˆ   s   @r2   rŠ   rŠ   –   s   ø† ÷Y÷ð r1   rŠ   c                   óv   ^ • \ rS rSrSrS\S\S\4U 4S jjrS\R                  S\R                  4S	 jr
S
rU =r$ )ÚEfficientLoFTRRepVGGBlocké«   zc
RepVGG architecture block introduced by the work "RepVGG: Making VGG-style ConvNets Great Again".
rK   Ú	stage_idxÚ	block_idxc           	      ó–  >• [         TU ]  5         UR                  U   U   nUR                  U   U   nUR                  U   U   nUR
                  n[        XUSUSS9U l        [        XUSUSS9U l        XE:X  a  US:X  a  [        R                  " U5      OS U l        Uc  [        R                  " 5       U l        g [        U   U l        g )Nr   r   ©r˜   r™   r�   r   )rP   rQ   Ústage_block_in_channelsÚstage_block_out_channelsÚstage_block_strideÚactivation_functionrŠ   Úconv1Úconv2r   r‘   Úidentityr”   r	   r•   )	rX   rK   r¢   r£   r–   r—   r™   r•   rZ   s	           €r2   rQ   Ú"EfficientLoFTRRepVGGBlock.__init__°   sË   ø€ Ü‰ÑÔØ×4Ñ4°YÑ?À	ÑJˆØ×6Ñ6°yÑAÀ)ÑLˆØ×*Ñ*¨9Ñ5°iÑ@ˆØ×/Ñ/ˆ
Ü0Ø ¸1ÀVÐUVñ
ˆŒ
ô 1Ø ¸1ÀVÐUVñ
ˆŒ
ð 8CÓ7RÐW]ÐabÓWbœŸš {Ô3ÐhlˆŒØ+5Ñ+=œ"Ÿ+š+›-ˆ�Ä6È*ÑCUˆ�r1   r$   r9   c                 ó¶   • U R                   b  U R                  U5      nOSnU R                  U5      U R                  U5      -   U-   nU R                  U5      nU$ )Nr   )r¬   rª   r«   r•   )rX   r$   Úidentity_outs      r2   r�   Ú!EfficientLoFTRRepVGGBlock.forward¿   sU   € Ø�=‰=Ñ$ØŸ=™=¨Ó7‰LàˆLØŸ
™
 =Ó1°D·J±J¸}Ó4MÑMÐP\Ñ\ˆØŸ™¨Ó6ˆØÐr1   )r•   rª   r«   r¬   )r'   r(   r)   r*   r+   r   rd   rQ   r,   r…   r�   r0   r‡   rˆ   s   @r2   r    r    «   sH   ø† ñðVÐ3ð VÀð VÐPS÷ Vð U§\¡\ð °e·l±l÷ ò r1   r    c                   ón   ^ • \ rS rSrS\S\4U 4S jjrS\R                  S\R                  4S jr	Sr
U =r$ )	ÚEfficientLoFTRRepVGGStageéÉ   rK   r¢   c                 óâ   >• [         TU ]  5         [        R                  " / 5      U l        [        UR                  U   5       H)  nU R                  R                  [        UUU5      5        M+     g rƒ   )	rP   rQ   r   Ú
ModuleListÚblocksÚrangeÚstage_num_blocksÚappendr    )rX   rK   r¢   r£   rZ   s       €r2   rQ   Ú"EfficientLoFTRRepVGGStage.__init__Ê   s\   ø€ Ü‰ÑÔÜ—m’m BÓ'ˆŒÜ˜v×6Ñ6°yÑAÖBˆIØ�K‰K×ÑÜ)ØØØóöò Cr1   r$   r9   c                 ó<   • U R                    H  nU" U5      nM     U$ rƒ   ©r¶   )rX   r$   Úblocks      r2   r�   Ú!EfficientLoFTRRepVGGStage.forwardÖ   s    € Ø—[”[ˆEÙ! -Ó0ŠMñ !àÐr1   r¼   ©r'   r(   r)   r*   r   rd   rQ   r,   r…   r�   r0   r‡   rˆ   s   @r2   r²   r²   É   s7   ø† ð
Ð3ð 
À÷ 
ð U§\¡\ð °e·l±l÷ ò r1   r²   c                   óp   ^ • \ rS rSrS\4U 4S jjrS\R                  S\\R                     4S jr	Sr
U =r$ )ÚEfficientLoFTRepVGGéÜ   rK   c                 óî   >• [         TU ]  5         [        R                  " / 5      U l        [        [        UR                  5      5       H)  n[        X5      nU R                  R                  U5        M+     g rƒ   )
rP   rQ   r   rµ   Ústagesr·   ÚlenÚstage_strider²   r¹   )rX   rK   r¢   ÚstagerZ   s       €r2   rQ   ÚEfficientLoFTRepVGG.__init__Ý   sT   ø€ Ü‰ÑÔä—m’m BÓ'ˆŒäœs 6×#6Ñ#6Ó7Ö8ˆIÜ-¨fÓ@ˆEØ�K‰K×Ñ˜uÖ%ò 9r1   r$   r9   c                 ól   • / nU R                    H  nU" U5      nUR                  U5        M     USS  nU$ )Nr   )rÄ   r¹   )rX   r$   ÚoutputsrÇ   s       r2   r�   ÚEfficientLoFTRepVGG.forwardæ   s=   € ØˆØ—[”[ˆEÙ! -Ó0ˆMØ�N‰N˜=Ö)ñ !ð
 ˜!˜"�+ˆØˆr1   )rÄ   )r'   r(   r)   r*   r   rQ   r,   r…   Úlistr�   r0   r‡   rˆ   s   @r2   rÁ   rÁ   Ü   s5   ø† ð&Ð3÷ &ð U§\¡\ð °d¸5¿<¹<Ñ6H÷ ò r1   rÁ   c            	       ó¬   ^ • \ rS rSrS\4U 4S jjr S
S\R                  S\R                  S-  S\\R                  \R                  4   4S jjr	S	r
U =r$ )ÚEfficientLoFTRAggregationLayeréñ   rK   c           
      óD  >• [         TU ]  5         UR                  n[        R                  " UUUR
                  SUR                  SUS9U l        [        R                  R                  UR                  UR                  S9U l        [        R                  " U5      U l        g )Nr   F)r˜   r�   r™   rŽ   Úgroups)r˜   r™   )rP   rQ   r8   r   r�   rw   rx   Úq_aggregationr,   Ú	MaxPool2dÚkv_aggregation_kernel_sizeÚkv_aggregation_strideÚkv_aggregationÚ	LayerNormr“   )rX   rK   r8   rZ   s      €r2   rQ   Ú'EfficientLoFTRAggregationLayer.__init__ò   sŒ   ø€ Ü‰ÑÔà×(Ñ(ˆäŸYšYØØØ×8Ñ8ØØ×.Ñ.ØØñ
ˆÔô $Ÿh™h×0Ñ0Ø×9Ñ9À&×B^ÑB^ð 1ð 
ˆÔô —L’L Ó-ˆ�	r1   Nr$   Úencoder_hidden_statesr9   c                 ó  • UnUS LnU(       a  UOUnU R                  U5      nU R                  U5      nUR                  SSSS5      nUR                  SSSS5      nU R                  U5      nU R                  U5      nX4$ )Nr   r>   r   r   )rÒ   rÖ   Úpermuter“   )rX   r$   rÙ   Úquery_statesÚis_cross_attentionÚ	kv_statess         r2   r�   Ú&EfficientLoFTRAggregationLayer.forward  s�   € ð
 %ˆØ2¸$Ð>ÐÞ-?Ñ)À]ˆ	à×)Ñ)¨,Ó7ˆØ×'Ñ'¨	Ó2ˆ	Ø#×+Ñ+¨A¨q°!°QÓ7ˆØ×%Ñ% a¨¨A¨qÓ1ˆ	ØŸ	™	 ,Ó/ˆØ $§	¡	¨)Ó 4ÐØÐ3Ð3r1   )rÖ   r“   rÒ   rƒ   )r'   r(   r)   r*   r   rQ   r,   r…   r/   r�   r0   r‡   rˆ   s   @r2   rÎ   rÎ   ñ   sZ   ø† ð.Ð3÷ .ð, 6:ñ4à—|‘|ð4ð  %Ÿ|™|¨dÑ2ð4ð 
ˆu�|‰|˜UŸ\™\Ð)Ñ	*÷	4ó 4r1   rÎ   c                 ó|   • U SS S S24   nU SSS S24   n[         R                  " U* U/SS9R                  S5      nU$ )N.r>   r   r=   rt   ro   )r,   ÚstackÚflatten)rm   Úx1Úx2Úrot_xs       r2   Úrotate_halfræ     sL   € à	
ˆ3‘�!�ˆ8‰€BØ	
ˆ3���1�ˆ9‰€BÜ�KŠK˜"˜˜b˜	 rÑ*×2Ñ2°2Ó6€EØ€Lr1   c                 ó&  • U R                   nU R                  5       n UR                  5       nUR                  U5      nUR                  U5      nX-  [        U 5      U-  -   nX-  [        U5      U-  -   nUR	                  US9UR	                  US94$ )aI  Applies Rotary Position Embedding to the query and key tensors.

Args:
    q (`torch.Tensor`): The query tensor.
    k (`torch.Tensor`): The key tensor.
    cos (`torch.Tensor`): The cosine part of the rotary embedding.
    sin (`torch.Tensor`): The sine part of the rotary embedding.
    unsqueeze_dim (`int`, *optional*, defaults to 1):
        The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and
        sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note
        that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and
        k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes
        cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have
        the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2.
Returns:
    `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding.
r`   )r;   rf   rA   ræ   rg   )ÚqÚkr}   r|   Úunsqueeze_dimr;   Úq_embedÚk_embeds           r2   Úapply_rotary_pos_embrí   !  sŠ   € ð$ �G‰G€EØ	�‰‹	€AØ	�‰‹	€AØ
�-‰-˜Ó
&€CØ
�-‰-˜Ó
&€CØ‰wœ; q›>¨CÑ/Ñ0€GØ‰wœ; q›>¨CÑ/Ñ0€GØ�:‰:˜Eˆ:Ð" G§J¡J°U JÐ$;Ð;Ð;r1   r$   Ún_repc                 ó    • U R                   u  p#pEUS:X  a  U $ U SS2SS2SSS2SS24   R                  X#XU5      n U R                  X#U-  XE5      $ )zÈ
This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch,
num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim)
r   N)rv   ÚexpandÚreshape)r$   rî   ÚbatchÚnum_key_value_headsÚslenr_   s         r2   Ú	repeat_kvrõ   >  s_   € ð
 2?×1DÑ1DÑ.€E Ø�ƒzØÐØ!¢!¢Q¨ªa²Ð"2Ñ3×:Ñ:¸5ÐW\ÐdlÓm€MØ× Ñ  ¸eÑ(CÀTÓTÐTr1   ÚmoduleÚqueryÚkeyÚvalueÚattention_maskÚscalingÚdropoutrh   c                 ó  • [        X R                  5      n[        X0R                  5      n	[        R                  " XR	                  SS5      5      U-  n
Ub  X¤-   n
[
        R                  R                  U
S[        R                  S9R                  UR                  5      n
[
        R                  R                  X¦U R                  S9n
[        R                  " X©5      nUR	                  SS5      R                  5       nXº4$ )Nr>   r   r=   )rj   r;   )ÚpÚtrainingr   )rõ   Únum_key_value_groupsr,   ÚmatmulÚ	transposer   Ú
functionalÚsoftmaxÚfloat32rg   r;   rü   rÿ   Ú
contiguous)rö   r÷   rø   rù   rú   rû   rü   rh   Ú
key_statesÚvalue_statesÚattn_weightsÚattn_outputs               r2   Úeager_attention_forwardr  K  sÒ   € ô ˜3× ;Ñ ;Ó<€JÜ˜U×$?Ñ$?Ó@€Lä—<’< ×';Ñ';¸A¸qÓ'AÓBÀWÑL€LØÑ!Ø#Ñ4ˆä—=‘=×(Ñ(¨¸2ÄUÇ]Á]Ð(ÐS×VÑVÐW\×WbÑWbÓc€LÜ—=‘=×(Ñ(¨È6Ï?É?Ð(Ð[€LÜ—,’,˜|Ó:€KØ×'Ñ'¨¨1Ó-×8Ñ8Ó:€KàÐ$Ð$r1   c                   ó  ^ • \ rS rSrSrS\S\4U 4S jjr  SS\R                  S\R                  S-  S	\
\R                  \R                  4   S-  S
\\   S\
\R                  \R                  S-  4   4
S jjrSrU =r$ )ÚEfficientLoFTRAttentionid  z=Multi-headed attention from 'Attention Is All You Need' paperrK   Ú	layer_idxc                 óP  >• [         TU ]  5         Xl        X l        [	        USUR
                  UR                  -  5      U l        UR                  UR                  -  U l	        U R                  S-  U l
        UR                  U l        SU l        [        R                  " UR
                  UR                  U R                  -  UR                  S9U l        [        R                  " UR
                  UR                  U R                  -  UR                  S9U l        [        R                  " UR
                  UR                  U R                  -  UR                  S9U l        [        R                  " UR                  U R                  -  UR
                  UR                  S9U l        g )Nr_   g      à¿F©rŽ   )rP   rQ   rK   r  rb   r8   rc   r_   ró   r   rû   Úattention_dropoutÚ	is_causalr   ÚLinearÚattention_biasÚq_projÚk_projÚv_projÚo_proj©rX   rK   r  rZ   s      €r2   rQ   Ú EfficientLoFTRAttention.__init__g  sI  ø€ Ü‰ÑÔØŒØ"ŒÜ ¨
°F×4FÑ4FÈ&×JdÑJdÑ4dÓeˆŒØ$*×$>Ñ$>À&×B\ÑB\Ñ$\ˆÔ!Ø—}‘} dÑ*ˆŒØ!'×!9Ñ!9ˆÔØˆŒä—i’iØ×Ñ × :Ñ :¸T¿]¹]Ñ JÐQW×QfÑQfñ
ˆŒô —i’iØ×Ñ × :Ñ :¸T¿]¹]Ñ JÐQW×QfÑQfñ
ˆŒô —i’iØ×Ñ × :Ñ :¸T¿]¹]Ñ JÐQW×QfÑQfñ
ˆŒô —i’iØ×&Ñ&¨¯©Ñ6¸×8JÑ8JÐQW×QfÑQfñ
ˆ�r1   Nr$   rÙ   Úposition_embeddingsrh   r9   c                 óh  • UR                   u  pVnUR                   S S nU R                  U5      R                  XVSU5      n	Ub  UOUn
U R                  U
5      R                  XVSU5      nU R	                  U
5      R                  XVSU R
                  5      R                  SS5      nUb  Uu  pÞ[        X›XÞSS9u  p›U	R                  XVSU R
                  5      R                  SS5      n	UR                  XVSU R
                  5      R                  SS5      n[        R                  " U R                  R                  [        5      nU" U U	UU4S U R                  (       d  SOU R                  U R                  S.UD6u  nnUR                   " / UQSP76 R#                  5       nU R%                  U5      nUU4$ )Nr=   r   r>   )rê   ç        )rú   rü   rû   )rv   r  Úviewr  r  r_   r  rí   r   Úget_interfacerK   Ú_attn_implementationr  rÿ   r  rû   rñ   r  r  )rX   r$   rÙ   r  rh   Ú
batch_sizeÚseq_lenrj   Úinput_shaperÜ   Úcurrent_statesr  r  r}   r|   Úattention_interfacer
  r	  s                     r2   r�   ÚEfficientLoFTRAttention.forward~  s´  € ð $1×#6Ñ#6Ñ ˆ
˜SØ#×)Ñ)¨#¨2Ð.ˆà—{‘{ =Ó1×6Ñ6°zÈBÐPSÓTˆà2GÑ2SÑ.ÐYfˆØ—[‘[ Ó0×5Ñ5°jÈ2ÈsÓSˆ
Ø—{‘{ >Ó2×7Ñ7¸
ÈRÐQU×Q^ÑQ^Ó_×iÑiÐjkÐmnÓoˆàÑ*Ø*‰HˆCÜ';¸LÐVYÐnoÑ'pÑ$ˆLà#×(Ñ(¨¸bÀ$Ç-Á-ÓP×ZÑZÐ[\Ð^_Ó`ˆØ—_‘_ Z¸"¸d¿m¹mÓL×VÑVÐWXÐZ[Ó\ˆ
ä(?×(MÒ(MØ�K‰K×,Ñ,Ô.Eó)
Ðñ %8ØØØØð		%
ð
  Ø#Ÿ}Ÿ}‘C°$×2HÑ2HØ—L‘Lñ	%
ð ñ	%
Ñ!ˆ�\ð "×)Ò)Ð;¨;Ð;¸Ò;×FÑFÓHˆØ—k‘k +Ó.ˆØ˜LÐ(Ð(r1   )r  rK   r_   r  r  r  r   r  r  rû   r  rž   )r'   r(   r)   r*   r+   r   rd   rQ   r,   r…   r/   r   r   r�   r0   r‡   rˆ   s   @r2   r  r  d  s�   ø† ÙGð
Ð3ð 
À÷ 
ð4 6:ØHLñ	()à—|‘|ð()ð  %Ÿ|™|¨dÑ2ð()ð # 5§<¡<°·±Ð#=Ñ>ÀÑEð	()ð
 Ð+Ñ,ð()ð 
ˆu�|‰|˜UŸ\™\¨DÑ0Ð0Ñ	1÷()ó ()r1   r  c                   ój   ^ • \ rS rSrS\4U 4S jjrS\R                  S\R                  4S jrSr	U =r
$ )ÚEfficientLoFTRMLPi©  rK   c                 ó(  >• [         TU ]  5         UR                  nUR                  n[        R
                  " US-  USS9U l        [        UR                     U l	        [        R
                  " X2SS9U l
        [        R                  " U5      U l        g )Nr>   Fr  )rP   rQ   r8   Úintermediate_sizer   r  Úfc1r	   Úmlp_activation_functionr•   Úfc2r×   Ú
layer_norm©rX   rK   r8   r*  rZ   s       €r2   rQ   ÚEfficientLoFTRMLP.__init__ª  ss   ø€ Ü‰ÑÔØ×(Ñ(ˆØ"×4Ñ4ÐÜ—9’9˜[¨1™_Ð.?ÀeÑLˆŒÜ  ×!?Ñ!?Ñ@ˆŒÜ—9’9Ð.À%ÑHˆŒÜŸ,š, {Ó3ˆ�r1   r$   r9   c                 óŽ   • U R                  U5      nU R                  U5      nU R                  U5      nU R                  U5      nU$ rƒ   )r+  r•   r-  r.  )rX   r$   s     r2   r�   ÚEfficientLoFTRMLP.forward³  s@   € ØŸ™ Ó/ˆØŸ™¨Ó6ˆØŸ™ Ó/ˆØŸ™¨Ó6ˆØÐr1   )r•   r+  r-  r.  )r'   r(   r)   r*   r   rQ   r,   r…   r�   r0   r‡   rˆ   s   @r2   r(  r(  ©  s0   ø† ð4Ð3÷ 4ð U§\¡\ð °e·l±l÷ ò r1   r(  c                   óÚ   ^ • \ rS rSrS\S\4U 4S jjr  SS\R                  S\R                  S-  S\	\R                  \R                  4   S-  S	\
\   S
\R                  4
S jjrSrU =r$ )Ú!EfficientLoFTRAggregatedAttentioni»  rK   r  c                 ó¤   >• [         TU ]  5         UR                  U l        [        U5      U l        [        X5      U l        [        U5      U l        g rƒ   )	rP   rQ   rw   rÎ   Úaggregationr  Ú	attentionr(  Úmlpr  s      €r2   rQ   Ú*EfficientLoFTRAggregatedAttention.__init__¼  sA   ø€ Ü‰ÑÔà)/×)IÑ)IˆÔ&Ü9¸&ÓAˆÔÜ0°ÓCˆŒÜ$ VÓ,ˆ�r1   Nr$   rÙ   r  rh   r9   c                 ó<  • UR                   u  pV  nU R                  X5      u  p‰UR                   u  pzp·UR                  USU5      nU	R                  USU5      n	U R                  " UU	4SU0UD6u  pÇUR	                  SSS5      nUR                  XVX«5      n[
        R                  R                  R                  XÀR                  SSS9n[
        R                  " X/SS	9nUR	                  SSS
S5      nU R                  U5      nUR	                  SS
SS5      nX-   nU$ )Nr=   r  r   r>   r   ÚbilinearF©Úscale_factorÚmodeÚalign_cornersrt   r   )rv   r6  rñ   r7  rÛ   r,   r   r  Úinterpolaterw   Úcatr8  )rX   r$   rÙ   r  rh   r!  Ú	embed_dimÚ_Úaggregated_hidden_statesÚ aggregated_encoder_hidden_statesÚaggregated_hÚaggregated_wr
  Úintermediate_statesÚoutput_statess                  r2   r�   Ú)EfficientLoFTRAggregatedAttention.forwardÄ  sU  € ð '4×&9Ñ&9Ñ#ˆ
˜q !ð FJ×EUÑEUØóF
ÑBÐ ð ,D×+IÑ+IÑ(ˆ˜ð $<×#CÑ#CÀJÐPRÐT]Ó#^Ð Ø+K×+SÑ+SÐT^Ð`bÐdmÓ+nÐ(ØŸšØ$Ø,ñ
ð !4ð
ð ñ	
‰ˆð "×)Ñ)¨!¨Q°Ó2ˆØ!×)Ñ)¨*ÀÓ\ˆÜ—h‘h×)Ñ)×5Ñ5Ø×&DÑ&DÈ:Ðejð 6ð 
ˆô $Ÿiši¨Ð(DÈ!ÑLÐØ1×9Ñ9¸!¸QÀÀ1ÓEÐØŸ™Ð!4Ó5ˆØ%×-Ñ-¨a°°A°qÓ9ˆà%Ñ5ˆàÐr1   )r6  r7  r8  rw   rž   ©r'   r(   r)   r*   r   rd   rQ   r,   r…   r/   r   r   r�   r0   r‡   rˆ   s   @r2   r4  r4  »  s‡   ø† ð-Ð3ð -À÷ -ð 6:ØHLñ	'à—|‘|ð'ð  %Ÿ|™|¨dÑ2ð'ð # 5§<¡<°·±Ð#=Ñ>ÀÑEð	'ð
 Ð+Ñ,ð'ð 
�‰÷'ó 'r1   r4  c            	       óº   ^ • \ rS rSrS\S\4U 4S jjr SS\R                  S\	\R                  \R                  4   S-  S\
\   S	\R                  4S
 jjrSrU =r$ )Ú*EfficientLoFTRLocalFeatureTransformerLayeriî  rK   r  c                 ób   >• [         TU ]  5         [        X5      U l        [        X5      U l        g rƒ   )rP   rQ   r4  Úself_attentionÚcross_attentionr  s      €r2   rQ   Ú3EfficientLoFTRLocalFeatureTransformerLayer.__init__ï  s(   ø€ Ü‰ÑÔä?ÀÓRˆÔÜ@ÀÓSˆÕr1   Nr$   r  rh   r9   c                 ó:  • UR                   u  pEpgnUR                  SXgU5      nU R                  " U4SU0UD6nUR                  SSXgU5      nUS S 2S4   n	US S 2S4   n
U R                  " Xš40 UD6n	U R                  " X©40 UD6n
[        R
                  " Xš4SS9nU$ )Nr=   r  r>   r   r   rt   )rv   rñ   rO  rP  r,   rá   )rX   r$   r  rh   r!  rC  rB  ÚheightÚwidthÚ
features_0Ú
features_1s              r2   r�   Ú2EfficientLoFTRLocalFeatureTransformerLayer.forwardõ  sÀ   € ð 3@×2EÑ2EÑ/ˆ
�y¨%à%×-Ñ-¨b°)ÀUÓKˆØ×+Ò+¨MÑmÐObÐmÐflÑmˆð
 &×-Ñ-¨b°!°YÈÓNˆØ"¢1 a 4Ñ(ˆ
Ø"¢1 a 4Ñ(ˆ
Ø×)Ò)¨*ÑKÀFÑKˆ
Ø×)Ò)¨*ÑKÀFÑKˆ
ÜŸš ZÐ$<À!ÑDˆð Ðr1   )rP  rO  rƒ   rK  rˆ   s   @r2   rM  rM  î  sv   ø† ðTÐ3ð TÀ÷ Tð IMñà—|‘|ðð # 5§<¡<°·±Ð#=Ñ>ÀÑEðð Ð+Ñ,ð	ð
 
�‰÷ó r1   rM  c            	       ó¶   ^ • \ rS rSrS\4U 4S jjr SS\R                  S\\R                  \R                  4   S-  S\	\
   S\R                  4S	 jjrS
rU =r$ )Ú%EfficientLoFTRLocalFeatureTransformeri  rK   c           
      ó¸   >• [         TU ]  5         [        R                  " [	        UR
                  5       Vs/ s H  n[        XS9PM     sn5      U l        g s  snf )N)r  )rP   rQ   r   rµ   r·   Únum_attention_layersrM  Úlayers)rX   rK   ÚirZ   s      €r2   rQ   Ú.EfficientLoFTRLocalFeatureTransformer.__init__  sP   ø€ Ü‰ÑÔÜ—m’mô ˜v×:Ñ:Ô;óâ;�Aô ;¸6ÔOÙ;ñó
ˆ�ùòs   ·ANr$   r  rh   r9   c                 óB   • U R                    H  nU" U4SU0UD6nM     U$ )Nr  ©r\  )rX   r$   r  rh   Úlayers        r2   r�   Ú-EfficientLoFTRLocalFeatureTransformer.forward  s.   € ð —[”[ˆEÙ! -ÑcÐEXÐcÐ\bÑcŠMñ !àÐr1   r`  rƒ   )r'   r(   r)   r*   r   rQ   r,   r…   r/   r   r   r�   r0   r‡   rˆ   s   @r2   rY  rY    sl   ø† ð
Ð3÷ 
ð IMñà—|‘|ðð # 5§<¡<°·±Ð#=Ñ>ÀÑEðð Ð+Ñ,ð	ð
 
�‰÷ó r1   rY  c                   óŠ   ^ • \ rS rSrS\S\S\4U 4S jjrS\R                  S\R                  S\R                  4S	 jr	S
r
U =r$ )ÚEfficientLoFTROutConvBlocki#  rK   r8   r*  c           	      ó@  >• [         TU ]  5         [        R                  " X#SSSSS9U l        [        R                  " X3SSSSS9U l        [        R                  " U5      U l        [        UR                     " 5       U l
        [        R                  " X2SSSSS9U l        g )Nr   r   F©r˜   r™   r�   rŽ   r   )rP   rQ   r   r�   Ú	out_conv1Ú	out_conv2r‘   Ú
batch_normr   r,  r•   Ú	out_conv3r/  s       €r2   rQ   Ú#EfficientLoFTROutConvBlock.__init__$  sŠ   ø€ Ü‰ÑÔäŸš ;ÈqÐYZÐdeÐlqÑrˆŒÜŸšØ¸aÈÐSTÐ[`ñ
ˆŒô Ÿ.š.Ð):Ó;ˆŒÜ! &×"@Ñ"@ÒAÓCˆŒÜŸšÐ#4ÈqÐYZÐdeÐlqÑrˆ�r1   r$   Úresidual_statesr9   c                 óø   • U R                  U5      nX!-   nU R                  U5      nU R                  U5      nU R                  U5      nU R	                  U5      n[
        R                  R                  USSSS9nU$ ©Ng       @r;  Fr<  )rg  rh  ri  r•   rj  r   r  r@  )rX   r$   rl  s      r2   r�   Ú"EfficientLoFTROutConvBlock.forward/  sz   € ØŸ.™.¨Ó9ˆØ)Ñ9ˆØŸ.™.¨Ó9ˆØŸ/™/¨/Ó:ˆØŸ/™/¨/Ó:ˆØŸ.™.¨Ó9ˆÜŸ-™-×3Ñ3Ø¨#°JÈeð 4ð 
ˆð Ðr1   )r•   ri  rg  rh  rj  r¿   rˆ   s   @r2   rd  rd  #  sQ   ø† ð	sÐ3ð 	sÀ#ð 	sÐZ]÷ 	sð
 U§\¡\ð 
ÀEÇLÁLð 
ÐUZ×UaÑUa÷ 
ò 
r1   rd  c                   ó  ^ • \ rS rSrS\4U 4S jjrS\R                  S\\R                     S\R                  4S jr	S\R                  S	\\R                     \
\R                     -  S\
\R                  \R                  4   4S
 jrSrU =r$ )ÚEfficientLoFTRFineFusionLayeri<  rK   c           	      ón  >• [         TU ]  5         UR                  U l        UR                  n[        R
                  " US   US   SSSSS9U l        [        R                  " 5       U l        [        S[        U5      5       H2  n[        XU   X#S-
     5      nU R                  R                  U5        M4     g )Nr   r   Frf  )rP   rQ   Úfine_kernel_sizeÚfine_fusion_dimsr   r�   Úout_convrµ   Úout_conv_layersr·   rÅ   rd  r¹   )rX   rK   rt  r]  ru  rZ   s        €r2   rQ   Ú&EfficientLoFTRFineFusionLayer.__init__=  s¨   ø€ Ü‰ÑÔà &× 7Ñ 7ˆÔà!×2Ñ2ÐÜŸ	š	Ø˜QÑÐ!1°!Ñ!4À!ÈAÐWXÐ_dñ
ˆŒô  "Ÿ}š}›ˆÔÜ�qœ#Ð.Ó/Ö0ˆAÜ1°&È1Ñ:MÐO_ÐdeÑ`eÑOfÓgˆHØ× Ñ ×'Ñ'¨Ö1ò 1r1   r$   rl  r9   c                 óº   • U R                  U5      n[        R                  R                  USSSS9n[	        U R
                  5       H  u  p4U" XU   5      nM     U$ rn  )ru  r   r  r@  Ú	enumeraterv  )rX   r$   rl  r]  ra  s        r2   Úforward_pyramidÚ-EfficientLoFTRFineFusionLayer.forward_pyramidK  sd   € ð
 Ÿ™ mÓ4ˆÜŸ™×1Ñ1Ø¨°*ÈEð 2ð 
ˆô " $×"6Ñ"6Ö7‰HˆAÙ! -ÀÑ1CÓDŠMñ 8ð Ðr1   Úcoarse_featuresÚresidual_featuresc                 ó¾  • UR                   u  p4pVnUR                  SXVU5      n[        [        U5      5      nU R	                  X5      nUR                   u  pIp«UR                  USXšU5      nUSS2S4   nUSS2S4   n[        X¦-  5      n[        R                  R                  XÀR                  USS9nUR                   u    pOUR                  USU R                  S-  U5      nUR                  SSSS5      n[        R                  R                  XÐR                  S-   USS9nUR                  USU R                  S-   S-  U5      nUR                  SSSS5      nXÍ4$ )a  
For each image pair, compute the fine features of pixels.
In both images, compute a patch of fine features center cropped around each coarse pixel.
In the first image, the feature patch is kernel_size large and long.
In the second image, it is (kernel_size + 2) large and long.
r=   r>   Nr   r   r¥   r   )rv   rñ   rÌ   Úreversedrz  rd   r   r  Úunfoldrs  rÛ   )rX   r|  r}  r!  rC  rB  Úcoarse_heightÚcoarse_widthÚfine_featuresÚfine_embed_dimÚfine_heightÚ
fine_widthÚfine_features_0Úfine_features_1r™   r"  s                   r2   r�   Ú%EfficientLoFTRFineFusionLayer.forwardY  s‰  € ð AP×@UÑ@UÑ=ˆ
�y°à)×1Ñ1°"°iÐP\Ó]ˆÜ ¤Ð*;Ó!<Ó=Ðð ×,Ñ,¨_ÓPˆØ5B×5HÑ5HÑ2ˆ˜;à%×-Ñ-¨j¸!¸^ÐZdÓeˆØ'ª¨1¨Ñ-ˆØ'ª¨1¨Ñ-ˆô �[Ñ1Ó2ˆÜŸ-™-×.Ñ.Ø×)>Ñ)>ÀvÐWXð /ð 
ˆð (×-Ñ-‰ˆˆ1Ø)×1Ñ1°*¸bÀ$×BWÑBWÐYZÑBZÐ\cÓdˆØ)×1Ñ1°!°Q¸¸1Ó=ˆäŸ-™-×.Ñ.Ø×)>Ñ)>ÀÑ)BÈ6Ð[\ð /ð 
ˆð *×1Ñ1°*¸bÀ4×CXÑCXÐ[\ÑC\ÐabÑBbÐdkÓlˆØ)×1Ñ1°!°Q¸¸1Ó=ˆàÐ/Ð/r1   )rs  ru  rv  )r'   r(   r)   r*   r   rQ   r,   r…   rÌ   rz  r/   r�   r0   r‡   rˆ   s   @r2   rq  rq  <  s•   ø† ð2Ð3÷ 2ðà—|‘|ðð ˜eŸl™lÑ+ðð 
�‰ô	ð'0àŸ™ð'0ð   §¡Ñ-°°e·l±lÑ0CÑCð'0ð 
ˆu�|‰|˜UŸ\™\Ð)Ñ	*÷	'0ò '0r1   rq  c                   óÔ   ^ • \ rS rSrSr\rSrSrSr	Sr
SrSr\\S.r\R"                  " 5       S\R&                  S	S
4U 4S jj5       rS\R*                  S	\R*                  4S jrSrU =r$ )ÚEfficientLoFTRPreTrainedModeliƒ  zz
An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained
models.
ÚefficientloftrÚpixel_values)ÚimageT)r$   r%   rö   r9   Nc                 ó  >• [         TU ]  U5        [        U[        R                  5      (       aÑ  [
        R                  " UR                  SU R                  R                  S9  UR                  b   [
        R                  " UR                  5        [        USS5      ba  [
        R                  " UR                  5        [
        R                  " UR                  5        [
        R                  " UR                   5        ggg)zInitialize the weightsr  )ÚmeanÚstdNÚrunning_mean)rP   Ú_init_weightsry   r   r‘   ÚinitÚnormal_ÚweightrK   Úinitializer_rangerŽ   Úzeros_rb   r’  Úones_Úrunning_varÚnum_batches_tracked)rX   rö   rZ   s     €r2   r“  Ú+EfficientLoFTRPreTrainedModel._init_weights–  s«   ø€ ô 	‰Ñ˜fÔ%Ü�fœbŸn™n×-Ñ-Ü�LŠL˜Ÿ™¨S°d·k±k×6SÑ6SÒTØ�{‰{Ñ&Ü—’˜FŸK™KÔ(Ü�v˜~¨tÓ4Ñ@Ü—’˜F×/Ñ/Ô0Ü—
’
˜6×-Ñ-Ô.Ü—’˜F×6Ñ6Õ7ð Að	 .r1   c                 ó:   • USS2SSS2SS24   SS2SSS2SS24   $ )a  
Assuming pixel_values has shape (batch_size, 3, height, width), and that all channels values are the same,
extract the first channel value to get a tensor of shape (batch_size, 1, height, width) for EfficientLoFTR. This is
a workaround for the issue discussed in :
https://github.com/huggingface/transformers/pull/25786#issuecomment-1730176446

Args:
    pixel_values: torch.FloatTensor of shape (batch_size, 3, height, width)

Returns:
    pixel_values: torch.FloatTensor of shape (batch_size, 1, height, width)

Nr   r&   )rX   r�  s     r2   Ú extract_one_channel_pixel_valuesÚ>EfficientLoFTRPreTrainedModel.extract_one_channel_pixel_values¤  s$   € ð šA˜q¢!¢Q˜JÑ'ª¨4²²A¨Ñ6Ð6r1   r&   )r'   r(   r)   r*   r+   r   Úconfig_classÚbase_model_prefixÚmain_input_nameÚinput_modalitiesÚsupports_gradient_checkpointingÚ_supports_flash_attnÚ_supports_sdpar    r  Ú_can_record_outputsr,   r†   r   ÚModuler“  r-   rž  r0   r‡   rˆ   s   @r2   r‹  r‹  ƒ  s�   ø† ñð
 (€LØ(ÐØ$€OØ!ÐØ&*Ð#ØÐØ€Nà2Ø-ñÐð
 ‡]‚]ƒ_ð
8 B§I¡Ið 
8°$ö 
8ó ð
8ð7¸U×=NÑ=Nð 7ÐSX×SdÑSd÷ 7ò 7r1   r‹  za
    EfficientLoFTR model taking images as inputs and outputting the features of the images.
    c                   ó¢   ^ • \ rS rSrS\4U 4S jjr\\\ SS\	R                  S\	R                  S-  S\\   S\4S	 jj5       5       5       rS
rU =r$ )ÚEfficientLoFTRModeliµ  rK   c                 ó¬   >• [         TU ]  U5        Xl        [        U5      U l        [        U5      U l        [        US9U l        U R                  5         g )N)rK   )
rP   rQ   rK   rÁ   ÚbackbonerY  Úlocal_feature_transformerrH   Ú
rotary_embÚ	post_init©rX   rK   rZ   s     €r2   rQ   ÚEfficientLoFTRModel.__init__»  sD   ø€ Ü‰Ñ˜Ô àŒÜ+¨FÓ3ˆŒÜ)NÈvÓ)VˆÔ&Ü7¸vÑFˆŒà�‰Õr1   Nr�  Úlabelsrh   r9   c                 ó¤  • Ub  [        S5      eUR                  S:w  d  UR                  S5      S:w  a  [        S5      eUR                  u  pEpgnUR	                  US-  XgU5      nU R                  U5      nU R                  U5      n	U	S   n
U	SS nU
R                  SS u  pÍnU R                  U
5      u  nnUR                  US-  SSS5      R	                  US-  SU5      nUR                  US-  SSS5      R	                  US-  SU5      nUU4nU
R	                  USXÍU5      n
U R                  " U
4S	U0UD6n
U
4[        U5      -   n	[        U	S
9$ )áé  
Examples:

```python
>>> from transformers import AutoImageProcessor, AutoModel
>>> import torch
>>> from PIL import Image
>>> import httpx
>>> from io import BytesIO

>>> url = "https://github.com/magicleap/SuperGluePretrainedNetwork/blob/master/assets/phototourism_sample_images/london_bridge_78916675_4568141288.jpg?raw=true"
>>> with httpx.stream("GET", url) as response:
...     image1 = Image.open(BytesIO(response.read()))

>>> url = "https://github.com/magicleap/SuperGluePretrainedNetwork/blob/master/assets/phototourism_sample_images/london_bridge_19481797_2295892421.jpg?raw=true"
>>> with httpx.stream("GET", url) as response:
...     image2 = Image.open(BytesIO(response.read()))

>>> images = [image1, image2]

>>> processor = AutoImageProcessor.from_pretrained("zju-community/efficient_loftr")
>>> model = AutoModel.from_pretrained("zju-community/efficient_loftr")

>>> with torch.no_grad():
>>>     inputs = processor(images, return_tensors="pt")
>>>     outputs = model(**inputs)
```Nz>EfficientLoFTR is not trainable, no labels should be provided.é   r   r>   zOInput must be a 5D tensor of shape (batch_size, 2, num_channels, height, width)r=   éýÿÿÿr  )Úfeature_maps)Ú
ValueErrorÚndimÚsizerv   rñ   rž  r¬  r®  rð   r­  r/   r   )rX   r�  r²  rh   r!  rC  ÚchannelsrS  rT  Úfeaturesr|  r}  Úcoarse_embed_dimr�  r‚  r}   r|   r  s                     r2   r�   ÚEfficientLoFTRModel.forwardÅ  s‹  € ðH ÑÜÐ]Ó^Ð^à×Ñ Ó! \×%6Ñ%6°qÓ%9¸QÓ%>ÜÐnÓoÐoà1=×1CÑ1CÑ.ˆ
�x¨Ø#×+Ñ+¨J¸©N¸HÈeÓTˆØ×<Ñ<¸\ÓJˆð —=‘= Ó.ˆà" 2™,ˆà$ S b˜MÐØ8G×8MÑ8MÈbÈcÐ8RÑ5Ð¨ð —?‘? ?Ó3‰ˆˆSØ�j‰j˜ a™¨¨R°Ó4×<Ñ<¸ZÈ!¹^ÈRÐQaÓbˆØ�j‰j˜ a™¨¨R°Ó4×<Ñ<¸ZÈ!¹^ÈRÐQaÓbˆØ" C˜jÐà)×1Ñ1°*¸aÐAQÐbnÓoˆØ×8Ò8Øñ
Ø1Dð
ØHNñ
ˆð $Ð%¬Ð.?Ó(@Ñ@ˆä¨8Ñ4Ð4r1   )r¬  rK   r­  r®  rƒ   )r'   r(   r)   r*   r   rQ   r   r   r   r,   r-   Ú
LongTensorr   r   r   r�   r0   r‡   rˆ   s   @r2   rª  rª  µ  sv   ø† ðÐ3÷ ð  ØØð +/ñ?5à×'Ñ'ð?5ð × Ñ  4Ñ'ð?5ð Ð+Ñ,ð	?5ð
 
ô?5ó ó ó  ö?5r1   rª  ÚtensorÚborder_marginc                 ó  • US::  a  U $ X SS2SU24'   X SS2SS2SU24'   X SS2SS2SS2SU24'   X SS2SS2SS2SS2SU24'   X SS2U* S24'   X SS2SS2U* S24'   X SS2SS2SS2U* S24'   X SS2SS2SS2SS2U* S24'   U $ )aº  
Mask a tensor border with a given value

Args:
    tensor (`torch.Tensor` of shape `(batch_size, height_0, width_0, height_1, width_1)`):
        The tensor to mask
    border_margin (`int`) :
        The size of the border
    value (`Union[bool, int, float]`):
        The value to place in the tensor's borders

Returns:
    tensor (`torch.Tensor` of shape `(batch_size, height_0, width_0, height_1, width_1)`):
        The masked tensor
r   Nr&   )rÀ  rÁ  rù   s      r2   Úmask_borderrÃ  
  s¶   € ð  ˜ÓØˆà %Š1ˆnˆ}ˆnÐÑØ#(Š1Ša��-�ÐÑ Ø&+Š1Ša’�N�]�NÐ"Ñ#Ø).Š1Ša’’A�~˜�~Ð%Ñ&Ø!&Š1ˆ}ˆn‰oÐÑØ$)Š1Ša�-�‘Ð Ñ!Ø',Š1Ša’�]�N‘OÐ#Ñ$Ø*/Š1Ša’’A˜�~‘Ð&Ñ'à€Mr1   rS  rT  Únormalized_coordinatesr<   r;   c                 óD  • [         R                  " SUS-
  XUS9n[         R                  " SU S-
  XUS9nU(       a  XQS-
  -  S-
  S-  nX`S-
  -  S-
  S-  n[         R                  " [         R                  " XeSS9SS	9nUR	                  SSS5      R                  S5      nU$ )
aÃ  
Copied from kornia library : kornia/kornia/utils/grid.py:26

Generate a coordinate grid for an image.

When the flag ``normalized_coordinates`` is set to True, the grid is
normalized to be in the range :math:`[-1,1]` to be consistent with the pytorch
function :py:func:`torch.nn.functional.grid_sample`.

Args:
    height (`int`):
        The image height (rows).
    width (`int`):
        The image width (cols).
    normalized_coordinates (`bool`):
        Whether to normalize coordinates in the range :math:`[-1,1]` in order to be consistent with the
        PyTorch function :py:func:`torch.nn.functional.grid_sample`.
    device (`torch.device`):
        The device on which the grid will be generated.
    dtype (`torch.dtype`):
        The data type of the generated grid.

Return:
    grid (`torch.Tensor` of shape `(1, height, width, 2)`):
        The grid tensor.

Example:
    >>> create_meshgrid(2, 2)
    tensor([[[[-1., -1.],
              [ 1., -1.]],
    <BLANKLINE>
             [[-1.,  1.],
              [ 1.,  1.]]]])

    >>> create_meshgrid(2, 2, normalized_coordinates=False)
    tensor([[[[0., 0.],
              [1., 0.]],
    <BLANKLINE>
             [[0., 1.],
              [1., 1.]]]])

r   r   ru   ç      à?r>   Úij)Úindexingr=   rt   )r,   Úlinspacerá   ÚmeshgridrÛ   rA   )rS  rT  rÄ  r<   r;   ÚxsÚysÚgrids           r2   Úcreate_meshgridrÎ  )  s¡   € ôb 
�Š˜˜5 1™9 eÀ%Ñ	H€BÜ	�Š˜˜6 A™: vÀEÑ	J€BÞØ˜A‘IÑ Ñ$¨Ñ)ˆØ˜Q‘JÑ #Ñ%¨Ñ*ˆÜ�;Š;”u—~’~ b°tÑ<À"ÑE€DØ�<‰<˜˜1˜aÓ ×*Ñ*¨1Ó-€DØ€Kr1   Úinputc                 óª  • U R                   u  p#pE[        XEXR                  5      nUR                  U R                  5      nUS   R                  S5      nUS   R                  S5      nU R                  X#S5      n	[        R                  " X‰-  SSS9n
[        R                  " Xy-  SSS9n[        R                  " Xº/S5      nUR                  X#S5      $ )aø  
Copied from kornia library : kornia/geometry/subpix/dsnt.py:76
Compute the expectation of coordinate values using spatial probabilities.

The input heatmap is assumed to represent a valid spatial probability distribution,
which can be achieved using :func:`~kornia.geometry.subpixel.spatial_softmax2d`.

Args:
    input (`torch.Tensor` of shape `(batch_size, embed_dim, height, width)`):
        The input tensor representing dense spatial probabilities.
    normalized_coordinates (`bool`):
        Whether to return the coordinates normalized in the range of :math:`[-1, 1]`. Otherwise, it will return
        the coordinates in the range of the input shape.

Returns:
    output (`torch.Tensor` of shape `(batch_size, embed_dim, 2)`)
        Expected value of the 2D coordinates. Output order of the coordinates is (x, y).

Examples:
    >>> heatmaps = torch.tensor([[[
    ... [0., 0., 0.],
    ... [0., 0., 0.],
    ... [0., 1., 0.]]]])
    >>> spatial_expectation2d(heatmaps, False)
    tensor([[[1., 2.]]])

©.r   r=   ©.r   T©Úkeepdimr>   )
rv   rÎ  r<   rg   r;   rñ   r  r,   ÚsumrA  )rÏ  rÄ  r!  rB  rS  rT  rÍ  Úpos_xÚpos_yÚ
input_flatÚ
expected_yÚ
expected_xÚoutputs                r2   Úspatial_expectation2drÜ  d  s¿   € ð8 ,1¯;©;Ñ(€J˜6ô ˜6Ð*@Ç,Á,ÓO€DØ�7‰7�5—;‘;Ó€Dà�‰L× Ñ  Ó$€EØ�‰L× Ñ  Ó$€Eà—‘˜J°2Ó6€Jô —’˜5Ñ-¨r¸4Ñ@€JÜ—’˜5Ñ-¨r¸4Ñ@€Jä�YŠY˜
Ð/°Ó4€Fà�;‰;�z¨aÓ0Ð0r1   z[
    EfficientLoFTR model taking images as inputs and outputting the matching of them.
    c                   ó¾  ^ • \ rS rSrSrS\4U 4S jjrS\R                  S\	\R                  \R                  4   4S jr
S\R                  S	\S\	\R                  \R                  \R                  4   4S
 jrS\R                  S\R                  S\S\S\	\R                  \R                  4   4
S jrS\R                  S\R                  S\R                  S\S\S\R                  4S jrS\R                  S\R                  S\R                  S\S\R                  4
S jr\\ SS\R&                  S\R(                  S-  S\\   S\4S jj5       5       rSrU =r$ )Ú!EfficientLoFTRForKeypointMatchingi”  a¶  EfficientLoFTR dense image matcher

Given two images, we determine the correspondences by:
  1. Extracting coarse and fine features through a backbone
  2. Transforming coarse features through self and cross attention
  3. Matching coarse features to obtain coarse coordinates of matches
  4. Obtaining full resolution fine features by fusing transformed and backbone coarse features
  5. Refining the coarse matches using fine feature patches centered at each coarse match in a two-stage refinement

Yifan Wang, Xingyi He, Sida Peng, Dongli Tan and Xiaowei Zhou.
Efficient LoFTR: Semi-Dense Local Feature Matching with Sparse-Like Speed
In CVPR, 2024. https://huggingface.co/papers/2403.04765
rK   c                 ó�   >• [         TU ]  U5        Xl        [        U5      U l        [        U5      U l        U R                  5         g rƒ   )rP   rQ   rK   rª  rŒ  rq  Úrefinement_layerr¯  r°  s     €r2   rQ   Ú*EfficientLoFTRForKeypointMatching.__init__¨  s9   ø€ Ü‰Ñ˜Ô àŒÜ1°&Ó9ˆÔÜ =¸fÓ EˆÔà�‰Õr1   Úscoresr9   c                 ó¢  • UR                   u  p#pEnUR                  X#U-  XV-  5      nUR                  SSS9R                  nUR                  SSS9R                  nXR                  R
                  :„  n	U	R                  X#XEU5      n	[        X�R                  R                  S5      n	U	R                  X#U-  XV-  5      n	X‘U:H  -  X:H  -  n	X-  n
U
R                  S5      u  p¼U
R                  S5      u  pÞ[        R                  " XÎ/5      R                  USS5      n[        R                  " X½/SS9n[        R                  " US:„  US5      nUU4$ )	aé  
Based on a keypoint score matrix, compute the best keypoint matches between the first and second image.
Since each image pair can have different number of matches, the matches are concatenated together for all pair
in the batch and a batch_indices tensor is returned to specify which match belong to which element in the batch.

Note:
    This step can be done as a postprocessing step, because does not involve any model weights/params.
    However, we keep it in the modeling code for consistency with other keypoint matching models AND for
    easier torch.compile/torch.export (all ops are in torch).

Args:
    scores (`torch.Tensor` of shape `(batch_size, height_0, width_0, height_1, width_1)`):
        Scores of keypoints

Returns:
    matched_indices (`torch.Tensor` of shape `(2, num_matches)`):
        Indices representing which pixel in the first image matches which pixel in the second image
    matching_scores (`torch.Tensor` of shape `(num_matches,)`):
        Scores of each match
r>   TrÓ  r   Fr=   rt   r   )rv   r  ÚmaxÚvaluesrK   Úcoarse_matching_thresholdrñ   rÃ  Úcoarse_matching_border_removalr,   rA  rá   Úwhere)rX   râ  r!  Úheight0Úwidth0Úheight1Úwidth1Úmax_0Úmax_1ÚmaskÚmasked_scoresÚmatching_scores_0Úmax_indices_0Úmatching_scores_1Úmax_indices_1Úmatching_indicesr"   s                    r2   Ú_get_matches_from_scoresÚ:EfficientLoFTRForKeypointMatching._get_matches_from_scores±  sX  € ð* 8>·|±|Ñ4ˆ
˜V¨fà—‘˜Z°6Ñ)9¸7Ñ;KÓLˆð —
‘
˜1 d�
Ð+×2Ñ2ˆØ—
‘
˜1 d�
Ð+×2Ñ2ˆð Ÿ™×=Ñ=Ñ=ˆð �|‰|˜J°À&ÓIˆÜ˜4§¡×!KÑ!KÈUÓSˆØ�|‰|˜J°&Ñ(8¸'Ñ:JÓKˆð  ‘Ñ'¨6©?Ñ;ˆð ™ˆØ+8×+<Ñ+<¸QÓ+?Ñ(ÐØ+8×+<Ñ+<¸QÓ+?Ñ(Ðä Ÿ9š9 mÐ%CÓD×LÑLÈZÐYZÐ\^Ó_ÐÜŸ+š+Ð'8Ð&LÐRSÑTˆô !Ÿ;š; ¸Ñ':Ð<LÈbÓQÐà Ð0Ð0r1   r|  Úcoarse_scalec                 ó¢  • UR                   u  p4pVnUR                  SSSSS5      nUR                  USSU5      nXR                   S   S-  -  nUSS2S4   nUSS2S4   n	X‰R                  SS	5      -  n
X R                  R
                  -  n
U R                  R                  (       a  U
nOA[        R                  R                  U
S5      [        R                  R                  U
S5      -  nUR                  X6XvU5      nU R                  U5      u  pÍ[        R                  " X|R                  S
9n[        R                  " XÎ-  XÎ-  /SS9U-  nXýU4$ )a|  
For each image pair, compute the matching confidence between each coarse element (by default (image_height / 8)
* (image_width / 8 elements)) from the first image to the second image.

Note:
    This step can be done as a postprocessing step, because does not involve any model weights/params.
    However, we keep it in the modeling code for consistency with other keypoint matching models AND for
    easier torch.compile/torch.export (all ops are in torch).

Args:
    coarse_features (`torch.Tensor` of shape `(batch_size, 2, hidden_size, coarse_height, coarse_width)`):
        Coarse features
    coarse_scale (`float`): Scale between the image size and the coarse size

Returns:
    keypoints (`torch.Tensor` of shape `(batch_size, 2, num_matches, 2)`):
        Keypoints coordinates.
    matching_scores (`torch.Tensor` of shape `(batch_size, 2, num_matches)`):
        The confidence matching score of each keypoint.
    matched_indices (`torch.Tensor` of shape `(batch_size, 2, num_matches)`):
        Indices which indicates which keypoint in an image matched with which keypoint in the other image. For
        both image in the pair.
r   r   r   é   r>   r=   rÆ  Nro   ©r<   rt   )rv   rÛ   rñ   r  rK   Úcoarse_matching_temperatureÚcoarse_matching_skip_softmaxr   r  r  r  rö  r,   rÀ  r<   rá   )rX   r|  rø  r!  rC  rB  rS  rT  Úcoarse_features_0Úcoarse_features_1Ú
similarityÚ
confidenceÚmatched_indicesr"   Úwidth_tr#   s                   r2   Ú_coarse_matchingÚ2EfficientLoFTRForKeypointMatching._coarse_matchingæ  sJ  € ð4 3B×2GÑ2GÑ/ˆ
�y¨%ð *×1Ñ1°!°Q¸¸1¸aÓ@ˆØ)×1Ñ1°*¸aÀÀYÓOˆà)×,AÑ,AÀ"Ñ,EÈÑ,LÑLˆØ+ªA¨q¨DÑ1ÐØ+ªA¨q¨DÑ1Ðà&×)DÑ)DÀRÈÓ)LÑLˆ
Ø§+¡+×"IÑ"IÑIˆ
à�;‰;×3×3Ø#‰JäŸ™×.Ñ.¨z¸1Ó=ÄÇÁ×@UÑ@UÐV`ÐbcÓ@dÑdˆJà—_‘_ Z¸ÈÓNˆ
Ø+/×+HÑ+HÈÓ+TÑ(ˆä—,’,˜u×-CÑ-CÑDˆä—K’K Ñ!:¸OÑ<VÐ WÐ]_Ñ`ÐcoÑoˆ	à¨?Ð:Ð:r1   Úfine_confidenceÚcoarse_matched_keypointsÚfine_window_sizeÚ
fine_scalec           
      ó  • UR                   u  pV  n[        US-  5      nUR                  XVS5      n[        R                  " USS9u  pšU
S   n
X£-  nX£-  n[        UUSUR                  UR                  S9nXØS-  -
  S-   nUR                  SSSS5      R                  XVSS5      n[        R                  " USUR                  S5      R                  SSSS5      5      R                  S5      n[        R                  " USUR                  S5      R                  SSSS5      5      R                  S5      nUS	S	2S
4   Xä-  -   nUS	S	2S4   Xô-  -   n[        R                  " X¼/SS9n
[        R                  " UU/SS9nU
U4$ )aØ  
For each coarse pixel, retrieve the highest fine confidence score and index.
The index represents the matching between a pixel position in the fine window in the first image and a pixel
position in the fine window of the second image.
For example, for a fine_window_size of 64 (8 * 8), the index 2474 represents the matching between the index 38
(2474 // 64) in the fine window of the first image, and the index 42 in the second image. This means that 38
which corresponds to the position (4, 6) (4 // 8 and 4 % 8) is matched with the position (5, 2). In this example
the coarse matched coordinate will be shifted to the matched fine coordinates in the first and second image.

Note:
    This step can be done as a postprocessing step, because does not involve any model weights/params.
    However, we keep it in the modeling code for consistency with other keypoint matching models AND for
    easier torch.compile/torch.export (all ops are in torch).

Args:
    fine_confidence (`torch.Tensor` of shape `(num_matches, fine_window_size, fine_window_size)`):
        First stage confidence of matching fine features between the first and the second image
    coarse_matched_keypoints (`torch.Tensor` of shape `(2, num_matches, 2)`):
        Coarse matched keypoint between the first and the second image.
    fine_window_size (`int`):
        Size of the window used to refine matches
    fine_scale (`float`):
        Scale between the size of fine features and coarse features

Returns:
    indices (`torch.Tensor` of shape `(2, num_matches, 1)`):
        Indices of the fine coordinate matched in the fine window
    fine_matches (`torch.Tensor` of shape `(2, num_matches, 2)`):
        Coordinates of matched keypoints after the first fine stage
rÆ  r=   rt   ©.NF)rÄ  r<   r;   r>   r   Nr   )rv   r   rñ   r,   rä  rÎ  r<   r;   rð   ÚgatherrA   Úsqueezerá   )rX   r  r  r  r	  r!  Únum_keypointsrC  rs  rå  ÚindicesÚ	indices_0Ú	indices_1rÍ  Údelta_0Údelta_1Úfine_matches_0Úfine_matches_1Úfine_matchess                      r2   Ú_get_first_stage_fine_matchingÚ@EfficientLoFTRForKeypointMatching._get_first_stage_fine_matching  s—  € ðJ +:×*?Ñ*?Ñ'ˆ
 1 aÜ$Ð%5°sÑ%:Ó;Ðà)×1Ñ1°*ÈRÓPˆÜŸ)š) O¸Ñ<‰ˆØ˜)Ñ$ˆØÑ/ˆ	ØÑ.ˆ	äØØØ#(Ø"×)Ñ)Ø!×'Ñ'ñ
ˆð ¨1Ñ,Ñ-°Ñ3ˆØ�|‰|˜A˜q " aÓ(×/Ñ/°
È2ÈrÓRˆÜ—,’,˜t Q¨	×(;Ñ(;¸BÓ(?×(FÑ(FÀrÈ2ÈrÐSTÓ(UÓV×^Ñ^Ð_`ÓaˆÜ—,’,˜t Q¨	×(;Ñ(;¸BÓ(?×(FÑ(FÀrÈ2ÈrÐSTÓ(UÓV×^Ñ^Ð_`Óaˆà1²!°Q°$Ñ7¸'Ñ:NÑNˆØ1²!°Q°$Ñ7¸'Ñ:NÑNˆä—+’+˜yÐ4¸!Ñ<ˆÜ—{’{ N°NÐ#CÈÑKˆà˜Ð$Ð$r1   r  r  c                 ó–  • UR                   u  pg  n[        US-  5      n	USS2S4   n
USS2S4   n[        R                  " X›R                  S9nX¼-  nX¼-  n[        R
                  " XjR                  S9R                  USSS5      n[        R
                  " XzR                  S9R                  SUSS5      nU
S   n
US   nUS   n[        SSSU
R                  S	9R                  [        R                  5      nUS
   nUUS   -   nUUS   -   nUR                  XgXIS-   U	S-   5      nX?UX­U4   nUR                  XgS5      n[        R                  R                  X0R                  R                  -  SS9nUR                  XgSS5      n[        US5      S   nUSS2S4   nUSS2S4   US-  U-  -   n[        R                   " UU/SS9nU$ )aL  
For the given position in their respective fine windows, retrieve the 3x3 fine confidences around this position.
After applying softmax to these confidences, compute the 2D spatial expected coordinates.
Shift the first stage fine matching with these expected coordinates.

Note:
    This step can be done as a postprocessing step, because does not involve any model weights/params.
    However, we keep it in the modeling code for consistency with other keypoint matching models AND for
    easier torch.compile/torch.export (all ops are in torch).

Args:
    indices (`torch.Tensor` of shape `(batch_size, 2, num_keypoints)`):
        Indices representing the position of each keypoint in the fine window
    fine_matches (`torch.Tensor` of shape `(2, num_matches, 2)`):
        Coordinates of matched keypoints after the first fine stage
    fine_confidence (`torch.Tensor` of shape `(num_matches, fine_window_size, fine_window_size)`):
        Second stage confidence of matching fine features between the first and the second image
    fine_window_size (`int`):
        Size of the window used to refine matches
    fine_scale (`float`):
        Scale between the size of fine features and coarse features

Returns:
    fine_matches (`torch.Tensor` of shape `(2, num_matches, 2)`):
        Coordinates of matched keypoints after the second fine stage
rÆ  Nr   r   rû  r  r   T)rÄ  r<   )N.rÒ  rÑ  r>   é	   r=   rt   )rv   r   r,   rÀ  r<   re   rñ   rÎ  rg   Úlongr   r  r  rK   Ú!fine_matching_regress_temperaturerÜ  rá   )rX   r  r  r  r  r	  r!  r  rC  rs  r  r  Úfine_kernel_size_tÚindices_1_iÚindices_1_jÚbatch_indicesÚmatches_indicesÚdeltaÚheatmapÚfine_coordinates_normalizedr  r  s                         r2   Ú_get_second_stage_fine_matchingÚAEfficientLoFTRForKeypointMatching._get_second_stage_fine_matching]  s  € ðD +:×*?Ñ*?Ñ'ˆ
 1 aÜ$Ð%5°sÑ%:Ó;ÐàšA˜q˜D‘Mˆ	ØšA˜q˜D‘Mˆ	Ü"Ÿ\š\Ð*:×CSÑCSÑTÐàÑ5ˆØÑ4ˆô Ÿš Z×8HÑ8HÑI×QÑQÐR\Ð^_ÐabÐdeÓfˆÜŸ,š, }×=MÑ=MÑN×VÑVÐWXÐZgÐijÐlmÓnˆØ˜iÑ(ˆ	Ø! )Ñ,ˆØ! )Ñ,ˆä  1¸TÈ)×JZÑJZÑ[×^Ñ^Ô_d×_iÑ_iÓjˆØ�iÑ ˆà! E¨&¡MÑ1ˆØ! E¨&¡MÑ1ˆà)×1Ñ1ØÐ'7ÈAÑ9MÐO_ÐbcÑOcó
ˆð *¸È)ÐbmÐ*mÑnˆØ)×1Ñ1°*ÈQÓOˆÜŸ-™-×/Ñ/ØŸk™k×KÑKÑKÐQSð 0ð 
ˆð "×)Ñ)¨*ÀQÈÓJˆÜ&;¸GÀTÓ&JÈ1Ñ&MÐ#à%¢a¨ dÑ+ˆØ%¢a¨ dÑ+Ð/JÈfÑ/UÐXbÑ/bÑcˆä—{’{ N°NÐ#CÈÑKˆàÐr1   r‡  rˆ  c                 óò  • UR                   u  pVpxU R                  R                  n	[        US-  5      n
[        R
                  " XU	-
  S5      n[        R
                  " X(U	-
  S5      nUS   nUS   nXR                   S   S-  -  nX"R                   S   S-  -  nXR                  SS5      -  n[        R                  R                  US5      [        R                  R                  US5      -  nUR                  XVXzS-   U
S-   5      nUSSS2SS24   nUR                  XVXw5      nU R                  UUUU5      u  nnUS   nUS   nX)S-  -  nXR                  SS5      -  nU R                  UUUUU5      nU$ )aü  
For each coarse pixel with a corresponding window of fine features, compute the matching confidence between fine
features in the first image and the second image.

Fine features are sliced in two part :
- The first part used for the first stage are the first fine_hidden_size - config.fine_matching_slicedim (64 - 8
 = 56 by default) features.
- The second part used for the second stage are the last config.fine_matching_slicedim (8 by default) features.

Each part is used to compute a fine confidence tensor of the following shape :
(batch_size, (coarse_height * coarse_width), fine_window_size, fine_window_size)
They correspond to the score between each fine pixel in the first image and each fine pixel in the second image.

Args:
    fine_features_0 (`torch.Tensor` of shape `(num_matches, fine_kernel_size ** 2, fine_kernel_size ** 2)`):
        Fine features from the first image
    fine_features_1 (`torch.Tensor` of shape `(num_matches, (fine_kernel_size + 2) ** 2, (fine_kernel_size + 2)
    ** 2)`):
        Fine features from the second image
    coarse_matched_keypoints (`torch.Tensor` of shape `(2, num_matches, 2)`):
        Keypoint coordinates found in coarse matching for the first and second image
    fine_scale (`int`):
        Scale between the size of fine features and coarse features

Returns:
    fine_coordinates (`torch.Tensor` of shape `(2, num_matches, 2)`):
        Matched keypoint between the first and the second image. All matched keypoints are concatenated in the
        second dimension.

rÆ  r=   r   ro   r   r>   .)rv   rK   Úfine_matching_slice_dimr   r,   Úsplitr  r   r  r  rñ   r  r%  )rX   r‡  rˆ  r  r	  r!  r  r  r„  r(  rs  Úsplit_fine_features_0Úsplit_fine_features_1r  Úfirst_stage_fine_confidenceÚfine_indicesr  Úsecond_stage_fine_confidenceÚfine_coordinatess                      r2   Ú_fine_matchingÚ0EfficientLoFTRForKeypointMatching._fine_matchingª  s×  € ðJ GV×F[ÑF[ÑCˆ
Ð#3Ø"&§+¡+×"EÑ"EÐä$Ð%5°sÑ%:Ó;Ðô !&§¢¨OÐNeÑ=eÐgiÓ jÐÜ %§¢¨OÐNeÑ=eÐgiÓ jÐð 0°Ñ2ˆØ/°Ñ2ˆð *×,AÑ,AÀ"Ñ,EÈÑ,LÑLˆØ)×,AÑ,AÀ"Ñ,EÈÑ,LÑLˆð *×,EÑ,EÀbÈ"Ó,MÑMˆÜŸ-™-×/Ñ/°ÀÓCÄbÇmÁm×F[ÑF[Ð\kÐmnÓFoÑoˆØ)×1Ñ1ØÐ'7ÈAÑ9MÐO_ÐbcÑOcó
ˆð *¨#¨q°¨t°Q°r°T¨/Ñ:ˆØ&5×&=Ñ&=ØÐ'7ó'
Ð#ð &*×%HÑ%HØ'Ø$ØØó	&
Ñ"ˆ�lð 0°Ñ2ˆØ/°Ñ2ˆð *ÀSÑ,HÑHˆð (7×9RÑ9RÐSUÐWYÓ9ZÑ'ZÐ$à×?Ñ?ØØØ(ØØó
Ðð  Ðr1   Nr�  r²  rh   c           	      óà  • Ub  [        S5      eU R                  " U40 UD6nUR                  nUS   nUR                  SS u  pxn	UR                  u  p«pÍnXØ-  nU R	                  Xo5      u  nnnUSS nX`R
                  R                  S-  -  nU R                  UU5      u  nnUR                  u    nn[        R                  " U
5      S   nUUUSS2S4   4   nUUUSS2S4   4   n[        X�-  5      nUU-  nU R                  UUUU5      nUSS2SS2SS2S4   U-  USS2SS2SS2S4'   USS2SS2SS2S4   U-  USS2SS2SS2S4'   Sn[        UUUUUR                  UR                  S9$ )	r´  Nz9SuperGlue is not trainable, no labels should be provided.r   r¶  r   rÆ  r  )r    r!   r"   r#   r$   r%   )r¸  rŒ  r·  rv   r  rK   r8   rà  r,   re   r   r0  r   r$   r%   )rX   r�  r²  rh   Úmodel_outputsr¼  r|  r½  r�  r‚  r!  rC  r»  rS  rT  rø  Úcoarse_keypointsÚcoarse_matching_scoresÚcoarse_matched_indicesr}  r‡  rˆ  r  r   r…  r	  Úmatching_keypointsr    s                               r2   r�   Ú)EfficientLoFTRForKeypointMatching.forward  sÜ  € ðF ÑÜÐXÓYÐYð )-×(;Ò(;¸LÑ(SÈFÑ(SˆØ ×-Ñ-ˆð # 1™+ˆØ8G×8MÑ8MÈbÈcÐ8RÑ5Ð¨Ø1=×1CÑ1CÑ.ˆ
�x¨ØÑ-ˆØKO×K`ÑK`ØóL
ÑHÐÐ0Ð2Hð
 % Q R˜LÐØ)¯K©K×,CÑ,CÀSÑ,HÑHˆØ+/×+@Ñ+@ÀÐRcÓ+dÑ(ˆ˜ð 5×:Ñ:Ñˆˆ1ˆmÜŸš ZÓ0°Ñ;ˆØ)¨-Ð9OÒPQÐSTÐPTÑ9UÐ*UÑVˆØ)¨-Ð9OÒPQÐSTÐPTÑ9UÐ*UÑVˆô   Ñ <Ó=ˆØ˜kÑ)ˆ
Ø!×0Ñ0°À/ÐScÐeoÓpÐà);ºAºqÂ!ÀQ¸JÑ)GÈ%Ñ)OÐš1ša¢ A˜:Ñ&Ø);ºAºqÂ!ÀQ¸JÑ)GÈ&Ñ)PÐš1ša¢ A˜:Ñ&àˆÜ3ØØ*Ø2Ø(Ø'×5Ñ5Ø$×/Ñ/ñ
ð 	
r1   )rK   rŒ  rà  rƒ   )r'   r(   r)   r*   r+   r   rQ   r,   r…   r/   rö  rf   r  rd   r  r%  r0  r   r   r-   r¿  r   r   r   r�   r0   r‡   rˆ   s   @r2   rÞ  rÞ  ”  sÙ  ø† ñðÐ3÷ ð31¨u¯|©|ð 31ÀÀeÇlÁlÐTY×T`ÑT`ÐF`Ñ@aô 31ðj3;Ø$Ÿ|™|ð3;Ø;@ð3;à	ˆu�|‰|˜UŸ\™\¨5¯<©<Ð7Ñ	8ô3;ðj@%àŸ™ð@%ð #(§,¡,ð@%ð ð	@%ð
 ð@%ð 
ˆu�|‰|˜UŸ\™\Ð)Ñ	*ô@%ðDKà—‘ðKð —l‘lðKð Ÿ™ð	Kð
 ðKð ðKð 
�‰ôKðZZ àŸ™ðZ ð Ÿ™ðZ ð #(§,¡,ð	Z ð
 ðZ ð 
�‰ôZ ðx Øð +/ñL
à×'Ñ'ðL
ð × Ñ  4Ñ'ðL
ð Ð+Ñ,ð	L
ð
 
.ôL
ó ó öL
r1   rÞ  )r‹  rª  rÞ  )r   )r  )FNN)T)IÚcollections.abcr   Údataclassesr   r,   r   Ú r   r”  Úactivationsr   r	   Úmodeling_layersr
   Úmodeling_outputsr   Úmodeling_rope_utilsr   Úmodeling_utilsr   r   Úprocessing_utilsr   Úpytorch_utilsr   Úutilsr   r   r   r   r   Úutils.deprecationr   Úutils.genericr   r   Úutils.output_capturingr   Úconfiguration_efficientloftrr   r   r…   rd   rF   r¨  rH   rŠ   r    r²   rÁ   rÎ   ræ   rí   rõ   rf   r  r  r(  r4  rM  rY  rd  rq  r‹  rª  ÚboolrÃ  r<   r;   rÎ  rÜ  rÞ  Ú__all__r&   r1   r2   Ú<module>rJ     sy  ðõ %Ý !ã Ý å &ß *Ý 9Ý .Ý 6ß FÝ &Ý @÷õ õ 1ß GÝ 5Ý >ñ ðñð ô7¨;ó 7ó óð7ñ6 %¨RÑ0ð
 §¡ð 
¸Sð 
Èsð 
Ðadð 
Ðin×iuÑiuó 
ó 1ð
ô8 B§I¡Iô 8ôx "§)¡)ô ô*Ð :ô ô< §	¡	ô ô&˜"Ÿ)™)ô ô*#4 R§Y¡Yô #4òNô<ð:	U˜UŸ\™\ð 	U°#ð 	U¸%¿,¹,ô 	Uð( ñ%Ø�I‰Ið%à�<‰<ð%ð 
�‰ð%ð �<‰<ð	%ð
 —L‘L 4Ñ'ð%ð ð%ð ð%ð Ð'Ñ(õ%ô2B)˜bŸi™iô B)ôJ˜Ÿ	™	ô ô$0¨¯	©	ô 0ôfÐ1Kô ô@¨B¯I©Iô ô* §¡ô ô2D0 B§I¡Iô D0ðN ô.7 Oó .7ó ð.7ñb ðñô
M5Ð7ó M5óð
M5ð`˜Ÿ™ð °Sð ÀÈÁÐPSÑASð ÐX]×XdÑXdô ðD $)Ø"&Ø $ñ8Ø�%—,‘,Ñð8à�—‘Ñð8ð !ð8ð �L‰L˜4Ñð	8ð
 �;‰;˜Ñð8ð ‡\�\õ8ñv-1 §¡ð -1Àtð -1ÐW\×WcÑWcõ -1ñ` ðñô
{
Ð(Eó {
óð
{
ò| h�r1   