Ë
    éÓ^jí,  ã                   óÐ   — d Z ddlmZmZmZmZ ddlZddlmZ ddlmc m	Z
 ddlmZ ddlmZ ddlmZ d	ee   fd
„Z G d„ dej&                  «      Z G d„ dej&                  «      Zy)a]   Halo Self Attention

Paper: `Scaling Local Self-Attention for Parameter Efficient Visual Backbones`
    - https://arxiv.org/abs/2103.12731

@misc{2103.12731,
Author = {Ashish Vaswani and Prajit Ramachandran and Aravind Srinivas and Niki Parmar and Blake Hechtman and
    Jonathon Shlens},
Title = {Scaling Local Self-Attention for Parameter Efficient Visual Backbones},
Year = {2021},
}

Status:
This impl is a WIP, there is no official ref impl and some details in paper weren't clear to me.
The attention mechanism works but it's slow as implemented.

Hacked together by / Copyright 2021 Ross Wightman
é    )ÚListÚOptionalÚTupleÚUnionN)Únné   )Úmake_divisible)Útrunc_normal_)Ú_assertÚpermute_maskc                 óæ  — | j                   \  }}}}|j                   d   }|dz   dz  }| |j                  dd«      z  }	|	j                  d||«      }	t        j                  |	ddg«      j                  d«      }
t        j                  |
d||z
  g«      }
