U
    ¯Ê¹j�8  ã                   @   sð  d Z ddl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
Z
 ddlmZ d/eeeeej d
œdd„Zd0eeeeej ejdœdd„Zddddejdfee eeeeejeej ejdœdd„Zddddddd	dejdf
ee eej eeeeeeeee  ejeej eej dœdd„ZG dd„ dejƒZdd„ Zejdœd d!„Zeej dœd"d#„Zejdœd$d%„Zd&d'„ Zdddddd	dejdf	ee eej eeeeeeee  ejeej d(œ
d)d*„ZG d+d,„ d,ejƒZ G d-d.„ d.ejƒZ!dS )1zv Sin-cos, fourier, rotary position embedding modules and functions

Hacked together by / Copyright 2022 Ross Wightman
é    N)ÚListÚTupleÚOptionalÚUnion)Únné   )Úndgrid)Ú_assertç      l@T)Ú	num_bandsÚmax_freqÚlinear_bandsÚdevicec                 C   sP   |r t jd|d | t j|d�}n&dt jdt |d¡d | t j|d� }|t j S )Nç      ð?é   ©Údtyper   r   r   )ÚtorchÚlinspaceÚfloat32ÚmathÚlogÚpi)r   r   r   r   Úbands© r   ú[/var/www/html/bwave/python/venv/lib/python3.8/site-packages/timm/layers/pos_embed_sincos.pyÚpixel_freq_bands   s    &r   ç     ˆÃ@r   )r   ÚtemperatureÚstepr   Úreturnc                 C   s2   t jd| |t j|d� t j¡|  }d||  }|S )Nr   r   r   ©r   ZarangeZint64Útor   )r   r   r   r   Úexpr   r   r   r   Ú
freq_bands   s    "r$   é@   F)Ú
feat_shapeÚdimr   Úreverse_coordÚinterleave_sin_cosr   r   r    c                    s¸   |d dkst dƒ‚|d }t||dˆ d�}|r>| ddd… } t t‡ fdd	„| D ƒƒ¡ d¡ dd¡}	|	 d¡| d¡ }
|r„d
nd}tjt |
¡t 	|
¡g|d� d¡}|j
|d�S )a  

    Args:
        feat_shape:
        dim:
        temperature:
        reverse_coord: stack grid order W, H instead of H, W
        interleave_sin_cos: sin, cos, sin, cos stack instead of sin, sin, cos, cos
        dtype:
        device:

    Returns:

    é   r   zHEmbed dimension must be divisible by 4 for sin-cos 2D position embeddingr   ©r   r   r   Néÿÿÿÿc                    s&   g | ]}t j|ˆ t jd � t j¡‘qS ©)r   r   r!   ©Ú.0Ús©r   r   r   Ú
<listcomp>D   s   ÿz,build_sincos2d_pos_embed.<locals>.<listcomp>r   ©r'   ©r   )ÚAssertionErrorr$   r   Ústackr   ÚflattenÚ	transposeÚ	unsqueezeÚsinÚcosr"   )r&   r'   r   r(   r)   r   r   Zpos_dimr   ÚgridÚpos2Z	stack_dimZpos_embr   r1   r   Úbuild_sincos2d_pos_embed'   s"    þ
ý ý$r>   éà   )r&   r   r   Úmax_resr   r   Úinclude_gridÚ	in_pixelsÚref_feat_shaper   r   r    c                    sö   |dkr4|r"t |t|ƒ|ˆ d�}qPt||dˆ d�}nˆ dkrB|j‰ |	dkrP|j}	|rh‡ fdd„| D ƒ}n‡ fdd„| D ƒ}|dk	r˜dd„ t|| |ƒD ƒ}tjt|ƒd	d
�}| 	d	¡}|| }| 
¡ j|	d�| ¡  |	¡ }}|rê|||gn||g}|S )a[  

    Args:
        feat_shape: Feature shape for embedding.
        bands: Pre-calculated frequency bands.
        num_bands: Number of frequency bands (determines output dim).
        max_res: Maximum resolution for pixel based freq.
        temperature: Temperature for non-pixel freq.
        linear_bands: Linear band spacing for pixel based freq.
        include_grid: Include the spatial grid in output.
        in_pixels: Output in pixel freq.
        ref_feat_shape: Reference feature shape for resize / fine-tune.
        dtype: Output dtype.
        device: Output device.

    Returns:

    N)r   r   r   r+   c              	      s"   g | ]}t jd d|ˆ t jd�‘qS )g      ð¿r   )Zstepsr   r   )r   r   r   r.   r1   r   r   r2   …   s     z+build_fourier_pos_embed.<locals>.<listcomp>c                    s&   g | ]}t j|ˆ t jd � t j¡‘qS r-   r!   r.   r1   r   r   r2   ‡   s     c                 S   s   g | ]\}}}|| | ‘qS r   r   )r/   ÚxÚfÚrr   r   r   r2   ‹   s     r,   r3   r4   )r   Úfloatr$   r   r   Úzipr   r6   r   r9   r:   r"   r;   )r&   r   r   r@   r   r   rA   rB   rC   r   r   Útr<   ÚposZpos_sinZpos_cosÚoutr   r1   r   Úbuild_fourier_pos_embedP   s:    üü
 rL   c                       s.   e Zd Zd
