U
    ®9%e4  ã                   @   sÆ   d Z ddlZddlmZmZ ddlm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dœdd„ƒZ
e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)Úlanguage)ÚBLOCK_MÚBLOCK_DMODELÚBLOCK_NÚ	IS_CAUSALc           6   	   C   sø  t  d¡}t  d¡}|| }t j| | ||f||	f|| df||fdd} t j|| ||f||fd||fdd}!t j|| ||f||fd||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  | ¡})|)|(  |j	j
¡})d}*|r0|d | n|}+t|*|+|ƒD ]0},t  |!¡}-t  |"¡}.t j||gt jd}/|r¦t  |#d d …d f |,|$d d d …f  k|/td
ƒ¡}/|/t j|)|-dd7 }/t  |%t  |/d¡¡}0t j |%|0 ¡}1t j |/|0d d …d f  ¡}2|&d |1 }3|'|3d d …d f 9 }'|'t j|2 |j	j
¡|.dd7 }'|&|1 t  |2d¡ }&|0}%t  |!d|f¡}!t  |"|df¡}"q@|'|&d d …d f  }'|||  |# }4t  |4|%t j |&¡ ¡ t j|| ||f||f|| df||fdd}5t  |5|' |j	j
¡¡ d S )Nr   é   )r
   r   )ÚbaseÚshapeÚstridesÚoffsetsZblock_shapeÚorder)r   r   )r   r
   ©ÚdtypeÚinfç/lîdG÷?ú-infT©Z
allow_tf32)ÚtlÚ
program_idZmake_block_ptrÚarangeÚzerosÚfloat32ÚfloatÚloadÚtor   Ú
element_tyÚrangeÚwhereÚdotÚmaximumÚmaxÚmathÚexp2ÚsumÚadvanceÚstoreÚlog2)6Ú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_vkÚ	stride_vnZ	stride_ozZ	stride_ohZ	stride_omZ	stride_onÚZÚHÚN_CTXr   r   r   r	   Ústart_mÚoff_hzZ
qvk_offsetZQ_block_ptrZK_block_ptrZV_block_ptrÚoffs_mÚoffs_nZm_iÚl_iÚaccÚqk_scaleÚqÚloÚhiÚstart_nÚkÚvÚqkZm_i_newÚalphaÚpZ	acc_scaleÚl_ptrsZO_block_ptr© rP   úY/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/triton/ops/flash_attention.pyÚ_fwd_kernel   s„    


úúú	


2
úrR   ©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&   r(   )
r/   ÚDOÚDeltar   rT   Zoff_mZoff_nÚoÚdoÚdeltarP   rP   rQ   Ú_bwd_preprocessr   s    66rZ   ©r   r   r   ÚSEQUENCE_PARALLELÚCAUSALc$           A      C   sè  |"r||  tj¡| 7 }|#r&|| }$nd}$|$t d|¡ }%|| t d|¡ }&t d|!¡}'t d| ¡}(| |%d d …d f | |(d d d …f |   })||&d d …d f | |(d d d …f |   }*||&d d …d f | |(d d d …f |   }+||%d d …d f | |(d d d …f |   },||%d d …d f | |(d d d …f |   }-|||  }.|
||  }/tj|| gtjd}0tj|| gtjd}1t |*¡}2t |+¡}3t|$|| |ƒD ]Ê}4|4|' }5t |)¡}6|#røt |5d d …d f |&d d d …f kt	dƒt	dƒ¡}7ntj||!gtjd}7|7t 
|6t |2¡¡7 }7|7|9 }7t |/|5 ¡}8tj |7|8d d …d f  ¡}9t |,¡}:|0tj
t |9  | jj¡¡|:dd7 }0t |.|5 ¡};tj
|:t |3¡dd}<|9|<|;d d …d f   |   | jj¡}=|1tj
t |=¡|6dd7 }1|"st |-¡}>|>tj
|=|2dd7 }>t |-|>¡ n4|"rLt tj
t |2¡t |=¡dd¡}>t |-|>¡ |-|| 7 }-|)|| 7 })|,|| 7 },q¦|	|&d d …d f | |(d d d …f |   }?||&d d …d f | |(d d d …f |   }@t |?|0¡ t |@|1¡ d S )Nr   r   g        r   Tr   )r   r   Zint64r   r   r   r   r   r    r   r!   Ztransr$   r%   r   r   r(   )Ar*   r+   r,   r-   rE   r/   rU   ÚDQÚDKÚDVr.   ÚDÚ
stride_dqar0   r1   r2   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r@   rI   Z	num_blockr   r   r   r\   r]   rG   Zoffs_qmrB   rA   Zoffs_kZq_ptrsZk_ptrsZv_ptrsZdo_ptrsZdq_ptrsZD_ptrsrO   ÚdvÚdkrJ   rK   r?   Zoffs_m_currrF   rL   rC   rN   rX   ZDiZdpZdsÚdqZdv_ptrsZdk_ptrsrP   rP   rQ   Ú_bwd_kernel_one_col_blockƒ   sd    
,,,,,


