o
    پiK                  
   @   s  d Z ddlZddlZddlmZmZ ddlZddlmZ ddl	m  m
Z ddlmZ ddlmZ ddlmZ ddlmZ eejd	ddkZ		
d4deeef deeeef  dedejfddZdeeef deedf fddZ		d5dedefddZdeeef deedf fddZG dd dejZ 	 	!d6d"eeef d#eeef fd$d%Z!G d&d' d'ejZ"	d7d(ed)ee fd*d+Z#d,ed-ed.ejd/ejdejf
d0d1Z$G d2d3 d3ejZ%dS )8zf Relative position embedding modules and functions

Hacked together by / Copyright 2022 Ross Wightman
    N)OptionalTuple   )ndgrid)RegularGridInterpolator)Mlp)trunc_normal_TIMM_USE_SCIPY_INTERPFq_sizek_sizeclass_tokenreturnc                 C   s`  |d u sJ dt tt | d t | d d}|d d d d d f |d d d d d f  }|ddd}|d d d d df  | d d 7  < |d d d d df  | d d 7  < |d d d d df  d| d  d 9  < d| d  d d| d  d  }|d}|rt|g d}||ddd f< |d |dd df< |d |d< |	 S )Nz-Different q & k sizes not currently supportedr   r      )r   r   r   r   r   r   )
torchstackr   arangeflattenpermutesumFpad
contiguous)r
   r   r   coordsrelative_coordsnum_relative_distancerelative_position_index r   M/home/ubuntu/.local/lib/python3.10/site-packages/timm/layers/pos_embed_rel.pygen_relative_position_index   s   *,&&* 
r    new_window_sizenew_bias_shape.c                 C   s  |d d d |d d d f}| j dkrI|\}}}| j\}}}	||d kr,||d ks.J ||ks6|	|krGtjjj| d|dddd} | S | j dksPJ |\}
}| j\}}|
|d |d   }t|| d }||f}|d |d ks|d |d kr|r| | d d d f }| d | d d f } nd }tjjj| 	dd
dd	|d |d f|dddd	|
| 	dd} |d urtj| |fdd
} | S )Nr   r   r      bicubicF)sizemodealign_corners      ?r   dim)ndimshaper   nn
functionalinterpolate	unsqueezesqueezeint	transposereshapeviewcat)rel_pos_biasr!   r"   dst_size_dst_hdst_wnum_attn_headssrc_hsrc_wdst_num_possrc_num_posnum_extra_tokenssrc_sizeextra_tokensr   r   r    resize_rel_pos_bias_table_simpleI   sJ    

 
  rD   r$   Tinterpolation	antialiasc                 C   s   |   \}}|\}}||ksJ ||krM| j}|  } t|d }	t|d }
tj| ddd||	|	|
|
f||d}|||dd}|| |S | S )z
    Resample relative position bias table suggested in LeVit
    Adapted from: https://github.com/microsoft/Cream/blob/main/TinyViT/utils.py
    r(   r   r   )r%   r&   rF   )	r%   dtypefloatr2   r   r/   r   r5   to)position_bias_tablenew_sizerE   rF   L1nH1L2nH2
orig_dtypeS1S2$relative_position_bias_table_resizedr   r   r   resize_rel_pos_bias_table_levitx   s&   

rT   c                    s  t rddlm} |d d d |d d d f}| jdkr?d}|\}}}||d kr0||d ks2J | j\}	}
}|
|f}d}n(| jdksFJ |\}}| j\}}	||d |d   }t|| d }||f}d}|d |d ksx|d |d krh|r| | d	d	d	f }| d	| d	d	f } nd	}d
d   fdd}||d |d }||d |d }t|t|g}|d d }|d d }t| |d d}t| |d d}t	||}g }t
|	D ]^}|r| d	d	|f |d |d  }n| |d	d	d	d	f  }t r%|j||| dd}t||| | j}nt||}|| | j}|r=|dd}|| q|rNtj|dd} ntj|dd} |d	urh|s_J tj| |fdd} | S )a   Resize relative position bias table using more advanced interpolation.

    Modified from code in Microsoft Unilm (https://github.com/microsoft/unilm) repo (BeiT, BeiT-v2, etc).

    https://github.com/microsoft/unilm/blob/5255d52de86dad642810f5849dd357769346c1d7/beit/run_class_finetuning.py#L351

    Args:
        rel_pos_bias:
        new_window_size:
        new_bias_shape:

    Returns:

    r   )r/   r   r   r#   Fr(   TNc                 S   s   | d||   d|  S )N      ?r   )arnr   r   r   geometric_progression   s   z8resize_rel_pos_bias_table.<locals>.geometric_progressionc           
         s   d\}}|| dkr)|| d } d|| d }||d kr!|}n|}|| dks
g }d}t | d D ]}|| |||d  7 }q3dd t|D }	|	dg | S )	N)g)\(?g      ?gư>       @r   r   c                 S   s   g | ]}| qS r   r   ).0r9   r   r   r   
<listcomp>   s    z<resize_rel_pos_bias_table.<locals>._calc.<locals>.<listcomp>r   )rangeappendreversed)
srcdstleftrightqgpdiscurir_idsrY   r   r   _calc   s   
z(resize_rel_pos_bias_table.<locals>._calcrZ   g?rU   cubic)kindr   r)   )
_USE_SCIPYscipyr/   r+   r,   r2   r   tensorr   r   r]   r5   rH   interp2dnumpyTensorr   rI   devicer   r^   r6   )r7   r!   r"   r/   r8   rA   r9   r:   r;   r<   r=   r>   rB   has_flat_shaper?   r@   rC   rk   yxyxtytxdydxdyxall_rel_pos_biasrh   zfrW   r   rj   r   resize_rel_pos_bias_table   sh    


"
&


r   c                       P   e Zd ZdZd fdd	Zdd Zdejfdd	Zdde	ej fddZ
  ZS )
RelPosBiasz_ Relative Position Bias
    Adapted from Swin-V1 relative position bias impl, modularized.
    r   c                    s   t    |dksJ || _|d |d  | _| j| fd |f | _d|d  d d|d  d  d|  }tt||| _	| j
dt| j|dkdddd	 |   d S )
Nr   r   r   r#   r   )r   r   F
persistent)super__init__window_sizewindow_area
bias_shaper-   	Parameterr   zerosrelative_position_bias_tableregister_bufferr    r5   init_weights)selfr   	num_headsprefix_tokensr   	__class__r   r   r     s   
(zRelPosBias.__init__c                 C   s   t | jdd d S Ng{Gz?)std)r   r   r   r   r   r   r   "  s   zRelPosBias.init_weightsr   c                 C   s0   | j | j }|| jddd}|d S )Nr   r   r   )r   r   r5   r   r   r0   r   r   relative_position_biasr   r   r   get_bias%  s   zRelPosBias.get_biasNshared_rel_posc                 C      ||    S Nr   r   attnr   r   r   r   forward+     zRelPosBias.forwardr   r   __name__
__module____qualname____doc__r   r   r   rs   r   r   r   __classcell__r   r   r   r   r     s    r   r   swinwin_sizepretrained_win_sizec                 C   sr  |dv sJ t | d d  | d t j}t | d d  | d t j}t t||}|ddd }|dkr|d dkrj|d d d d df  |d d   < |d d d d df  |d d   < n&|d d d d df  | d d   < |d d d d df  | d d   < |d9 }t |t 	d|
   t	d }|S t |t d|
   }|S )N)r   crr   r   r   r      rU   )r   r   rI   float32r   r   r   r   signlog2absmathlog)r   r   r&   relative_coords_hrelative_coords_wrelative_coords_tabler   r   r   gen_relative_log_coords/  s,   ""&(&&

r   c                       sR   e Zd ZdZ					d fdd	Zd	ejfd
dZddeej fddZ	  Z
S )	RelPosMlpz Log-Coordinate Relative Position MLP
    Based on ideas presented in Swin-V2 paper (https://arxiv.org/abs/2111.09883)

    This impl covers the 'swin' implementation as well as two timm specific modes ('cr', and 'rw')
    r      r   r   r   c                    s   t    || _| jd | jd  | _|| _|| _| jfd |f | _|dkr2t | _	d| _
d}n
t | _	d | _
d}td||tj|dd	| _| jd
t|ddd | jdt|||ddd d S )Nr   r   r   r      )TFT)g      ?g        )hidden_featuresout_features	act_layerbiasdropr   r   Fr   rel_coords_log)r&   )r   r   r   r   r   r   r   r-   Sigmoidbias_act	bias_gainIdentityr   ReLUmlpr   r    r5   r   )r   r   r   
hidden_dimr   r&   pretrained_window_sizemlp_biasr   r   r   r   R  s>   
	

	
zRelPosMlp.__init__r   c                 C   s   |  | j}| jd ur|d| j| j }|| j}|ddd}| |}| jd ur1| j| }| j	r@t
|| j	d| j	dg}|d S )Nr   r   r   r   )r   r   r   r5   r   r   r   r   r   r   r   r   r0   r   r   r   r   r   r   ~  s   



zRelPosMlp.get_biasNr   c                 C   r   r   r   r   r   r   r   r     r   zRelPosMlp.forward)r   r   r   r   r   r   )r   r   r   r   r   r   rs   r   r   r   r   r   r   r   r   r   L  s    ,r   lengthmax_relative_positionc                 C   sv   |du r| d }d| d }t | | |}t| D ]}t| D ]}|| | }t|| |kr0qd||||f< qq|S )a  Generate a one_hot lookup tensor to reindex embeddings along one dimension.

    Args:
        length: the length to reindex to.
        max_relative_position: the maximum relative position to consider.
            Relative position embeddings for distances above this threshold
            are zeroed out.
    Returns:
        a lookup Tensor of size [length, length, vocab_size] that satisfies
            ret[n,m,v] = 1{m - n + max_relative_position = v}.
    Nr   r   )r   r   r]   r   )r   r   
vocab_sizeretrh   rw   vr   r   r   generate_lookup_tensor  s   r   heightwidthheight_lookupwidth_lookupc                 C   s8   t d| |}t d||}|| }|| jd ||S )a\  Reindex 2d relative position bias with 2 independent einsum lookups.

    Adapted from:
     https://github.com/google-research/maxvit/blob/2e06a7f1f70c76e64cd3dabe5cd1b8c1a23c9fb7/maxvit/models/attention_utils.py

    Args:
        relative_position_tensor: tensor of shape
            [..., vocab_height, vocab_width, ...].
        height: height to reindex to.
        width: width to reindex to.
        height_lookup: one-hot height lookup
        width_lookup: one-hot width lookup
    Returns:
        reindexed_tensor: a Tensor of shape
            [..., height * width, height * width, ...]
    znhw,ixh->nixwznixw,jyw->nijxyr   )r   einsumr4   r,   )relative_position_tensorr   r   r   r   reindexed_tensorarear   r   r   reindex_2d_einsum_lookup  s   r   c                       r   )RelPosBiasTfz Relative Position Bias Impl (Compatible with Tensorflow MaxViT models)
    Adapted from:
     https://github.com/google-research/maxvit/blob/2e06a7f1f70c76e64cd3dabe5cd1b8c1a23c9fb7/maxvit/models/attention_utils.py
    r   c                    s   t    |dksJ || _|d |d  | _|| _d|d  d }d|d  d }| j||f| _tt	| j| _
| jdt|d dd | jdt|d dd |   d S )Nr   r   r   r   Fr   r   )r   r   r   r   r   r   r-   r   r   r   r   r   r   r   )r   r   r   r   vocab_heightvocab_widthr   r   r   r     s   
zRelPosBiasTf.__init__c                 C   s   t jj| jdd d S r   )r-   initnormal_r   r   r   r   r   r     s   zRelPosBiasTf.init_weightsr   c                 C   s"   t | j| jd | jd | j| jS )Nr   r   )r   r   r   r   r   r   r   r   r   r     s   zRelPosBiasTf.get_biasNr   c                 C   r   r   r   r   r   r   r   r     r   zRelPosBiasTf.forwardr   r   r   r   r   r   r   r     s    
r   )NF)r$   T)r   r   r   )&r   r   ostypingr   r   r   torch.nnr-   torch.nn.functionalr.   r   gridr   r/   r   r   r   weight_initr   r2   environgetrn   boolrs   r    rD   strrT   r   Moduler   r   r   r   r   r   r   r   r   r   <module>   s    

4


2
 


t%


E

