o
    Xi                     @  s   d dl mZ d dlZd dlmZ d dlZd dlmZm	Z	m
Z
 d dlmZ eeejf ZG dd de
jZe
e gZeeZdS )    )annotationsN)Union)_fusion_utils	_ir_utilspattern)MatchFailureErrorc                   @  s2   e Zd ZU ded< dd ZdddZdddZdS )SDPAzfloat | None_scalec	                 C  s^  |j |g dd}	||tj}
|j |
g dd}||tj}|j |g dd}tj|	||gdg dd}tj|||||||gdg d	d}tj|||||||gd
g d	d}|||}tj|||||||gdg d	d}|||}tj||gdddgd}|j	|dd}|
|}||d|}t||g}|||}|S )N)r            )perm)r   r   r
   )r   r   r   r
   
key_format)BHSdr   BSHd)tag_var
tag_valuesquery_scaling)MulDivNonekey_scaling
qk_scalinghas_maskTF)axisg        )	TransposeReshaper   	ANY_VALUEOrValuer   r   MatMulAddSoftmaxIsNaNWhere)selfopquerykeyvaluemaskquery_scale	key_scaleqk_scalekey_transposed_1key_3dkey_3d_transposedkey_transposed_2key_transposed_3key_transposed
attn_scoremasked_attn_scoreattn_weightis_nanadj_attn_weightattn_output r:   X/home/ubuntu/.local/lib/python3.10/site-packages/onnxscript/rewriter/ort_fusions/sdpa.pyr      sZ   

	





zSDPA.patternr'   ir.Value | Noner(   r)   r*   r   strc                   s   t  }i }	t|	|g d |dkrt|	|g d n|dks(J d| t|	|g d t|	|g d d fdd}
|
dd}|
dd}|
dd}|| | | _|	d }t|tsb|S dt| }tj	| j|dddrvd | _|S )N)BHSDhr   )r>   r?   SkvrA   r   zUnexpected key format: )r>   rB   r?   rA   )r>   r?   rB   Dvtag_namer=   
scale_namereturnfloatc                   sp     | d}|dkrdS   |}t|}|d u r"t| d||dkr(|S |dks4J d| dd| S )Nr         ?z is not a scalar.r   r   zUnexpected z scaling operation)getr   get_singleton_valuer   )rD   rE   scaling_typescaler)   match_bindingsr:   r;   get_scale_value   s   

z#SDPA.check.<locals>.get_scale_valuer   r+   r   r,   r   r-   rA   rH   gh㈵>g:0yE>)rel_tolabs_tol)rD   r=   rE   r=   rF   rG   )
r   MatchResultr   check_shaper	   
isinstanceintmathsqrtisclose)r%   contextr'   r(   r)   r*   r   rN   check_resultbindingsrO   query_scale_valuekey_scale_valueqk_scale_value	head_sizedefault_scaling_factorr:   rM   r;   checkm   s(   




z
SDPA.checkc           	      K  s2   |||g}|d ur| | |j|| j|ddS )Nzai.onnxruntime._fusion)rL   r   _domain)appendr   r	   )	r%   r&   r'   r(   r)   r*   r   _	sdpa_argsr:   r:   r;   rewrite   s   


zSDPA.rewriteN)
r'   r<   r(   r<   r)   r<   r*   r<   r   r=   )__name__
__module____qualname____annotations__r   ra   rf   r:   r:   r:   r;   r      s
   
 
N?r   )
__future__r   rV   typingr   onnx_irironnxscript.rewriterr   r   r   onnxscript.rewriter._basicsr   rU   SymbolicDimDimRewriteRuleClassBaser   RewriteRuleSetrule
sdpa_rulesapply_fusion_rules	fuse_sdpar:   r:   r:   r;   <module>   s    (