|
j                  d|dz   |«      }
|
dd…d|…|dz
  d…f   }	|	j                  ||d||«      j                  dd|dd«      }	|	j                  |«      S )a~   Compute relative logits along one dimension

    As per: https://gist.github.com/aravindsrinivas/56359b79f0ce4449bcb04ab4b56a57a2
    Originally from: `Attention Augmented Convolutional Networks` - https://arxiv.org/abs/1904.09925

    Args:
        q: (batch, height, width, dim)
        rel_k: (2 * window - 1, dim)
        permute_mask: permute output dim according to this
    r   r   é   éÿÿÿÿéþÿÿÿN)ÚshapeÚ	transposeÚreshapeÚFÚpadÚflattenÚexpandÚpermute)ÚqÚrel_kr   ÚBÚHÚWÚdimÚrel_sizeÚwin_sizeÚxÚx_pads              ú`/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/timm/layers/halo_attn.pyÚrel_logits_1dr$      sþ   € ð —7‘7�L€A€qˆ!ˆSØ�{‰{˜1‰~€HØ˜1‘ Ñ"€Hà	
ˆU�_‰_˜R Ó$Ñ	$€AØ	�	‰	�"�a˜Ó"€Aô �E‰E�!�a˜�VÓ×$Ñ$ QÓ'€EÜ�E‰E�%˜!˜X¨™\Ð*Ó+€Eð �M‰M˜"˜a !™e XÓ.€EØŠa��!��X ‘\‘]Ð"Ñ#€Að 	
�	‰	�!�Q˜˜1˜hÓ'×.Ñ.¨r°2°xÀÀRÓH€AØ�9‰9�\Ó"Ð"ó    c            	       óF   ‡ — e Zd ZdZ	 	 d	dedededefˆ fd„Zd„ Zd„ Zˆ xZ	S )
ÚPosEmbedRelzÜ Relative Position Embedding
    As per: https://gist.github.com/aravindsrinivas/56359b79f0ce4449bcb04ab4b56a57a2
    Originally from: `Attention Augmented Convolutional Networks` - https://arxiv.org/abs/1904.09925

    Ú
block_sizer    Údim_headÚscalec                 óJ  •— ||dœ}t         ‰| �  «        || _        || _        || _        t        j                  t        j                  |dz  dz
  |fi |¤Ž«      | _	        t        j                  t        j                  |dz  dz
  |fi |¤Ž«      | _
        | j                  «        y)z¾
        Args:
            block_size: block size
            win_size: neighbourhood window size
            dim_head: attention head dim
            scale: scale factor (for init)
        ©ÚdeviceÚdtyper   r   N)ÚsuperÚ__init__r(   r)   r*   r   Ú	ParameterÚtorchÚemptyÚ
height_relÚ	width_relÚreset_parameters)	Úselfr(   r    r)   r*   r-   r.   ÚddÚ	__class__s	           €r#   r0   zPosEmbedRel.__init__C   s�   ø€ ð  ¨Ñ/ˆÜ‰ÑÔØ$ˆŒØ ˆŒØˆŒ
äŸ,™,¤u§{¡{°8¸a±<À!Ñ3CÀXÑ'TÐQSÑ'TÓUˆŒÜŸ™¤e§k¡k°(¸Q±,ÀÑ2BÀHÑ&SÐPRÑ&SÓTˆŒà×ÑÕr%   c                 ó   — t         j                  j                  j                  | j                  | j
                  ¬«       t         j                  j                  j                  | j                  | j
                  ¬«       y )N©Ústd)r2   r   ÚinitÚnormal_r4   r*   r5   )r7   s    r#   r6   zPosEmbedRel.reset_parameters^   sH   € Ü�‰�‰×Ñ˜dŸo™o°4·:±:ÐÔ>Ü�‰�‰×Ñ˜dŸn™n°$·*±*ÐÕ=r%   c                 óB  — |j                   \  }}}}|j                  d| j                  | j                  | j                  «      }t	        || j
                  d¬«      }|j                  dd«      }t	        || j                  d¬«      }||z   }|j                  |||d«      }|S )Nr   )r   r   é   r   é   )r   r   r   )r   r@   r   rA   r   )r   r   r(   r)   r$   r5   r   r4   )	r7   r   r   ÚBBÚHWÚ_Úrel_logits_wÚrel_logits_hÚ
rel_logitss	            r#   ÚforwardzPosEmbedRel.forwardb   s‘   € Ø—w‘w‰ˆˆ2ˆr�1ð �I‰I�b˜$Ÿ/™/¨4¯?©?¸D¿M¹MÓJˆÜ$ Q¨¯©À_ÔUˆð �K‰K˜˜1ÓˆÜ$ Q¨¯©ÀoÔVˆà! LÑ0ˆ
Ø×'Ñ'¨¨2¨r°2Ó6ˆ
ØÐr%   )NN)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚintÚfloatr0   r6   rH   Ú__classcell__©r9   s   @r#   r'   r'   =   sE   ø„ ñð Øñ àð ð ð ð ð	 ð
 õ ò6>ör%   r'   c                   ó˜   ‡ — e Zd ZdZ	 	 	 	 	 	 	 	 	 	 	 	 	 ddedee   deeeef      dededee   ded	ed
edededefˆ fd„Z	d„ Z
d„ Zˆ xZS )ÚHaloAttnaÀ   Halo Attention

    Paper: `Scaling Local Self-Attention for Parameter Efficient Visual Backbones`
        - https://arxiv.org/abs/2103.12731

    The internal dimensions of the attention module are controlled by the interaction of several arguments.
      * the output dimension of the module is specified by dim_out, which falls back to input dim if not set
      * the value (v) dimension is set to dim_out // num_heads, the v projection determines the output dim
      * the query and key (qk) dimensions are determined by
        * num_heads * dim_head if dim_head is not None
        * num_heads * (dim_out * attn_ratio // num_heads) if dim_head is None
      * as seen above, attn_ratio determines the ratio of q and k relative to the output if dim_head not used

    Args:
        dim (int): input dimension to the module
        dim_out (int): output dimension of the module, same as dim if not set
        feat_size (Tuple[int, int]): size of input feature_map (not used, for arg compat with bottle/lambda)
        stride: output stride of the module, query downscaled if > 1 (default: 1).
        num_heads: parallel attention heads (default: 8).
        dim_head: dimension of query and key heads, calculated from dim_out * attn_ratio // num_heads if not set
        block_size (int): size of blocks. (default: 8)
        halo_size (int): size of halo overlap. (default: 3)
        qk_ratio (float): ratio of q and k dimensions to output dimension when dim_head not set. (default: 1.0)
        qkv_bias (bool) : add bias to q, k, and v projections
        avg_down (bool): use average pool downsample instead of strided query blocks
        scale_pos_embed (bool): scale the position embedding as well as Q @ K
    r   Údim_outÚ	feat_sizeÚstrideÚ	num_headsr)   r(   Ú	halo_sizeÚqk_ratioÚqkv_biasÚavg_downÚscale_pos_embedc                 óæ  •— ||dœ}t         ‰| �  «        |xs |}||z  dk(  sJ ‚|dv sJ ‚|| _        |xs t        ||	z  d¬«      |z  | _        || j                  z  | _        || j                  z  | _        || j
                  z  | _        | j                  dz  | _        || _	        |x| _
        | _        || _        ||dz  z   | _        d| _        d	}|dkD  r5|xs ||z  dk7  }|rdn|| _        | j                  | j                  z  | _        t        j                   || j                  df| j                  |
d
œ|¤Ž| _        t        j                   || j                  | j                  z   dfd|
i|¤Ž| _        t'        d| j                  | j                  | j                  | j                  dœ|¤Ž| _        |rt        j*                  dd«      nt        j,                  «       | _        | j1                  «        y )Nr,   r   )r   r   é   )Údivisorç      à¿r   r   F)rU   Úbiasr`   )r(   r    r)   r*   © )r/   r0   rV   r	   Údim_head_qkÚ
dim_head_vÚ
dim_out_qkÚ	dim_out_vr*   r[   r(   Úblock_size_dsrW   r    Úblock_strider   ÚConv2dr   Úkvr'   Ú	pos_embedÚ	AvgPool2dÚIdentityÚpoolr6   )r7   r   rS   rT   rU   rV   r)   r(   rW   rX   rY   rZ   r[   r-   r.   r8   Úuse_avg_poolr9   s                    €r#   r0   zHaloAttn.__init__Ž   sç  ø€ ð" ¨Ñ/ˆÜ‰ÑÔØ’.˜SˆØ˜Ñ" aÒ'Ð'Ð'Ø˜ÑÐÐØ"ˆŒØ#Òa¤~°gÀÑ6HÐRSÔ'TÐXaÑ'aˆÔØ! T§^¡^Ñ3ˆŒØ# d×&6Ñ&6Ñ6ˆŒØ" T§_¡_Ñ4ˆŒØ×%Ñ%¨Ñ-ˆŒ
Ø.ˆÔØ/9Ð9ˆŒ˜$Ô,Ø"ˆŒØ" Y°¡]Ñ2ˆŒØˆÔØˆØ�AŠ:Ø#Ò? z°FÑ':¸aÑ'?ˆLÙ%1¡°vˆDÔØ!%§¡°D×4EÑ4EÑ!EˆDÔô
 —‘˜3 §¡°Ðb¸4×;LÑ;LÐS[ÑbÐ_aÑbˆŒÜ—)‘)˜C §¡°4·>±>Ñ!AÀ1ÑZÈ8ÐZÐWYÑZˆŒä$ð 
