U
    âhnF  ã                   @   sÞ   d Z ddlZddlZddlmZmZ ddlmZ dd„ Zeej	ej	ej	ej	dœd	d
„ƒZ
eej	ej	dœdd„ƒZeej	ej	ej	ej	ej	ej	dœdd„ƒZeej	ej	ej	ej	ej	ej	dœdd„ƒZG dd„ dejjƒZejZdS )ao  
Fused Attention
===============
This is a Triton implementation of the Flash Attention algorithm
(see: Dao et al., https://arxiv.org/pdf/2205.14135v2.pdf; Rabe and Staats https://arxiv.org/pdf/2112.05682v2.pdf)

Sequence Parallel implementation inspired by HazyResearch
(see https://github.com/HazyResearch/flash-attention/blob/main/flash_attn/flash_attn_triton.py)
é    Né   )ÚcdivÚjit)Úlanguagec                   C   s   t jjj ¡ jdkS )NZhip)ÚtritonÚruntimeZdriverZactiveZget_current_targetÚbackend© r	   r	   úL/var/www/html/venv/lib/python3.8/site-packages/triton/ops/flash_attention.pyÚis_hip   s    r   )ÚBLOCK_MÚBLOCK_DMODELÚBLOCK_NÚ	IS_CAUSALc           8   	   C   sú  t  d¡}t  d¡}|| } | | }!t j|||f||fd|!f||fdd}"t j|||f||f|!df||fdd}#|| t  d|¡ }$t  d|¡}%t j|gt jdtdƒ }&t j|gt jd}'t j||gt jd}(|d })t  d|¡}*| |  |$d d …d f |  |*d d d …f |	  }+t  |+¡},|,|)  |j	j
¡},d}-|rF|d | n|}.t|-|.|ƒD ]}/t  |"¡}0t  |#¡}1t j||gt jd}2|r¼t  |$d d …d f |/|%d d d …f  k|2td	ƒ¡}2|2t  |,|0¡7 }2t  |&t  |2d¡¡}3t j |&|3 ¡}4t j |2|3d d …d f  ¡}5|(|4d d …d f 9 }(|(t  |5 |j	j
¡|1¡7 }(|'|4 t  |5d¡ }'|3}&t  |"d|f¡}"t  |#|df¡}#qV|(|'d d …d f  }(|||  |$ }6t  |6|&t j |'¡ ¡ t j|||f||f|!||  df||fdd}7t  |7|( |j	j
¡¡ d S )
Nr   é   )r   r   ©ÚbaseÚshapeÚstridesÚoffsetsZblock_shapeÚorder©r   r   ©ÚdtypeÚinfç/lîdG÷?ú-inf)ÚtlÚ
program_idÚmake_block_ptrÚarangeÚzerosÚfloat32ÚfloatÚloadÚtor   Ú
element_tyÚrangeÚwhereÚdotÚmaximumÚmaxÚmathÚexp2ÚsumÚadvanceÚstoreÚlog2)8ÚQÚKÚVÚsm_scaleÚLÚOutÚ	stride_qzÚ	stride_qhÚ	stride_qmÚ	stride_qkÚ	stride_kzÚ	stride_khÚ	stride_knÚ	stride_kkÚ	stride_vzÚ	stride_vhÚ	stride_vnÚ	stride_vkZ	stride_ozZ	stride_ohZ	stride_omZ	stride_onÚZÚHÚN_CTXÚ	Z_H_N_CTXr   r   r   r   Ústart_mÚoff_hzZ
qvk_offsetZ	vk_offsetÚK_block_ptrÚV_block_ptrÚoffs_mÚoffs_nZm_iÚl_iÚaccÚqk_scaleZoffs_kZQ_ptrsÚqÚloÚhiÚstart_nÚkÚvÚqkZm_i_newÚalphaÚpÚl_ptrsZO_block_ptrr	   r	   r
   Ú_fwd_kernel   sx    