eedœ‡ fdd„Zdd	„ Z‡  ZS )ÚFourierEmbedr?   r%   TF)r@   r   c                    s<   t ƒ  ¡  || _|| _|| _|| _| jdt||ƒdd� d S )Nr   F©Ú
persistent)ÚsuperÚ__init__r@   r   Úconcat_gridÚkeep_spatialÚregister_bufferr   )Úselfr@   r   rR   rS   ©Ú	__class__r   r   rQ   ˜   s    
ýzFourierEmbed.__init__c                 C   sä   |j d d… \}}|j dd … }t|| j| j|j|jd�}tj|dd�}| dd¡ 	t
|ƒ¡}|fd|jd   }| jr¤tj|| d¡ |¡ dd	dd¡gdd�}n<tj| ddd	d¡| d¡ |¡gdd�}| || ¡ d¡}|S )
Nr   )rA   r   r   r,   r3   éþÿÿÿ)r,   r   r   é   )ÚshaperL   r   rR   r   r   r   Úcatr8   r7   ÚlenÚndimrS   r9   ÚexpandZpermuteÚreshapeZnumel)rU   rD   ÚBÚCr&   ÚembZbatch_expandr   r   r   Úforwardª   s"    û,*zFourierEmbed.forward)r?   r%   TF)Ú__name__Ú
__module__Ú__qualname__ÚintrQ   rc   Ú__classcell__r   r   rV   r   rM   –   s       ûýrM   c                 C   s6   t  | ddd d…f  | dd d d…f gd¡ | j¡S )N.r   r   r,   )r   r6   r_   rZ   ©rD   r   r   r   ÚrotÂ   s    rj   ri   c                 C   sJ   |j dkr6| | d¡ | ¡ t| ƒ| d¡ | ¡  S | | t| ƒ|  S )NrY   r   )r]   r9   Ú	expand_asrj   ©rD   Úsin_embÚcos_embr   r   r   Úapply_rot_embedÆ   s    
,ro   c                    s&   t | tjƒr| g} ‡ ‡fdd„| D ƒS )Nc                    s    g | ]}|ˆ  t |ƒˆ  ‘qS r   )rj   )r/   rI   ©rn   rm   r   r   r2   Ï   s     z(apply_rot_embed_list.<locals>.<listcomp>)Ú
isinstancer   ÚTensorrl   r   rp   r   Úapply_rot_embed_listÌ   s    rs   c                 C   sZ   |  dd¡\}}|jdkrF| | d¡ | ¡ t| ƒ| d¡ | ¡  S | | t| ƒ|  S )Nr   r,   rY   r   )Ztensor_splitr]   r9   rk   rj   )rD   rb   rm   rn   r   r   r   Úapply_rot_embed_catÒ   s    
,rt   c              	   C   s@   |  d¡ | jd dd¡}| d|  d¡ dd|jd ¡¡}|S )Nr   r,   r   )r9   r^   rZ   Zgather)rD   Ú	pos_embedZkeep_indicesr   r   r   Úapply_keep_indices_nlcÙ   s    "rv   )
r&   r   r'   r@   r   r   rB   rC   r   r   c
                 C   sj   t | ||d ||||||	|d�
\}
}d}| D ]}||9 }q,|
 |d¡ dd¡}
| |d¡ dd¡}|
|fS )aÿ  

    Args:
        feat_shape: Spatial shape of the target tensor for embedding.
        bands: Optional pre-generated frequency bands
        dim: Output dimension of embedding tensor.
        max_res: Maximum resolution for pixel mode.
        temperature: Temperature (inv freq) for non-pixel mode
        linear_bands: Linearly (instead of log) spaced bands for pixel mode
        in_pixels: Pixel vs language (inv freq) mode.
        dtype: Output dtype.
        device: Output device.

    Returns:

    r*   )	r   r   r@   r   r   rB   rC   r   r   r   r,   r   )rL   r_   Zrepeat_interleave)r&   r   r'   r@   r   r   rB   rC   r   r   rm   rn   Znum_spatial_dimrD   r   r   r   Úbuild_rotary_pos_embedß   s$    ö