Ø×)Ñ)Ø—]‘]Ø×%Ñ%Ø—*‘*ñ	
ð
 ñ
ˆŒñ +7”B—L‘L  AÔ&¼B¿K¹K»MˆŒ	à×ÑÕr%   c                 ó€  — | j                   j                  j                  d   dz  }t        | j                   j                  |¬«       t        | j                  j                  |¬«       t        | j
                  j                  | j                  ¬«       t        | j
                  j                  | j                  ¬«       y )Nr   r_   r;   )	r   Úweightr   r
   ri   rj   r4   r*   r5   )r7   r<   s     r#   r6   zHaloAttn.reset_parametersÇ   ss   € Ø�f‰f�m‰m×!Ñ! !Ñ$¨Ñ,ˆÜ�d—f‘f—m‘m¨Õ-Ü�d—g‘g—n‘n¨#Õ.Ü�d—n‘n×/Ñ/°T·Z±ZÕ@Ü�d—n‘n×.Ñ.°D·J±JÖ?r%   c                 ó”  — |j                   \  }}}}t        || j                  z  dk(  d«       t        || j                  z  dk(  d«       || j                  z  }|| j                  z  }||z  }| j                  |«      }	|	j	                  d| j
                  || j                  || j                  «      j                  dddddd«      }	|	j	                  || j                  z  | j
                  d|«      j                  dd«      }	| j                  |«      }
t        j                  |
| j                  | j                  | j                  | j                  g«      }
|
j                  d| j                  | j                  «      j                  d| j                  | j                  «      j	                  || j                  z  | j
                  | j                   z   |d«      j                  dddd«      }
