o
    Xi|+                     @  s   d dl mZ d dlmZmZ d dlZd dlmZm	Z	m
Z
 eeejf ZG dd de
jZdd d	D Ze
d
d eD ZeeZdS )    )annotations)SequenceUnionN)_fusion_utils	_ir_utilspatternc                      sZ   e Zd Zd fddZdd Z													dd	d
Z			dddZ  ZS )AttentionFusionhas_pastboolno_slicec                  s   t  | || _|| _d S N)super__init__	_has_past	_no_slice)selfnamer	   r   	__class__ ]/home/ubuntu/.local/lib/python3.10/site-packages/onnxscript/rewriter/ort_fusions/attention.pyr      s   
zAttentionFusion.__init__c                 C  sx  | j r|||}|||}|||}n-|j||dgd}|j|||dgdgd}|j||	|
dgdgd}|j|||dgdgd}| jr|j|dgdgdgd	gd}||dg}|j|dgdgdgd
gd}||dg}|j||||d tjddd|||dg dd\}}}||dg}||dg}|j	||dd}||fS |j||||d tjdddd d |ddgd}|S )N	projected)_outputs   query_mm_slicedkey_mm_slicedvalue_mm_slicedr      past_key_slicedpast_value_slicedattention_biasT)can_match_nonecom.microsoft)
mha_outputpresent_keypresent_value)	num_heads_domainr   axisr#   )
r   MatMulSlicer   SqueezeMultiHeadAttentionr   Var	UnsqueezeConcat)r   opinput
qkv_weightqkv_biaspastr&   start1end1start2end2start3end3q_mulk_mulv_mul	query_BSDkey_BSD	value_BSDr   past_key
past_value	attentionr$   r%   presentr   r   r   r      s   
zAttentionFusion.patternNc              
     s  t  }i _d(fdd}||g d	r|d
| d|S js|d u s2|jd u s2t|jdkr8|d|S |jd  t tsH|d|S t	
|drlt	|	t	|
krlt	|t	|krlt	
| fddsr|d|S ||ddgr|d
| d|S ||g dr|d
| d|S ||g dr|d
| d|S ||g dr|d
| d|S n3||ddgr|d
| d|S ||ddgr|d
| d |S ||dd!gr|d
| d"|S jd}jd}jd}jd!}t|trt|trt|ts|d#S jsBt|ts(|d$S ||| | krB|d%| d&| d'| d'| S |S ))Nvalir.ValuedimsSequence[str]returnr
   c                   s   t  j| | S r   )r   check_shape_boolbindings)rF   rH   )r   r   r   no_match   s   z'AttentionFusion.check.<locals>.no_match)BSDzShape mismatch: z3 does not match expected dimensions ['B', 'S', 'D']   z$Input projection is not a 3D tensor.r   zHidden size is not an integer.r   c                   s   |  kS r   r   )x)hidden_sizer   r   <lambda>   s    z'AttentionFusion.check.<locals>.<lambda>zPProjected input is not being split into q, k, v correctly based on hidden sizes.rP   Dhz/ does not match expected dimensions ['D', 'Dh'])rN   rO   Dh_qz6 does not match expected dimensions ['B', 'S', 'Dh_q'])rN   rO   Dh_kz6 does not match expected dimensions ['B', 'S', 'Dh_k'])rN   rO   Dh_vz6 does not match expected dimensions ['B', 'S', 'Dh_v']rV   z1 does not match expected dimensions ['D', 'Dh_q']rW   z1 does not match expected dimensions ['D', 'Dh_k']rX   z1 does not match expected dimensions ['D', 'Dh_v']z>Could not determine the hidden sizes of query, key, and value.z4Could not determine the total hidden size of weight.zBHidden size of query, key and value do not add up to hidden size: z != z + )rF   rG   rH   rI   rJ   r
   )r   MatchResultrL   failr   shapelen
isinstanceintr   is_singleton_valueget_singleton_valueget)r   r1   r2   r3   r   r   r   r   r6   r7   r8   r9   r:   r;   r<   r=   r>   _check_resultrM   rU   rV   rW   rX   r   )rS   r   r   check   s   
 









$zAttentionFusion.checkc                 K  s   | j d}| j d}| j d}|||g}| jr#|j|	|
|dd}| jdd }| jrE|j|||d |||||ddd	\}}||fS |j|||d d |d |||ddd	S )
NrV   rW   rX   r   r(   scaler"   r   )r&   qkv_hidden_sizesre   r'   r   )	rL   ra   r   r0   producer
attributes	get_floatr   	Attention)r   r1   r2   r3   r4   r5   r    r&   r#   r<   r=   r>   rb   rV   rW   rX   rf   re   rD   rE   r   r   r   rewrite   sH   

zAttentionFusion.rewrite)r	   r
   r   r
   )NNNNNNNNNNNNN)NNN)__name__
__module____qualname__r   r   rd   rk   __classcell__r   r   r   r   r      s*    s
}r   c                 C  sB   g | ]}d D ]}d|rdnd |rdnd  d||dqqS )FT
attention_
with_past_ r   rb   )r   r	   r   )strip).0r	   r   r   r   r   
<listcomp>;  s    	rv   rp   c                 C  s(   g | ]}t j|d  |d |d dqS )r   r	   r   )r	   r   )r   rule)ru   paramsr   r   r   rv   I  s    )
__future__r   typingr   r   onnx_irironnxscript.rewriterr   r   r   r^   SymbolicDimDimRewriteRuleClassBaser   parameter_combinationsRewriteRuleSetattention_rulesapply_fusion_rulesfuse_attentionr   r   r   r   <module>   s"     ,