a
    dF                     @   sx   d Z ddlmZmZ ddlZddlmZ ddlmZ ddl	m
Z
mZ ddlmZ G dd	 d	ejZG d
d dejZdS )a:   Attention Pool 2D

Implementations of 2D spatial feature pooling using multi-head attention instead of average pool.

Based on idea in CLIP by OpenAI, licensed Apache 2.0
https://github.com/openai/CLIP/blob/3b473b0e682c091a9e53623eebc1ca1657385717/clip/model.py

Hacked together by / Copyright 2021 Ross Wightman
    )UnionTupleN   )	to_2tuple)apply_rot_embedRotaryEmbedding)trunc_normal_c                       s8   e Zd ZdZd
eeeeed fddZdd	 Z  ZS )RotAttentionPool2daB   Attention based 2D feature pooling w/ rotary (relative) pos embedding.
    This is a multi-head attention based replacement for (spatial) average pooling in NN architectures.

    Adapted from the AttentionPool2d in CLIP w/ rotary embedding instead of learned embed.
    https://github.com/openai/CLIP/blob/3b473b0e682c091a9e53623eebc1ca1657385717/clip/model.py

    NOTE: While this impl does not require a fixed feature size, performance at differeing resolutions from
    train varies widely and falls off dramatically. I'm not sure if there is a way around this... -RW
    N   T)in_featuresout_features	embed_dim	num_headsqkv_biasc                    s   t    |p|}|p|}tj||d |d| _t||| _|| _|| dksTJ || | _| jd | _t	| j| _
t| jj|d d tj| jj d S )N   biasr         ࿩Zstd)super__init__nnLinearqkvprojr   head_dimscaler   	pos_embedr   weightinitzeros_r   )selfr   r   r   r   r   	__class__ e/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/timm/layers/attention_pool2d.pyr      s    

zRotAttentionPool2d.__init__c                 C   s  |j \}}}}|| }||d|ddd}tj|jddd|gdd}| |||d d| j| jddddd	}|d |d |d   }}}	|d d d d d df |d d d d dd f  }
}| j	
||f\}}t|||}tj|
|gdd}|d d d d d df |d d d d dd f  }}t|||}tj||gdd}||d
d | j }|jdd}||	 dd||d d}| |}|d d df S )Nr      r   TZkeepdimZdimr   r
   )shapereshapepermutetorchcatmeanr   r   r   r   Z	get_embedr   	transposer   softmaxr   )r!   xB_HWNqkvZqcZsin_embZcos_embZkcattnr$   r$   r%   forward4   s$    .66
zRotAttentionPool2d.forward)NNr
   T)	__name__
__module____qualname____doc__intboolr   r=   __classcell__r$   r$   r"   r%   r	      s       r	   c                       sJ   e Zd ZdZd
eeeeeef f eeeed fddZdd	 Z	  Z
S )AttentionPool2da   Attention based 2D feature pooling w/ learned (absolute) pos embedding.
    This is a multi-head attention based replacement for (spatial) average pooling in NN architectures.

    It was based on impl in CLIP by OpenAI
    https://github.com/openai/CLIP/blob/3b473b0e682c091a9e53623eebc1ca1657385717/clip/model.py

    NOTE: This requires feature size upon construction and well prevent adaptive sizing of the network.
    Nr
   T)r   	feat_sizer   r   r   r   c                    s   t    |p|}|p|}|| dks*J t|| _tj||d |d| _t||| _|| _|| | _	| j	d | _
| jd | jd  }tt|d || _t| j|d d t| jj|d d tj| jj d S )Nr   r   r   r   r   r   )r   r   r   rF   r   r   r   r   r   r   r   	Parameterr.   zerosr   r   r   r   r    r   )r!   r   rF   r   r   r   r   Zspatial_dimr"   r$   r%   r   X   s    	


zAttentionPool2d.__init__c                 C   s*  |j \}}}}|| }| jd |ks(J | jd |ks:J ||d|ddd}tj|jddd|gdd}|| jd	|j
 }| |||d d| j| jddddd	}|d |d |d   }}}	||d
d | j }
|
jdd}
|
|	 dd||d d}| |}|d d df S )Nr   r   r&   r'   Tr(   r)   r   r
   r*   )r+   rF   r,   r-   r.   r/   r0   r   Z	unsqueezetoZdtyper   r   r   r1   r   r2   r   )r!   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r$   r$   r%   r=   s   s    .
zAttentionPool2d.forward)NNr
   T)r>   r?   r@   rA   rB   r   r   rC   r   r=   rD   r$   r$   r"   r%   rE   O   s       rE   )rA   typingr   r   r.   Ztorch.nnr   Zhelpersr   Zpos_embed_sincosr   r   Zweight_initr   Moduler	   rE   r$   r$   r$   r%   <module>   s   	;