t#        j$                  |
| j
                  | j                   gd¬	«      \  }}| j&                  r5|	|j                  dd
«      z  | j)                  |	«      z   | j*                  z  }n4|	|j                  dd
«      z  | j*                  z  | j)                  |	«      z   }|j-                  d¬	«      }||z  j                  dd«      }|j	                  d| j                  | j                  ||«      }|j                  ddddd«      j/                  «       j1                  || j2                  || j4                  z  || j4                  z  «      }| j7                  |«      }|S )Nr   Ú r   r   r@   é   r   rA   )r   r   )r   r   r(   r   r   rb   rf   r   rV   r   ri   r   r   rW   Úunfoldr    rc   r2   Úsplitr[   rj   r*   ÚsoftmaxÚ
contiguousÚviewre   rg   rm   )r7   r!   r   ÚCr   r   Únum_h_blocksÚnum_w_blocksÚ
num_blocksr   ri   ÚkÚvÚattnÚouts                  r#   rH   zHaloAttn.forwardÎ   sÞ  € Ø—W‘W‰
ˆˆ1ˆa�Ü��D—O‘OÑ# qÑ(¨"Ô-Ü��D—O‘OÑ# qÑ(¨"Ô-Ø˜DŸO™OÑ+ˆØ˜DŸO™OÑ+ˆØ! LÑ0ˆ
à�F‰F�1‹Iˆà�I‰IØ�× Ñ Ø˜$×,Ñ,¨l¸D×<NÑ<NóPçPWÑPWÐXYÐ[\Ð^_ÐabÐdeÐghÓPið 	
ð �I‰I�a˜$Ÿ.™.Ñ(¨$×*:Ñ*:¸BÀ
ÓK×UÑUÐVWÐYZÓ[ˆð �W‰W�Q‹Zˆô �U‰U�2˜Ÿ™¨¯©¸¿¹ÈÏÉÐWÓXˆØ�Y‰Y�q˜$Ÿ-™-¨¯©Ó9×@Ñ@ÀÀDÇMÁMÐSW×SbÑSbÓc×kÑkØ�—‘Ñ × 0Ñ 0°4·?±?Ñ BÀJÐPRóTßT[ÑT[Ð\]Ð_`ÐbcÐefÓTgð 	ä�{‰{˜2 × 0Ñ 0°$·/±/ÐBÈÔK‰ˆˆ1ð ×ÒØ˜Ÿ™ B¨Ó+Ñ+¨d¯n©n¸QÓ.?Ñ?À4Ç:Á:ÑM‰Dà˜Ÿ™ B¨Ó+Ñ+¨t¯z©zÑ9¸D¿N¹NÈ1Ó<MÑMˆDà�|‰| ˆ|Ó#ˆà�a‰x×"Ñ" 1 aÓ(ˆà�k‰k˜"˜d×0Ñ0°$×2DÑ2DÀlÐT`ÓaˆØ�k‰k˜!˜Q  1 aÓ(×3Ñ3Ó5×:Ñ:Øˆt�~‰~˜q D×$5Ñ$5Ñ5°q¸D×<MÑ<MÑ7MóOˆð �i‰i˜‹nˆØˆ
r%   )NNr   r]   Nr]   r@   g      ð?FFFNN)rI   rJ   rK   rL   rM   r   r   rN   Úboolr0   r6   rH   rO   rP   s   @r#   rR   rR   r   sÍ   ø„ ñð< &*Ø37ØØØ&*ØØØ!Ø"Ø"Ø$)ØØñ7 àð7 ð ˜c‘]ð7 ð    c¨3 h¡Ñ0ð	7 ð
 ð7 ð ð7 ð ˜s‘mð7 ð ð7 ð ð7 ð ð7 ð ð7 ð ð7 ð "õ7 òr@ö)r%   rR   )rL   Útypingr   r   r   r   r2   r   Útorch.nn.functionalÚ
functionalr   Úhelpersr	   Úweight_initr
   Útrace_utilsr   rM   r$   ÚModuler'   rR   ra   r%   r#   ú<module>r‰      s`   ðñ÷$ 0Ó /ã Ý ß Ð å #Ý &Ý  ð#¨$¨s©)ó #ô>2�"—)‘)ô 2ôjEˆr�y‰yô EðPr%   