úú	0


2ú	r[   ©r   ÚD_HEADc           
      C   s¸   t  d¡| t  d|¡ }t  d|¡}t  | |d d …d f |  |d d d …f  ¡ t j¡}t  ||d d …d f |  |d d d …f  ¡ t j¡}t j|| dd}	t  || |	¡ d S )Nr   r   )Zaxis)r   r   r    r$   r%   r"   r.   r0   )
r7   ÚDOÚDeltar   r]   Zoff_mZoff_nÚoÚdoÚdeltar	   r	   r
   Ú_bwd_preprocessu   s    66rc   ©r   r   r   ÚSEQUENCE_PARALLELÚCAUSALÚMMA_V3c.           F   	   C   s´  |,r|&|( }.nd}.|$| |#|  | }/|$| |#|  }0|$| |#|  | }1|$| |#|  | }2|+rn|0||& 7 }0|0| }0t  ||.|/ df¡}t  ||&|( |1 df¡}t  ||&|( |2 df¡}t  ||.|/ df¡}t  ||.|0 df¡}t  ||&|( |1 df¡}t  ||&|( |2 df¡}|&|( t  d|(¡ }3t  d|*¡}4||%|"  }5|
|%|"  }6t j|(|)gt jd}7t j|(|)gt jd}8t  |¡}9t  |¡}:t|.|'|( |(ƒD ]ê};|;|4 }<t  |¡}=|,rèt  |<d d …d f |3d d d …f ktdƒtdƒ¡}>nt j|(|*gt jd}>|>t  	|=t  
|9¡¡7 }>|>|9 }>t  |6|< ¡}?t j |>|?d d …d f  ¡}@t  |¡}A|7t  	t  
|@ | jj¡¡|A¡7 }7t  |5|< ¡}Bt  	|At  
|:¡¡}C|@|C|Bd d …d f   |  | jj¡}D|8t  	t  
|D¡|=¡7 }8|+st  |¡}E|Et  	|D|9¡7 }Et  ||E | jj¡¡ nN|+rP|-rt  	|D|9¡}Ent  
t  	t  
|9¡t  
|D¡¡¡}Et  ||E | jj¡¡ t  ||(df¡}t  ||(df¡}t  ||(df¡}q–t  ||7 |jj¡¡ t  ||8 |jj¡¡ d S )Nr   r   g        r   )r   r/   r    r!   r"   r$   r'   r(   r#   r)   Ztransr,   r-   r%   r   r&   r0   )Fr2   r3   r4   r5   rP   r7   r^   ÚDQÚDKÚDVr6   ÚDÚQ_block_ptrrJ   rK   ÚDO_block_ptrÚDQ_block_ptrÚDK_block_ptrÚDV_block_ptrÚ
stride_dqar8   r9   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   rD   rE   rF   Úoff_hÚoff_zrI   rT   Z	num_blockr   r   r   re   rf   rg   rR   ZQ_offsetZ	DQ_offsetZK_offsetZV_offsetrM   rL   ZD_ptrsrZ   ÚdvÚdkrU   rV   rH   Zoffs_m_currrQ   rW   rN   rY   ra   ZDiZdpZdsÚdqr	   r	   r
   Ú_bwd_kernel_one_col_blockˆ   sn    



4
 &
rw   c#           0   1   C   s4  |d }#t  d¡}$|$| }%|$| }&t j| ||f||fd||fdd}'t j|||f||fd||fdd}(t j|||f||fd||fdd})t j|||f||fd||fdd}*| rÒt j|||f||fd||fdd}+n"t j|||f||fd||fdd}+t j|||f||fd||fdd},t j|||f||fd||fdd}-t  ||¡}.| sÂtd|.ƒD ]j}/t| ||||#||||||	|
|'|(|)|*|+|,|-|||||||||||||||||&|%|$|/|.|||| |!|"d. qTnnt  d¡}/t| ||||#||||||	|
|'|(|)|*|+|,|-|||||||||||||||||&|%|$|/|.|||| |!|"d. d S )Nr   r   )r   r   r   r   rd   r   )r   r   r   r   r'   rw   )0r2   r3   r4   r5   r7   r^   rh   ri   rj   r6   rk   rq   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   rD   rE   rF   rG   ZSQ_Z_H_N_CTXr   r   r   re   rf   rg   rP   rI   rs   rr   rl   rJ   rK   rm   rn   ro   rp   Znum_block_nrT   r	   r	   r
   Ú_bwd_kernelì   s6   