rw   c                       s\   e Zd ZdZdeeee  eee  dœ‡ fdd	„Zdeee  d
œdd„Z	dd„ Z
‡  ZS )ÚRotaryEmbeddinga®   Rotary position embedding

    NOTE: This is my initial attempt at impl rotary embedding for spatial use, it has not
    been well tested, and will likely change. It will be moved to its own file.

    The following impl/resources were referenced for this impl:
    * https://github.com/lucidrains/vit-pytorch/blob/6f3a5fcf0bca1c5ec33a35ef48d97213709df4ba/vit_pytorch/rvt.py
    * https://blog.eleuther.ai/rotary-embeddings/
    r?   é'  TFN©r   r&   rC   c                    sÎ   t ƒ  ¡  || _|| _|| _|| _|| _|| _|d krŠ|rRt|d t	|ƒ|d�}nt
|d |dd�}t|ƒ | jd|dd� d | _d | _n@t|||||| jd�\}	}
d | _| jd	|	dd� | jd
|
dd� d S )Nr*   ©r   r   ©r   r   r   FrN   ©r&   r'   r@   r   rB   rC   Úpos_embed_sinÚpos_embed_cos)rP   rQ   r'   r@   r   rB   r&   rC   r   rG   r$   ÚprintrT   r~   r   rw   r   )rU   r'   r@   r   rB   r   r&   rC   r   Zemb_sinZemb_cosrV   r   r   rQ     s\    

ýýýú
ýýzRotaryEmbedding.__init__©rZ   c                 C   s8   | j d k	r(|d k	st‚t|| j | jd�S | j| jfS d S )N)rB   )r   r5   rw   rB   r~   r   )rU   rZ   r   r   r   Ú	get_embedY  s    
ýzRotaryEmbedding.get_embedc                 C   s$   |   |jdd … ¡\}}t|||ƒS ©Nr   )r‚   rZ   ro   )rU   rD   rm   rn   r   r   r   rc   e  s    zRotaryEmbedding.forward)r?   ry   TFNN)N©rd   re   rf   Ú__doc__Úboolr   r   rg   rQ   r‚   rc   rh   r   r   rV   r   rx     s         ø

ø>rx   c                       s\   e Zd ZdZdeeee  eee  dœ‡ fdd	„Zdeee  d
œdd„Z	dd„ Z
‡  ZS )ÚRotaryEmbeddingCata   Rotary position embedding w/ concatenatd sin & cos

    The following impl/resources were referenced for this impl:
    * https://github.com/lucidrains/vit-pytorch/blob/6f3a5fcf0bca1c5ec33a35ef48d97213709df4ba/vit_pytorch/rvt.py
    * https://blog.eleuther.ai/rotary-embeddings/
    r?   ry   TFNrz   c           
         s´   t ƒ  ¡  || _|| _|| _|| _|| _|| _|d kr||rRt|d t	|ƒ|d�}nt
|d |dd�}| jd|dd� d | _n4t|||||| jd�}	d | _| jd	t |	d
¡dd� d S )Nr*   r{   r   r|   r   FrN   r}   ru   r,   )rP   rQ   r'   r@   r   rB   r&   rC   r   rG   r$   rT   ru   rw   r   r   r[   )
rU   r'   r@   r   rB   r   r&   rC   r   ÚembedsrV   r   r   rQ   s  sN    

ýýýú
ýzRotaryEmbeddingCat.__init__r�   c                 C   sT   | j d k	r4|d k	r4t|| j | j| jd�}t |d¡S | jd k	rD| jS dsPtdƒ‚d S )N)rB   rC   r,   FzPget_embed() requires pre-computed pos_embed or valid shape w/ pre-computed bands)r   rw   rB   rC   r   r[   ru   r5   )rU   rZ   rˆ   r   r   r   r‚   ª  s    ü
zRotaryEmbeddingCat.get_embedc                 C   s   |   |jdd … ¡}t||ƒS rƒ   )r‚   rZ   rt   )rU   rD   ru   r   r   r   rc   ¹  s    zRotaryEmbeddingCat.forward)r?   ry   TFNN)Nr„   r   r   rV   r   r‡   k  s   
      ø

ø7r‡   )r
   TN)r   r   N)"r…   r   Útypingr   r   r   r   r   r   r<   r   Ztrace_utilsr	   rg   rG   r†   r   r   rr   r$   r   r   r>   rL   ÚModulerM   rj   ro   rs   rt   rv   rw   rx   r‡   r   r   r   r   Ú<module>   s¼      üü   üûùø+õ
ôF,ö
ö1[