4
$&
",,rf   c            &   '   C   s€  |d } t  d¡}!|!| }"|!| }#| |"| |#|  7 } ||"| |#|  7 }||"| |#|  7 }||"| |#|  7 }||"| |#|  7 }||"| |#|  7 }||"| |#|  7 }t  ||¡}$|s"td|$ƒD ]T}%t| |||| ||||||	|
|||||||||||||||||!|%|$|||||d$ qÊnZt  d¡}%t| |||| ||||||	|
|||||||||||||||||!|%|$|||||d$ d S )Nr   r   r[   r
   )r   r   r   r   rf   )&r*   r+   r,   r-   r/   rU   r^   r_   r`   r.   ra   rb   r0   r1   r2   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r   r   r   r\   r]   rE   r@   Zoff_zZoff_hZnum_block_nrI   rP   rP   rQ   Ú_bwd_kernelÝ   s¶    
                       ó

                       órg   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 ||	|||dd |  |||||¡ || _|| _|| _|| _|| _|S )Nr   é   zEFlash attention currently only supported for compute capability >= 80é€   é@   éÿÿÿÿ>   é   é    rk   rj   r   r
   ©Údevicer   é   é   )r   r   r   r	   Ú	num_warpsÚ
num_stages)ÚtorchÚcudaZget_device_capabilityÚRuntimeErrorr   ÚAssertionErrorÚ
empty_liker   Úemptyrp   r   rR   ÚstrideZsave_for_backwardÚgridr-   r   ÚcausalÚsequence_parallel)ÚctxrF   rJ   rK   r}   r-   r~   Z
capabilityr   r   ZLqZLkZLvrW   r|   r.   rs   rP   rP   rQ   Úforward#  sh    
"
&.                   ôz_attention.forwardc              $   C   s¬  d}| j \}}}}}| j}|jd }	| ¡ }|r\t|	|ƒ}
|
f|j }tj||j|jd}ntj	|tj
d}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|| jd	dd
" t|jƒdkrœ|jdd}|||d d d fS )Nrj   r   ro   r   r   r
   rS   rr   ri   )r   r   r   r\   r]   rs   rt   é   )Údim)Zsaved_tensorsr~   r   Ú
contiguousr   ru   r   rp   r   Z
zeros_liker   ry   rZ   r|   r   rg   r-   Znumelr{   r}   Úlenr&   )r   rX   ZBLOCKrF   rJ   rK   rW   r.   r~   Z
seq_len_kvZreplicasZnew_dq_shapere   rd   rc   rY   rP   rP   rQ   ÚbackwardI  sv    




  ý                   ñz_attention.backwardN)F)Ú__name__Ú
__module__Ú__qualname__Ústaticmethodr€   r…   rP   rP   rP   rQ   rh   !  s   %rh   )Ú__doc__ru   Ú r   r   r   r   Z	constexprrR   rZ   rf   rg   ZautogradÚFunctionrh   ÚapplyZ	attentionrP   rP   rP   rQ   Ú<module>   s:   

 õ` ý òY òCT