úúúúú	ú	úú	                        ñ
                        ñrx   c                   @   s&   e Zd Zeddd„ƒZedd„ ƒZdS )Ú
_attentionFc              "   C   sâ  t j ¡ }|d dk rtdƒ‚d}d}	|jd |jd |jd   }
}}|
|krX||ks\t‚|dksht‚t  |¡}t|jd |ƒ|jd |jd	  d	f}t j|jd |jd	  |jd f|j	t j
d
}|dkrÒdnd}t| ||||||| d¡| d	¡| d¡| d¡| d¡| d	¡| d¡| d¡| d¡| d	¡| d¡| d¡| d¡| d	¡| d¡| d¡|jd |jd	 |jd |jd |jd	  |jd  ||	|||dd  |  |||||¡ || _|| _|| _|| _|| _|S )Nr   é   zEFlash attention currently only supported for compute capability >= 80é€   é@   éÿÿÿÿ>   é   é    r|   r{   r   r   ©Údevicer   é   é   )r   r   r   r   Ú	num_warpsÚ
num_stages)ÚtorchÚcudaÚget_device_capabilityÚRuntimeErrorr   ÚAssertionErrorÚ
empty_liker   Úemptyr   r"   r[   ÚstrideZsave_for_backwardÚgridr5   r   ÚcausalÚsequence_parallel)ÚctxrQ   rU   rV   r   r5   r   Ú
capabilityr   r   ZLqZLkZLvr`   rŽ   r6   r„   r	   r	   r
   Úforwardr  sj    
"
&.                   óz_attention.forwardc              '   C   s  t j ¡ }|d dk}d}tƒ r$d}| j\}}}}}	| j}
|jd }| ¡ }|
r|t||ƒ}|f|j }t j	||j
|jd}nt j||jd}t  |¡}t  |¡}t  |	¡}tt|jd |ƒ| jd  f ||||| jd	 t| jd |
ròt||ƒndf |||| j||||||	|| ¡ | d¡| d¡| d¡| d
¡| d¡| d¡| d¡| d
¡| d¡| d¡| d¡| d
¡|jd |jd |jd |jd |jd  |jd  t||ƒ|jd  |jd  |jd  ||| j|
| j|ddd% t|jƒdkr|jdd}|||d d d fS )Nr   é	   r{   r|   r   r€   r   r   r\   rƒ   rz   )r   r   r   re   rf   rg   r„   r…   é   )Údim)r†   r‡   rˆ   r   Zsaved_tensorsr   r   Ú
contiguousr   r!   r   r   Z
zeros_liker‹   rc   rŽ   r   rx   r5   Znumelr   r   Úlenr.   )r‘   ra   r’   rg   ZBLOCKrQ   rU   rV   r`   r6   r   Z
seq_len_kvZreplicasZnew_dq_shaperv   ru   rt   rb   r	   r	   r
   Úbackwardš  s„    





û                  & îz_attention.backwardN)F)Ú__name__Ú
__module__Ú__qualname__Ústaticmethodr“   r™   r	   r	   r	   r
   ry   p  s   'ry   )Ú__doc__r†   r   Ú r   r   r   r   r   Z	constexprr[   rc   rw   rx   ZautogradÚFunctionry   ÚapplyZ	attentionr	   r	   r	   r
   Ú<module>   sD   

 õ^û ðc ñ b