§
    kŠtjïÆ  ã                   ó²   — d dl 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mZmZmZ d dlmZ  ee¦  «        Z G d„ d	¦  «        Z G d
„ de¦  «        ZdS )é    )Ú	getLoggerN)ÚFusion)ÚAttentionMaskFormat)ÚFusionUtilsÚNumpyHelper)Ú	NodeProtoÚTensorProtoÚhelperÚnumpy_helper)Ú	OnnxModelc                   óL   — e Zd ZdZdefd„Zdefd„Zd„ Zd„ Z	de
d	e
d
z  fd„Zd
S )ÚAttentionMaskú:
    Fuse Attention subgraph into one Attention node.
    Úmodelc                 ó¬   — || _         i | _        i | _        t          |¦  «        | _        t
          j        | _        |                     ¦   «         | _	        d S ©N)
r   Úmask_indiceÚmask_castedr   Úutilsr   ÚMaskIndexEndÚmask_formatÚget_opset_versionÚopset_version)Úselfr   s     úg/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/onnxruntime/transformers/fusion_attention.pyÚ__init__zAttentionMask.__init__   sM   € ØˆŒ
àˆÔàˆÔÝ  Ñ'Ô'ˆŒ
Ý.Ô;ˆÔØ"×4Ò4Ñ6Ô6ˆÔÐÐó    r   c                 ó   — || _         d S r   )r   )r   r   s     r   Úset_mask_formatzAttentionMask.set_mask_format    s   € Ø&ˆÔÐÐr   c                 óR   — || j         v r|| j         |         k    sJ ‚|| j         |<   d S r   )r   )r   ÚmaskÚ
mask_indexs      r   Úset_mask_indicezAttentionMask.set_mask_indice#   s<   € Ø�4Ô#Ð#Ð#Ø Ô!1°$Ô!7Ò7Ð7Ð7Ð7Ø!+ˆÔ˜ÑÐÐr   c                 óx   — t          | j        ¦  «        dk    sJ ‚t          t          | j        ¦  «        ¦  «        S ©Nr   )Úlenr   ÚnextÚiter)r   s    r   Úget_first_maskzAttentionMask.get_first_mask(   s7   € Ý�4Ô#Ñ$Ô$ qÒ(Ð(Ð(Ð(Ý•D˜Ô)Ñ*Ô*Ñ+Ô+Ð+r   Úmask_2dÚreturnNc           	      ó^  — | j         t          j        k    rd S || j        v r| j        |         S | j                             |¦  «        r| j                             |¦  «        \  }}n| j                             |¦  «        \  }}d}|r
|| j	        |<   | j         t          j
        k    r|| j        |<   |S | j                             d¦  «        }| j        dk     rwt          j        d|g|g| j                             dd¦  «        ¬¦  «        }|j                             t          j        ddg¦  «        t          j        d	d
¦  «        g¦  «         n»d}| j                             |¦  «        €=| j                             t          j        |t*          j        dgdgd¬¦  «        ¦  «         t          j        d||g|g| j                             dd¦  «        ¬¦  «        }|j                             t          j        d	d
¦  «        g¦  «         | j                             |¦  «         || j        |<   |S )NTr"   é   Ú	ReduceSumÚMaskReduceSum©ÚinputsÚoutputsÚnameÚaxesé   Úkeepdimsr   Úort_const_1_reduce_sum_axesF©r3   Ú	data_typeÚdimsÚvalsÚraw)r   r   ÚNoMaskr   r   Úfind_graph_inputr   Úcast_graph_input_to_int32Úcast_input_to_int32r   r   Úcreate_node_namer   r
   Ú	make_nodeÚ	attributeÚextendÚmake_attributeÚget_initializerÚadd_initializerÚmake_tensorr	   ÚINT64Úadd_node)r   r*   ÚcastedÚ
input_nameÚ
_cast_nodeÚoutput_nameÚmask_index_nodeÚ	axes_names           r   Úprocess_maskzAttentionMask.process_mask,   sW  € ØÔÕ2Ô9Ò9Ð9Ø�4à�dÔ&Ð&Ð&ØÔ# GÔ,Ð,ð Œ:×&Ò& wÑ/Ô/ð 	Ø!%¤×!EÒ!EÀgÑ!NÔ!NÑˆF�J�Jà%)¤Z×%CÒ%CÀGÑ%LÔ%LÑ"ˆJ˜
ØˆFàð 	3Ø(2ˆDÔ˜WÑ%ð ÔÕ2Ô@Ò@Ð@Ø(2ˆDÔ˜WÑ%ØÐð ”j×1Ò1°,Ñ?Ô?ˆØÔ Ò"Ð"Ý$Ô.ØØ"�|Ø$˜Ø”Z×0Ò0°¸oÑNÔNð	ñ ô ˆOð Ô%×,Ò,­fÔ.CÀFÈQÈCÑ.PÔ.PÕRXÔRgÐhrÐtuÑRvÔRvÐ-wÑxÔxÐxÐxð 6ˆIØŒz×)Ò)¨)Ñ4Ô4Ð<Ø”
×*Ò*ÝÔ&Ø&Ý"-Ô"3Ø˜SØ˜SØ!ðñ ô ñô ð õ %Ô.ØØ" IÐ.Ø$˜Ø”Z×0Ò0°¸oÑNÔNð	ñ ô ˆOð Ô%×,Ò,­fÔ.CÀJÐPQÑ.RÔ.RÐ-SÑTÔTÐTàŒ
×Ò˜OÑ,Ô,Ð,à$/ˆÔ˜Ñ!ØÐr   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r#   r)   ÚstrrQ   © r   r   r   r      s™   € € € € € ðð ð7˜ið 7ð 7ð 7ð 7ð'Ð+>ð 'ð 'ð 'ð 'ð,ð ,ð ,ð
,ð ,ð ,ð8 Cð 8¨C°$©Jð 8ð 8ð 8ð 8ð 8ð 8r   r   c            (       óX  ‡ — e Zd ZdZdddddgfdededed	edz  d
ededee	         fˆ fd„Z
dedeeef         fd„Zdedeeef         fd„Zdefd„Zde	fd„Zde	de	de	fd„Zde	de	de	fd„Zdededz  dedz  d e	dedz  f
d!„Zd"ed#ed$edededz  dedz  deeeef         fd%„Z	 	 	 	 	 	 	 	 d5d"ed#ee	z  dz  d$ee	z  dz  dededz  dedz  deded'e	d(e	de	d)ede	de	d*e	d+e	d,ededz  f$d-„Z	 	 	 	 	 	 	 d6d.e	dz  d"ed#ed$edededededed/e	d'e	d0e	d1ede	de	d*e	d+e	d2edz  dedz  f&d3„Zd4„ Zˆ xZS )7ÚFusionAttentionr   NFÚSkipLayerNormalizationÚLayerNormalizationr   Úhidden_sizeÚ	num_headsÚattention_maskÚuse_multi_head_attentionÚ!disable_multi_head_attention_biasÚsearch_op_typesc                 ó  •— |rdnd}t          ¦   «                              |||¦  «         || _        || _        |r|nt	          |¦  «        | _        || _        || _        d | _        d| _	        d| _
        d | _        d| _        d S )NÚMultiHeadAttentionÚ	AttentionT)Úsuperr   r\   r]   r   r^   r_   r`   Úmask_filter_valueÚnum_heads_warningÚhidden_size_warningÚshape_inferÚshape_infer_done)
r   r   r\   r]   r^   r_   r`   ra   Úattention_op_nameÚ	__class__s
            €r   r   zFusionAttention.__init__l   sž   ø€ ð 5MÐ]Ð0Ð0ÐR]ÐÝ‰Œ×Ò˜Ð 1°?ÑCÔCÐCØ&ˆÔØ"ˆŒØ0>ÐX˜n˜nÅMÐRWÑDXÔDXˆÔØ(@ˆÔ%Ø1RˆÔ.Ø!%ˆÔð "&ˆÔØ#'ˆÔ àˆÔØ $ˆÔÐÐr   Úconcatr+   c                 ó¨  — t          |j        ¦  «        dk    r­| j                             |j        d         ¦  «        }| j                             |j        d         ¦  «        }t	          |t
          j        ¦  «        rI|j        dk    r>t	          |t
          j        ¦  «        r$|j        dk    r|d         |d         |d         z  fS | j        | j	        fS )aU  
        Detect num_heads and hidden_size from Concat node in the following subgraph:

        SkipLayerNormalization or EmbedLayerNormalization
                        /        |
                     MatMul    Shape
                        |        |
                       Add     Gather(indices=0)
                        |        |
                        |      Unsqueeze
                        |        |
                        |     Concat (*, -1, 12, 64)
                        |     /
                       Reshape
                          |
                       Transpose
        é   é   é   r5   r   )
r&   Úinputr   Úget_constant_valueÚ
isinstanceÚnpÚndarrayÚsizer]   r\   )r   rm   r]   Ú	head_sizes       r   Ú)get_num_heads_and_hidden_size_from_concatz9FusionAttention.get_num_heads_and_hidden_size_from_concat†   s¾   € õ$ ˆvŒ|ÑÔ Ò!Ð!Øœ
×5Ò5°f´lÀ1´oÑFÔFˆIØœ
×5Ò5°f´lÀ1´oÑFÔFˆIå˜9¥b¤jÑ1Ô1ðAà”N aÒ'Ð'Ý˜y­"¬*Ñ5Ô5ð (à”N aÒ'Ð'à  ”| Y¨q¤\°I¸a´LÑ%@Ð@Ð@àŒ~˜tÔ/Ð/Ð/r   Ú	reshape_qc                 óT  — | j                              |j        d         ¦  «        }|€q| j                              |d¦  «        }|� |j        dk    r|                      |¦  «        S t                               d|j        d         ¦  «         | j        | j	        fS t          |t          j        ¦  «        r+t          |¦  «        dk    s|d         dk    s|d         dk    r)t                               d	|¦  «         | j        | j	        fS |d         }|d         }||z  }| j        dk    r:|| j        k    r/| j        r(t                               d
| j        |¦  «         d| _        | j	        dk    r:|| j	        k    r/| j        r(t                               d| j	        |¦  «         d| _        ||fS )zÌDetect num_heads and hidden_size from a reshape node.

        Args:
            reshape_q (NodeProto): reshape node for Q

        Returns:
            Tuple[int, int]: num_heads and hidden_size
        r5   NÚConcatz%s is not initializer.ro   rp   r   rq   zGq_shape_value=%s. Expected value are like [0, 0, num_heads, head_size].z>--num_heads is %d. Detected value is %d. Using detected value.Fz@--hidden_size is %d. Detected value is %d. Using detected value.)r   rs   rr   Ú
get_parentÚop_typery   ÚloggerÚdebugr]   r\   rt   ru   rv   r&   rg   Úwarningrh   )r   rz   Úq_shape_valuerm   r]   rx   r\   s          r   Úget_num_heads_and_hidden_sizez-FusionAttention.get_num_heads_and_hidden_size¥   sÈ  € ð œ
×5Ò5°i´oÀaÔ6HÑIÔIˆØÐ Ø”Z×*Ò*¨9°aÑ8Ô8ˆFØÐ! f¤n¸Ò&@Ð&@Ø×EÒEÀfÑMÔMÐMÝ�LŠLÐ1°9´?À1Ô3EÑFÔFÐFØ”> 4Ô#3Ð3Ð3õ ˜M­2¬:Ñ6Ô6ð	4å�=Ñ!Ô! QÒ&Ð&Ø˜aÔ  AÒ%Ð%¨°qÔ)9¸QÒ)>Ð)>å�LŠLÐbÐdqÑrÔrÐrØ”> 4Ô#3Ð3Ð3à! !Ô$ˆ	Ø! !Ô$ˆ	Ø )Ñ+ˆàŒ>˜AÒÐ )¨t¬~Ò"=Ð"=ØÔ%ð /Ý—’ØTÐVZÔVdÐfoñô ð ð */�Ô&àÔ˜aÒÐ K°4Ô3CÒ$CÐ$CØÔ'ð 1Ý—’ØVÐX\ÔXhÐjuñô ð ð ,1�Ô(à˜+Ð%Ð%r   Úadd_qkc                 ó¦  — | j         s'| j                             d¬¦  «        | _        d| _         | j        €d S | j                             |j        d         ¦  «        }| j                             |j        d         ¦  «        }|�|€t                               d|¦  «         d S ||k    rt                               d|¦  «         d S |j        d         S )NT)Úupdater   r5   zone of the inputs of %s is Nonez)the shape of two inputs of %s is not same)rj   r   Úinfer_runtime_shaperi   Úget_edge_shaperr   r   r€   )r   r„   Úinput_0_shapeÚinput_1_shapes       r   Úget_add_qk_strzFusionAttention.get_add_qk_strÓ   sÌ   € ØÔ$ð 	)Ø#œz×=Ò=ÀTÐ=ÑJÔJˆDÔØ$(ˆDÔ!àÔÐ#Ø�4àÔ(×7Ò7¸¼ÀQ¼ÑHÔHˆØÔ(×7Ò7¸¼ÀQ¼ÑHÔHˆàÐ  MÐ$9Ý�LŠLÐ:¸FÑCÔCÐCØ�4à˜MÒ)Ð)Ý�LŠLÐDÀfÑMÔMÐMØ�4àŒ|˜AŒÐr   c                 ó¨  ‡‡— ‰dz   Št          t          ˆfd„| j        ¦  «        ¦  «        }t          |¦  «        dk    r‰S t          |¦  «        dk    sJ ‚| j                             d¦  «        }t          j        dˆfd„t          | j	        ¦  «        D ¦   «         ‰g|d¬¦  «        }| j         
                    |¦  «         | j        | j        |<   ‰S )NÚ_maskc                 ó&   •— | j         d         ‰k    S r%   )Úoutput)ÚnodeÚmask_output_names    €r   ú<lambda>z0FusionAttention.reshape_add_qk.<locals>.<lambda>î   s   ø€ ¨t¬{¸1¬~ÐAQÒ/Q€ r   r5   r   r|   c                 ó   •— g | ]}‰‘ŒS rW   rW   )Ú.0Ú_r„   s     €r   ú
<listcomp>z2FusionAttention.reshape_add_qk.<locals>.<listcomp>ö   s   ø€ Ð:Ð:Ð:˜q�FÐ:Ð:Ð:r   ©r1   r2   r3   Úaxis)ÚlistÚfilterÚnodes_to_addr&   r   rA   r
   rB   Úranger]   ÚappendÚthis_graph_nameÚnode_name_to_graph_name)r   r„   Úconcat_nodeÚconcat_node_nameÚconcat_add_qk_fp32r‘   s    `   @r   Úreshape_add_qkzFusionAttention.reshape_add_qkè   sù   øø€ ð " GÑ+Ðõ �6Ð"QÐ"QÐ"QÐ"QÐSWÔSdÑeÔeÑfÔfˆÝˆ{ÑÔ˜qÒ Ð Ø#Ð#å�;ÑÔ 1Ò$Ð$Ð$Ð$Øœ:×6Ò6°xÑ@Ô@ÐÝ#Ô-ØØ:Ð:Ð:Ð:¥E¨$¬.Ñ$9Ô$9Ð:Ñ:Ô:Ø%Ð&Ø!Øð
ñ 
ô 
Ðð 	Ô× Ò Ð!3Ñ4Ô4Ð4Ø9=Ô9MˆÔ$Ð%5Ñ6àÐr   Úpast_kÚpast_vc                 ó   — | j                              d¦  «        }| j                              d¦  «        }|dz                        dd¦  «        }|dz                        dd¦  «        }t          j        d|g|g|dg¬¦  «        }t          j        d|g|g|dg¬¦  «        }| j                             |¦  «         | j                             |¦  «         | j        | j        |<   | j        | j        |<   | j                              d¦  «        }	|                     dd	¦  «                             dd¦  «                             d
d¦  «        }
t          j        d||g|
g|	d¬¦  «        }| j                             |¦  «         | j        | j        |	<   |
S )zýConcatenate past_k and past_v inputs to create past_kv input.

        Args:
            past_k (str): name of past K value
            past_v (str): name of past V value

        Returns:
            kv_output_name (str): name of past KV value
        Ú	UnsqueezeÚ_5dú.r•   r   )r1   r2   r3   r4   r|   z.valuez.kvÚ_valueÚ_kvr—   )	r   rA   Úreplacer
   rB   r›   r�   rž   rŸ   )r   r¤   r¥   Úunsqueeze_k_nameÚunsqueeze_v_nameÚ	k_5d_nameÚ	v_5d_nameÚk_5dÚv_5dr¡   Úkv_output_nameÚ	concat_kvs               r   r´   zFusionAttention.concat_kv  s¹  € ð  œ:×6Ò6°{ÑCÔCÐØœ:×6Ò6°{ÑCÔCÐØ˜e‘^×,Ò,¨S°#Ñ6Ô6ˆ	Ø˜e‘^×,Ò,¨S°#Ñ6Ô6ˆ	åÔØØ�8Ø�KØ!Ø�ð
ñ 
ô 
ˆõ ÔØØ�8Ø�KØ!Ø�ð
ñ 
ô 
ˆð 	Ô× Ò  Ñ&Ô&Ð&ØÔ× Ò  Ñ&Ô&Ð&Ø9=Ô9MˆÔ$Ð%5Ñ6Ø9=Ô9MˆÔ$Ð%5Ñ6ð  œ:×6Ò6°xÑ@Ô@ÐØŸš¨°%Ñ8Ô8×@Ò@ÀÀcÑJÔJ×RÒRÐS[Ð]bÑcÔcˆÝÔ$ØØ˜yÐ)Ø#Ð$Ø!Øð
ñ 
ô 
ˆ	ð 	Ô× Ò  Ñ+Ô+Ð+Ø9=Ô9MˆÔ$Ð%5Ñ6àÐr   Úpresent_k_nameÚpresent_v_nameÚkv_nodec                 ó$  — d\  }}| j                              |¦  «        }| j                              |¦  «        }|€Jt          j        t	          j        dd¬¦  «        |¬¦  «        }| j                              || j        ¦  «         |€Jt          j        t	          j        dd¬¦  «        |¬¦  «        }| j                              || j        ¦  «         | j                              d¦  «        }| j                              d¦  «        }	t          j
        d||g|g|d¬	¦  «        }
t          j
        d||g|g|	d¬	¦  «        }| j                             |
¦  «         | j                             |¦  «         | j        | j        |<   | j        | j        |	<   dS )
a?  Split kv_node containing present KV values into separate present K and present V values.

        Args:
            present_k_name (str): name of output to store present K value in
            present_v_name (str): name of output to store present V value in
            kv_node (str): name of present KV values
        )Úindex_0Úindex_1Nr   Úint64)Údtype©r3   r5   ÚGatherr—   )r   rF   r   Ú
from_arrayru   ÚarrayrG   rž   rA   r
   rB   r›   r�   rŸ   )r   rµ   r¶   r·   Úk_indexÚv_indexÚk_dimÚv_dimÚgather_k_nameÚgather_v_nameÚ	present_kÚ	present_vs               r   Úsplit_kvzFusionAttention.split_kv8  s   € ð 0Ñˆ�Ø”
×*Ò*¨7Ñ3Ô3ˆØ”
×*Ò*¨7Ñ3Ô3ˆØˆ=Ý Ô+­B¬H°Q¸gÐ,FÑ,FÔ,FÈWÐUÑUÔUˆEØŒJ×&Ò& u¨dÔ.BÑCÔCÐCØˆ=Ý Ô+­B¬H°Q¸gÐ,FÑ,FÔ,FÈWÐUÑUÔUˆEØŒJ×&Ò& u¨dÔ.BÑCÔCÐCð œ
×3Ò3°HÑ=Ô=ˆØœ
×3Ò3°HÑ=Ô=ˆÝÔ$ØØ˜WÐ%Ø#Ð$ØØð
ñ 
ô 
ˆ	õ Ô$ØØ˜WÐ%Ø#Ð$ØØð
ñ 
ô 
ˆ	ð 	Ô× Ò  Ñ+Ô+Ð+ØÔ× Ò  Ñ+Ô+Ð+Ø6:Ô6JˆÔ$ ]Ñ3Ø6:Ô6JˆÔ$ ]Ñ3Ð3Ð3r   Úq_addÚk_addÚv_addÚname_prefixc                 óD  — | j                              |j        d         ¦  «        p$| j                              |j        d         ¦  «        }t          j        |¦  «        }t          j        |¦  «        }t          j        |¦  «        }|�^| j                              |j        d         ¦  «        p$| j                              |j        d         ¦  «        }	t          j        |	¦  «        }|�^| j                              |j        d         ¦  «        p$| j                              |j        d         ¦  «        }
t          j        |
¦  «        }t          j        |||fd¬¦  «        }dt          j        |j	        ¦  «        z  }|dz   }|  
                    ||j        |g|¬¦  «         |S )Nr5   r   ©r˜   rq   Ú	_qkv_bias©r3   r9   r:   r;   )r   rF   rr   r   Úto_arrayru   Ú
zeros_likeÚstackÚprodÚshaperG   r9   )r   rÊ   rË   rÌ   rÍ   Úq_biasÚqbÚkbÚvbÚk_biasÚv_biasÚqkv_biasÚqkv_bias_dimÚ	bias_names                 r   Úcreate_combined_qkv_biasz(FusionAttention.create_combined_qkv_biase  s|  € ð ”×+Ò+¨E¬K¸¬NÑ;Ô;Ði¸t¼z×?YÒ?YÐZ_ÔZeÐfgÔZhÑ?iÔ?iˆÝÔ! &Ñ)Ô)ˆÝŒ]˜2ÑÔˆÝŒ]˜2ÑÔˆØÐØ”Z×/Ò/°´¸A´Ñ?Ô?ÐmÀ4Ä:×C]ÒC]Ð^cÔ^iÐjkÔ^lÑCmÔCmˆFÝÔ% fÑ-Ô-ˆBØÐØ”Z×/Ò/°´¸A´Ñ?Ô?ÐmÀ4Ä:×C]ÒC]Ð^cÔ^iÐjkÔ^lÑCmÔCmˆFÝÔ% fÑ-Ô-ˆBå”8˜R  R˜L¨qÐ1Ñ1Ô1ˆØ�2œ7 2¤8Ñ,Ô,Ñ,ˆà +Ñ-ˆ	Ø×ÒØØÔ&Ø�Øð	 	ñ 	
ô 	
ð 	
ð Ðr   Úq_matmulÚk_matmulÚv_matmulc                 óÐ  — | j                              d¦  «        }|j        d         |j        d         k    r|j        d         |j        d         k    sJ ‚| j                              |j        d         ¦  «        }| j                              |j        d         ¦  «        }	| j                              |j        d         ¦  «        }
t	          j        |¦  «        }t	          j        |	¦  «        }t	          j        |
¦  «        }|j        |j        k    r|j        |j        k    sJ ‚|j        d         }t          j        |||fd¬¦  «         	                    |d|z  f¦  «        }|dz   }|  
                    ||j        |j        d         |j        d         g|¬¦  «         |dz   }t          j        d|j        d         |g|g|¬	¦  «        }| j        | j        |<   |g}|d
z   }|  
                    |t           j        dgdgd¬¦  «         |dz   }|  
                    |t           j        dg|gd¬¦  «         |dz   }|  
                    |t           j        dgd|z  gd¬¦  «         |dz   }|  
                    |t           j        dgd|z  gd¬¦  «         |dz   }|  
                    |t           j        dgdgd¬¦  «         |dz   }t          j        d||||g|g| j                              d¦  «        ¬	¦  «        }| j        | j        |j        <   |dz   }t          j        d||||g|g| j                              d¦  «        ¬	¦  «        }| j        | j        |j        <   |dz   }t          j        d||||g|g| j                              d¦  «        ¬	¦  «        }| j        | j        |j        <   |}|} |}!|                     |||g¦  «         | j        �r|�ª| j                              |j        d         ¦  «        rdnd}"t          j        t	          j        | j                              |j        |"         ¦  «        ¦  «        ¦  «        r8||j        d|"z
  <   |}|                     |¦  «         | j        | j        |j        <   |�ª| j                              |j        d         ¦  «        rdnd}"t          j        t	          j        | j                              |j        |"         ¦  «        ¦  «        ¦  «        r8||j        d|"z
  <   |} |                     |¦  «         | j        | j        |j        <   |�ª| j                              |j        d         ¦  «        rdnd}"t          j        t	          j        | j                              |j        |"         ¦  «        ¦  «        ¦  «        r8||j        d|"z
  <   |}!|                     |¦  «         | j        | j        |j        <   | j                             |¦  «         || |!fS )a©  Create packed QKV MatMul node before MultiHeadAttention node.
           This is for the scenario where an Attention node should be created but cannot be created
           because past_key and past_value are separate inputs and not one concatenated input.

        Args:
            q_matmul (NodeProto): name of MatMul from Q path - (batch_size, sequence_length, hidden_size)
            k_matmul (NodeProto): name of MatMul from K path - (batch_size, sequence_length, hidden_size)
            v_matmul (NodeProto): name of MatMul from V path - (batch_size, sequence_length, hidden_size)
            q_add (NodeProto): name of Add from Q path
            k_add (NodeProto): name of Add from K path
            v_add (NodeProto): name of Add from V path

        Returns:
             q_output (NodeProto): Slice node for Q
             k_output (NodeProto): Slice node for K
             v_output (NodeProto): Slice node for V
        ÚMatMulr   r5   rÏ   rq   Ú_qkv_weightrÑ   Ú_qkv_outr0   Ú_q_start_indexFr8   Ú_k_start_indexÚ_v_start_indexrp   Ú_end_of_qkv_indexÚ_qkv_last_axiséÿÿÿÿÚ_q_outÚSliceÚ_k_outÚ_v_out)r   rA   rr   rF   r   rÒ   rÖ   ru   rÔ   ÚreshaperG   r9   r
   rB   rž   rŸ   r	   rI   r3   rD   r`   Úanyr�   r›   )#r   rá   râ   rã   rÊ   rË   rÌ   Úmatmul_node_nameÚq_weightÚk_weightÚv_weightÚqwÚkwÚvwÚdÚ
qkv_weightÚqkv_weight_nameÚqkv_matmul_outputÚ
qkv_matmulÚ	qkv_nodesÚq_slice_nameÚk_slice_nameÚv_slice_nameÚend_of_qkv_nameÚqkv_last_axis_nameÚq_slice_outputÚq_sliceÚk_slice_outputÚk_sliceÚv_slice_outputÚv_sliceÚq_outputÚk_outputÚv_outputÚinitializer_inputs#                                      r   Úcreate_packed_qkv_matmul_nodez-FusionAttention.create_packed_qkv_matmul_nodeƒ  sP  € ð4  œ:×6Ò6°xÑ@Ô@Ðð Œ~˜aÔ  H¤N°1Ô$5Ò5Ð5¸(¼.ÈÔ:KÈxÌ~Ð^_ÔO`Ò:`Ð:`Ð:`Ð`ð ”:×-Ò-¨h¬n¸QÔ.?Ñ@Ô@ˆØ”:×-Ò-¨h¬n¸QÔ.?Ñ@Ô@ˆØ”:×-Ò-¨h¬n¸QÔ.?Ñ@Ô@ˆåÔ! (Ñ+Ô+ˆÝÔ! (Ñ+Ô+ˆÝÔ! (Ñ+Ô+ˆàŒx˜2œ8Ò#Ð#¨¬°B´HÒ(<Ð(<Ð(<Ð<ØŒH�QŒKˆå”X˜r 2 r˜l°Ð3Ñ3Ô3×;Ò;¸QÀÀAÁ¸JÑGÔGˆ
Ø*¨]Ñ:ˆà×ÒØ ØÔ(ØÔ" 1Ô% zÔ'7¸Ô':Ð;Øð	 	ñ 	
ô 	
ð 	
ð" -¨zÑ9ÐÝÔ%ØØ”N 1Ô% Ð7Ø&Ð'Ø!ð	
ñ 
ô 
ˆ
ð :>Ô9MˆÔ$Ð%5Ñ6à�Lˆ	ð (Ð*:Ñ:ˆØ×Ò ,½+Ô:KÐSTÐRUÐ]^Ð\_ÐejÐÑkÔkÐkØ'Ð*:Ñ:ˆØ×Ò ,½+Ô:KÐSTÐRUÐ]^Ð\_ÐejÐÑkÔkÐkØ'Ð*:Ñ:ˆØ×Ò ,½+Ô:KÐSTÐRUÐ]^ÐabÑ]bÐ\cÐinÐÑoÔoÐoØ*Ð-@Ñ@ˆØ×Ò /½[Ô=NÐVWÐUXÐ`aÐdeÑ`eÐ_fÐlqÐÑrÔrÐrØ-Ð0@Ñ@ÐØ×ÒÐ"4ÅÔ@QÐYZÐX[ÐceÐbfÐlqÐÑrÔrÐrà)¨HÑ4ˆÝÔ"ØØ% |°\ÐCUÐVØ#Ð$Ø”×,Ò,¨WÑ5Ô5ð	
ñ 
ô 
ˆð 6:Ô5IˆÔ$ W¤\Ñ2Ø)¨HÑ4ˆÝÔ"ØØ% |°\ÐCUÐVØ#Ð$Ø”×,Ò,¨WÑ5Ô5ð	
ñ 
ô 
ˆð 6:Ô5IˆÔ$ W¤\Ñ2Ø)¨HÑ4ˆÝÔ"ØØ% |°_ÐFXÐYØ#Ð$Ø”×,Ò,¨WÑ5Ô5ð	
ñ 
ô 
ˆð 6:Ô5IˆÔ$ W¤\Ñ2àˆØˆØˆØ×Ò˜' 7¨GÐ4Ñ5Ô5Ð5àÔ1ñ 	TØÐ Ø)-¬×)CÒ)CÀEÄKÐPQÄNÑ)SÔ)SÐ$Z A AÐYZÐ!Ý”6�+Ô.¨t¬z×/IÒ/IÈ%Ì+ÐVgÔJhÑ/iÔ/iÑjÔjÑkÔkð TØ9G�E”K Ð$5Ñ 5Ñ6Ø$�HØ×$Ò$ UÑ+Ô+Ð+Ø?CÔ?S�DÔ0°´Ñ<ØÐ Ø)-¬×)CÒ)CÀEÄKÐPQÄNÑ)SÔ)SÐ$Z A AÐYZÐ!Ý”6�+Ô.¨t¬z×/IÒ/IÈ%Ì+ÐVgÔJhÑ/iÔ/iÑjÔjÑkÔkð TØ9G�E”K Ð$5Ñ 5Ñ6Ø$�HØ×$Ò$ UÑ+Ô+Ð+Ø?CÔ?S�DÔ0°´Ñ<ØÐ Ø)-¬×)CÒ)CÀEÄKÐPQÄNÑ)SÔ)SÐ$Z A AÐYZÐ!Ý”6�+Ô.¨t¬z×/IÒ/IÈ%Ì+ÐVgÔJhÑ/iÔ/iÑjÔjÑkÔkð TØ9G�E”K Ð$5Ñ 5Ñ6Ø$�HØ×$Ò$ UÑ+Ô+Ð+Ø?CÔ?S�DÔ0°´Ñ<ð 	Ô× Ò  Ñ+Ô+Ð+Ø˜ 8Ð+Ð+r   Ú r�   Úkey_padding_maskÚunidirectionalrÇ   rÈ   Ú
packed_qkvc                 óz  — |dk    sJ ‚|dk    r'||z  dk    rt                                d||¦  «         dS d„ | j                             ¦   «         j        D ¦   «         }| j                             d¦  «        }g }|rY|                      ||||||¦  «        \  }}}|                     |j        d         |j        d         |j        d         g¦  «         �n(t          |t          ¦  «        r�t          |t          ¦  «        r{| j        r:|                     |j        d         |j        d         |j        d         g¦  «         n½|                     |j        d         |j        d         |j        d         g¦  «         nƒt          |t          ¦  «        rlt          |t          ¦  «        rW||v rS||v rO| j        r$|                     |j        d         ||g¦  «         n&|                     |j        d         ||g¦  «         ndS | j        s.|                      ||||¦  «        }|                     |¦  «         n|                     d¦  «         |r|r|                     |
|||g¦  «         n|
s|r|                     |
|g¦  «         |	g}|r|r|                     ||g¦  «         t          j        d|||¬¦  «        }d	|_        |j                             t          j        d
|¦  «        ¦  «         |r:|j                             t          j        dt)          |¦  «        ¦  «        ¦  «         |                      d¦  «         |S )aº  Create a MultiHeadAttention node.

        Args:
            q_matmul (NodeProto): name of MatMul from Q path - (batch_size, sequence_length, hidden_size)
            k_matmul (NodeProto): name of MatMul from K path - (batch_size, sequence_length, hidden_size) or (batch_size, num_heads, past_sequence_length, head_size)
            v_matmul (NodeProto): name of MatMul from V path - (batch_size, sequence_length, hidden_size) or (batch_size, num_heads, past_sequence_length, head_size)
            q_add (NodeProto): name of Add from Q path
            k_add (NodeProto): name of Add from K path
            v_add (NodeProto): name of Add from V path
            num_heads (int): number of attention heads. If a model is pruned, it is the number of heads after pruning.
            hidden_size (int): hidden dimension. If a model is pruned, it is the hidden dimension after pruning.
            output (str): output name of MHA
            key_padding_mask (str): name of key padding mask
            add_qk (str): name of add after Q x K'
            unidirectional (bool): whether to apply causal attention mask automatically or not
            past_k (str): name of past K value - (batch_size, num_heads, past_sequence_length, head_size)
            past_v (str): name of past V value - (batch_size, num_heads, past_sequence_length, head_size)
            present_k (str): name of present K value - (batch_size, num_heads, sequence_length, head_size)
            present_v (str): name of present V value - (batch_size, num_heads, sequence_length, head_size)
            packed_qkv (bool): whether to combine MatMuls from Q, K, V paths
                               Note: This is for the scenario where an Attention node should be created but cannot be created
                               because past_key and past_value are separate inputs and not one concatenated input.

        Returns:
            Union[NodeProto, None]: the node created or None if failed.
        r   ú9input hidden size %d is not a multiple of num of heads %dNc                 ó   — h | ]	}|j         ’Œ
S rW   r½   )r”   r�   s     r   ú	<setcomp>zBFusionAttention.create_multihead_attention_node.<locals>.<setcomp>H  s   € ÐLÐLÐL¨4˜TœYÐLÐLÐLr   rd   r  rc   r0   úcom.microsoftr]   r  )r   r€   r   Úgraphrr   rA   r  rD   r�   rt   r   r`   rV   rà   r�   r
   rB   ÚdomainrC   rE   ÚintÚincrease_counter)r   rá   râ   rã   rÊ   rË   rÌ   r]   r\   r�   r  r„   r  r¤   r¥   rÇ   rÈ   r  Úgraph_input_namesÚmha_node_nameÚ
mha_inputsr  r	  r  rß   Úmha_outputsÚmha_nodes                              r   Úcreate_multihead_attention_nodez/FusionAttention.create_multihead_attention_node  s   € ð^ ˜1Š}ˆ}ˆ}ˆ}à˜Š?ˆ? ¨iÑ 7¸AÒ=Ð=Ý�LŠLÐTÐVaÐclÑmÔmÐmØ�4àLÐL°4´:×3CÒ3CÑ3EÔ3EÔ3KÐLÑLÔLÐØœ
×3Ò3°KÑ@Ô@ˆð ˆ
Øð 	Ø(,×(JÒ(JØØØØØØñ)ô )Ñ%ˆG�W˜gð ×Ò˜wœ~¨aÔ0°'´.ÀÔ2CÀWÄ^ÐTUÔEVÐWÑXÔXÐXÑXÝ˜¥)Ñ,Ô,ð 	µ¸HÅiÑ1PÔ1Pð 	ØÔ5ð `Ø×!Ò! 5¤<°¤?°H´OÀAÔ4FÈÌÐUVÌÐ"XÑYÔYÐYÐYà×!Ò! 8¤?°1Ô#5°x´ÀqÔ7IÈ8Ì?Ð[\ÔK]Ð"^Ñ_Ô_Ð_Ð_å�x¥Ñ%Ô%ð	å˜8¥SÑ)Ô)ð	ð Ð-Ð-Ð-ØÐ-Ð-Ð-àÔ5ð LØ×!Ò! 5¤<°¤?°H¸hÐ"GÑHÔHÐHÐHà×!Ò! 8¤?°1Ô#5°xÀÐ"JÑKÔKÐKÐKà�4ð Ô5ð 	"Ø×5Ò5°e¸UÀEÈ=ÑYÔYˆIØ×Ò˜iÑ(Ô(Ð(Ð(à×Ò˜bÑ!Ô!Ð!ð ð 	:�fð 	:Ø×ÒÐ/°¸ÀÐHÑIÔIÐIÐIØð 	: ð 	:Ø×ÒÐ/°Ð8Ñ9Ô9Ð9ð �hˆØð 	7˜ð 	7Ø×Ò 	¨9Ð5Ñ6Ô6Ð6åÔ#Ø ØØØð	
ñ 
ô 
ˆð *ˆŒØÔ×!Ò!¥&Ô"7¸ÀYÑ"OÔ"OÑPÔPÐPØð 	dØÔ×%Ò%¥fÔ&;Ð<LÍcÐR`ÑNaÔNaÑ&bÔ&bÑcÔcÐcà×ÒÐ2Ñ3Ô3Ð3Øˆr   r"   Úfirst_inputÚ
add_qk_strÚcausalÚscalec                 óæ  — |dk    sJ ‚|	dk    r'|	|z  dk    rt                                d|	|¦  «         dS d}|€|€|€d}| j                             |j        d         ¦  «        }| j                             |j        d         ¦  «        }| j                             |j        d         ¦  «        }d\  }}}|rè| j                             |j        d         ¦  «        p$| j                             |j        d         ¦  «        }| j                             |j        d         ¦  «        p$| j                             |j        d         ¦  «        }| j                             |j        d         ¦  «        p$| j                             |j        d         ¦  «        }|r|r|r|sdS |€t          |j        d         › d�¦  «         dS t          j        |¦  «        }t          j        |¦  «        }t          j        |¦  «        }|j        |j        k    sJ ‚|j        d         }|j        d         }|j        d         }||cxk    r|k    sn J ‚|	dk    r"|	|k    rt            	                    d	|	|¦  «         d} |j        |j        k    rd} t          j        |j        dd…         ¦  «        }!t          j        |j        dd…         ¦  «        }"t          j        |j        dd…         ¦  «        }#d}$| r"t          j        |||fd¬
¦  «        }%|!|"z   |#z   }$nt          j        |||fd¬
¦  «        }%d|!z  }$d}&d}'|rât          j        |¦  «        }(t          j        |¦  «        })t          j        |¦  «        }*t          j        |(j        ¦  «        }+t          j        |)j        ¦  «        },t          j        |*j        ¦  «        }-|+|,cxk    r|!k    sn J ‚|-|#k    sJ ‚| r"t          j        |(|)|*fd¬
¦  «        }'|+|,z   |-z   }&nt          j        |(|)|*fd¬
¦  «        }'d|+z  }&| j                             d¦  «        }.| j        s0|                      |.dz   |j        |t%          |$¦  «        g|%¬¦  «         |r/|                      |.dz   |j        t%          |&¦  «        g|'¬¦  «         | j        r�|rt                                d¦  «         dS |j        d         |j        d         |j        d         |.dz   g}/|�|/                     |¦  «         t+          j        d|/|g|.¬¦  «        }0|                      d¦  «         �n9|
|.dz   |r|.dz   ndg}/|�|/                     |¦  «         n|/                     d¦  «         |o|}1|1r+|                      ||¦  «        }2|/                     |2¦  «         |r,|1s|/                     d¦  «         |/                     |¦  «         |g}3|rl|rj|                     dd¦  «                             dd¦  «                             dd¦  «        }4|3                     |4¦  «         |                      |||4¦  «         t+          j        d|/|3|.¬¦  «        }0|                      d¦  «         d|0_        |0j                             t+          j        d|¦  «        g¦  «         |r.|0j                             t+          j        dd¦  «        g¦  «         |�.|0j                             t+          j        d|¦  «        g¦  «         | r1|0j                             t+          j        d|!|"|#g¦  «        g¦  «         | j        �@|0j                             t+          j        dtA          | j        ¦  «        ¦  «        g¦  «         |0S )a>  Create an Attention node.

        Args:
            mask_index (str | None): mask input
            q_matmul (NodeProto): MatMul node in fully connection for Q
            k_matmul (NodeProto): MatMul node in fully connection for K
            v_matmul (NodeProto): MatMul node in fully connection for V
            q_add (NodeProto): Add bias node in fully connection for Q
            k_add (NodeProto): Add bias node in fully connection for K
            v_add (NodeProto): Add bias node in fully connection for V
            num_heads (int): number of attention heads. If a model is pruned, it is the number of heads after pruning.
            hidden_size (int): hidden dimension. If a model is pruned, it is the hidden dimension after pruning.
            first_input (str): first input name
            output (str): output name
            add_qk_str (str): name of Add node after Q x K'
            causal: whether it is uni-directional mask.
            past_k (str): name of input for past K value
            past_v (str): name of input for past V value
            present_k (str): name of output to store present K value
            present_v (str): name of output to store present V value
            scale: scale before softmax

        Returns:
            Union[NodeProto, None]: the node created or None if failed.
        r   r  NTFr5   )NNNzl is not an initializer. Please set do_constant_folding=True in torch.onnx.export to unblock attention fusionz„Input hidden size (%d) is not same as weight matrix dimension of q,k,v (%d). Please provide a correct input hidden size or pass in 0rÏ   rq   rd   ræ   rÑ   rÐ   zVMultiHeadAttention does not support relative_position_bias: cannot fuse the attention.rc   r0   r  z.keyÚ_keyr©   r•   r  r]   r  r'  Úqkv_hidden_sizesrf   )!r   r€   r   rF   rr   Úprintr   rÒ   rÖ   r�   ru   rÕ   ÚconcatenaterÔ   rA   r_   rG   r9   r  r�   r�   r
   rB   r  r´   r¬   rÉ   r  rC   rD   rE   rf   Úfloat)5r   r"   rá   râ   rã   rÊ   rË   rÌ   r]   r\   r$  r�   r%  r&  r¤   r¥   rÇ   rÈ   r'  Úhas_biasrõ   rö   r÷   r×   rÛ   rÜ   rø   rù   rú   Ú
qw_in_sizeÚ
kw_in_sizeÚ
vw_in_sizeÚis_qkv_diff_dimsÚqw_out_sizeÚkw_out_sizeÚvw_out_sizeÚqkv_weight_dimrü   rÞ   rÝ   rØ   rÙ   rÚ   Úq_bias_shapeÚk_bias_shapeÚv_bias_shapeÚattention_node_nameÚattention_inputsÚattention_nodeÚpast_existsÚpast_kvÚattention_outputsÚ
present_kvs5                                                        r   Úcreate_attention_nodez%FusionAttention.create_attention_nodeŒ  sJ  € ð\ ˜1Š}ˆ}ˆ}ˆ}à˜Š?ˆ? ¨iÑ 7¸AÒ=Ð=Ý�LŠLÐTÐVaÐclÑmÔmÐmØ�4àˆØˆ=˜U˜]¨u¨}ØˆHà”:×-Ò-¨h¬n¸QÔ.?Ñ@Ô@ˆØ”:×-Ò-¨h¬n¸QÔ.?Ñ@Ô@ˆØ”:×-Ò-¨h¬n¸QÔ.?Ñ@Ô@ˆà!1Ñˆ�˜Øð 	Ø”Z×/Ò/°´¸A´Ñ?Ô?ÐmÀ4Ä:×C]ÒC]Ð^cÔ^iÐjkÔ^lÑCmÔCmˆFØ”Z×/Ò/°´¸A´Ñ?Ô?ÐmÀ4Ä:×C]ÒC]Ð^cÔ^iÐjkÔ^lÑCmÔCmˆFØ”Z×/Ò/°´¸A´Ñ?Ô?ÐmÀ4Ä:×C]ÒC]Ð^cÔ^iÐjkÔ^lÑCmÔCmˆFàð  ð ¨fð ¸ð Ø�tàÐÝØ”> !Ô$ð gð gð gñô ð ð �4åÔ! (Ñ+Ô+ˆÝÔ! (Ñ+Ô+ˆÝÔ! (Ñ+Ô+ˆð Œx˜2œ8Ò#Ð#Ð#Ð#à”X˜a”[ˆ
Ø”X˜a”[ˆ
Ø”X˜a”[ˆ
à˜ZÐ5Ð5Ò5Ð5¨:Ò5Ð5Ð5Ð5Ð5Ð5à˜Š?ˆ?˜{¨jÒ8Ð8Ý�NŠNðJàØñ	ô ð ð !ÐØŒ8�r”xÒÐØ#Ðõ
 ”g˜bœh q r rœlÑ+Ô+ˆÝ”g˜bœh q r rœlÑ+Ô+ˆÝ”g˜bœh q r rœlÑ+Ô+ˆàˆØð 	-Ýœ¨¨R°¨¸1Ð=Ñ=Ô=ˆJØ(¨;Ñ6¸ÑDˆNˆNåœ 2 r¨2 ,°QÐ7Ñ7Ô7ˆJØ ™_ˆNàˆØ&*ˆØð 	0ÝÔ% fÑ-Ô-ˆBÝÔ% fÑ-Ô-ˆBÝÔ% fÑ-Ô-ˆBåœ7 2¤8Ñ,Ô,ˆLÝœ7 2¤8Ñ,Ô,ˆLÝœ7 2¤8Ñ,Ô,ˆLà <Ð>Ð>Ò>Ð>°;Ò>Ð>Ð>Ð>Ð>Ð>Ø ;Ò.Ð.Ð.Ð.àð 0Ýœ>¨2¨r°2¨,¸QÐ?Ñ?Ô?�Ø+¨lÑ:¸\ÑI��åœ8 R¨¨R L°qÐ9Ñ9Ô9�Ø  <Ñ/�à"œj×9Ò9¸+ÑFÔFÐàÔ,ð 	Ø× Ò Ø(¨=Ñ8Ø"Ô,Ø ¥# nÑ"5Ô"5Ð6Øð	 !ñ ô ð ð ð 	Ø× Ò Ø(¨;Ñ6Ø Ô*Ý˜,Ñ'Ô'Ð(Øð	 !ñ ô ð ð Ô(ð 9	/Øð Ý—’ÐuÑvÔvÐvØ�tð ” Ô"Ø” Ô"Ø” Ô"Ø# kÑ1ð	 Ðð Ð%Ø ×'Ò'¨
Ñ3Ô3Ð3å#Ô-Ø$Ø'Ø˜Ø(ð	ñ ô ˆNð ×!Ò!Ð"6Ñ7Ô7Ð7Ñ7ð Ø# mÑ3Ø5=ÐEÐ# kÑ1Ð1À2ð Ðð
 Ð%Ø ×'Ò'¨
Ñ3Ô3Ð3Ð3à ×'Ò'¨Ñ+Ô+Ð+à Ð+ VˆKØð 1ØŸ.š.¨°Ñ8Ô8�Ø ×'Ò'¨Ñ0Ô0Ð0àð 4à"ð 0Ø$×+Ò+¨BÑ/Ô/Ð/Ø ×'Ò'¨
Ñ3Ô3Ð3à!' ÐØð @˜Yð @Ø&×.Ò.¨v°rÑ:Ô:×BÒBÀ6È2ÑNÔN×VÒVÐWZÐ\_Ñ`Ô`�
Ø!×(Ò(¨Ñ4Ô4Ð4Ø—’˜i¨°JÑ?Ô?Ð?å#Ô-ØØ'Ø)Ø(ð	ñ ô ˆNð ×!Ò! +Ñ.Ô.Ð.à /ˆÔØÔ ×'Ò'­Ô)>¸{ÈIÑ)VÔ)VÐ(WÑXÔXÐXàð 	ZØÔ$×+Ò+­VÔ-BÐCSÐUVÑ-WÔ-WÐ,XÑYÔYÐYàÐØÔ$×+Ò+­VÔ-BÀ7ÈEÑ-RÔ-RÐ,SÑTÔTÐTàð 	ØÔ$×+Ò+ÝÔ&Ð'9¸KÈÐVaÐ;bÑcÔcÐdñô ð ð Ô!Ð-ØÔ$×+Ò+­VÔ-BÐCVÕX]Ð^bÔ^tÑXuÔXuÑ-vÔ-vÐ,wÑxÔxÐxàÐr   c                 óæ  — |}|}|j         dk    rK| j                             |dd¦  «        }|�|}n*| j                             |j        d         ¦  «        �|}nd S | j                             |g d¢g d¢¦  «        }d }|�	|\  }	}	}
}}n,| j                             |g d¢g d¢¦  «        }|�|\  }	}}}nd S g }t          |j        ¦  «        D ]Q\  }}||vr| j                             |¦  «        €Œ$||d         j        d         k    rŒ<|                     |¦  «         ŒRt          |¦  «        dk    rd S |d         }| j                             |d	d¦  «        }|�p||j        d                  }|�6t          |¦  «        d
k    r#|d         }|j         dk    r|j        d         }nUd S |�!t          |¦  «        dk    r|j        d         }n0d S |j         dv r%||         }|D ]}|j         dk    r|j        d         }Œ||v r8||         }|j         dk    r%t          |j        ¦  «        dk    r|j        d         }||         }d„ |D ¦   «         }| 
                    d¦  «        dk    rd S | j                             |g d¢g d¢¦  «        }|€t                               d¦  «         d S |\  }	}	}}d}d}d}d}g d¢g d¢fg d¢g d¢fg d¢g d¢fg d¢g d¢fg d¢g d¢fg d¢g d ¢fd!œ}d } |                     ¦   «         D ]S\  }!}"| j                             ||"d         |"d         ¦  «        } | €Œ0|!d"k    rd#}n|!d$k    rd#}n|!d%k    rd#}n|!d&k    rd#} | €t                               d'¦  «         d S d }#d }$d }%d }&|r| \  }	}%}$}	n%|r| \  }	}#}%}$n|r| \  }	}	}$n|r	| \  }	}#}$}&}	n| \  }	}#}	}$|&p|$}&| j                             |&g d¢g d(¢¦  «        }'|'€>| j                             |&g d)¢g d*¢¦  «        }'|'€t                               d+¦  «         d S |'d,         }(|'d-         })|'d.         }*|$}+|rC| j                             |$d	d/gdd g¦  «        },|,€t                               d0¦  «         d S |,\  }+}	| j                             |+g d¢|rdndddd g¦  «        }-|-€>| j                             |$g d1¢g d2¢¦  «        }-|-€t                               d3¦  «         d S |-d-         }.|-d.         }/d }0d4}1|r6| j                             |%g d5¢g d¢fg d6¢g d¢fg d7¢g d8¢fg|¦  «        \  }	}0}	n¦|re| j                             |%g d9¢g d8¢fg d6¢g d¢fg|¦  «        \  }	}0}	|#�4|                      |#¦  «        }1|1€t                               d:|#¦  «         d S n?|rn<| j                             |#g d;¢g d<¢fg d=¢g d>¢fg d?¢g d@¢fg dA¢g dB¢fg|¦  «        \  }	}0}	|s|0€t                               dC¦  «         d S |s¨t          |0¦  «        dk    r•| j                             |0d         ¦  «        \  }	}2|2�=t#          |2t$          j        ¦  «        r#|2j        dk    r|2                     ¦   «         dk    rd S |2                     ¦   «         dDk    r|2                     ¦   «         | _        |j        d         |k    �r]|*j        d         |k    �rM|/j        d         |k    �r=|s+| j                             |0d.         j        d         ¦  «        nd }3|€|
n|}4|                      |(¦  «        \  }5}6|5dk    s|6dk    rt                               dE¦  «         d S |                      |3|*|/||)|.||5|6||4j        d         |1¬F¦  «        }7|7€d S | j                             |7¦  «         | j        | j        |7j        <   |�£|j        d         }8dG|8z   }9|                       dH|8z   tB          j"        dgdd|5tG          |6|5z  ¦  «        gd¬I¦  «        }:| j         $                    tK          j&        dJ|4j        d         |:j        g|9gdK|8z   ¦  «        | j        ¦  «         |9|j        d<   | j'         (                    |4||g¦  «         | j'         (                    | ¦  «         | j'         (                    | j)        s|'n	|'d d.…         ¦  «         | j'         (                    | j)        s|-n	|-d d.…         ¦  «         | j'         (                    | j)        s|n	|d d.…         ¦  «         d#| _*        d S d S d S d S )LNr[   ÚAddr   )rC  rå   ÚReshapeÚ	Transposerå   )NNr   r   r   )rC  ÚEinsumrE  rå   )r5   Nr   r   r5   ÚMulrp   é   )r[   rZ   rZ   ro   c                 ó   — g | ]	}|j         ‘Œ
S rW   )r~   )r”   Úchilds     r   r–   z(FusionAttention.fuse.<locals>.<listcomp>Ò  s   € Ð>Ð>Ð>¨E˜%œ-Ð>Ð>Ð>r   rå   rq   )rE  rD  rC  rå   )r5   r   r   Nz&fuse_attention: failed to match v pathF)ÚSoftmaxrC  ÚDivrå   )r   r   Nr   )rK  rC  rG  rå   )rK  ÚWhererå   rL  )r   r   rp   r   )rK  rC  rM  rå   )r   r   r   rp   )rK  rL  rå   )r   r   r   )rK  rC  rå   rG  ÚSqrt)r   r   Nr   r5   )Úpath1Úpath2Úpath3Úpath4Úpath5ÚsdparQ  TrR  rS  rT  z'fuse_attention: failed to match qk path)r   r   r   N)rL  rE  rD  rC  rå   )r   r   r   r   Nz&fuse_attention: failed to match q pathéýÿÿÿéþÿÿÿrí   rN  z/fuse_attention: failed to match mul sqrt q path)rE  rE  rD  rC  rå   )r5   r   r   r   Nz&fuse_attention: failed to match k pathr  )ÚExpandrD  ÚEqual)rX  r§   r§   )ÚCastrW  rD  rX  )r   r   r   r   )rY  rX  r§   r§   z6fuse_attention: failed to verify shape inference of %s)rG  ÚSubrY  r§   r§   )Nr   r5   r   r   )rG  rZ  r§   r§   )Nr   r5   r   )rM  rY  rZ  rW  r§   r§   )Nr   r   r5   r   r   )rM  rY  rZ  rY  rW  r§   r§   )Nr   r   r5   r   r   r   z)fuse_attention: failed to match mask pathiðØÿÿzmFailed to detect num_heads and hidden_size for Attention fusion. Please specify those parameters in argument.)r"   rá   râ   rã   rÊ   rË   rÌ   r]   r\   r$  r�   r%  Úedge_modified_Úshape_modified_tensorr8   rD  Úreshape_modified_)+r~   r   Úmatch_parentr>   rr   Úmatch_parent_pathÚ	enumerater�   r�   r&   Úcountr   r€   ÚitemsÚmatch_parent_pathsr‹   Úget_constant_inputrt   ru   rv   rw   Úitemrf   r^   rQ   rƒ   r�   rA  r›   rž   rŸ   r3   rG   r	   rI   r  rJ   r
   rB   Únodes_to_removerD   r_   Úprune_graph);r   r�   Úinput_name_to_nodesÚoutput_name_to_nodeÚnormalize_nodeÚ
start_nodeÚadd_before_layernormr   Úeinsum_noder•   Úreshape_qkvÚtranspose_qkvÚ
matmul_qkvÚother_inputsÚ_iÚ
node_inputÚ
root_inputÚmul_before_layernormÚmul_childrenÚlayernorm_nodeÚchildrenrJ  Úparent_nodeÚchildren_typesÚv_nodesÚadd_vÚmatmul_vÚ
is_distillÚis_distill_addÚis_no_mask_attentionÚis_sdpaÚqk_pathsÚqk_nodesÚkÚvr„   Ú	matmul_qkÚwhere_qkÚafter_qÚq_nodesrz   Úadd_qÚmatmul_qÚafter_kÚmul_k_nodesÚk_nodesÚadd_kÚmatmul_kÚ
mask_nodesr%  Úmul_valr"   Úattention_last_nodeÚq_num_headsÚq_hidden_sizeÚnew_nodeÚunique_indexÚnew_edgeÚshape_tensors;                                                              r   ÚfusezFusionAttention.fusev  s   € ð ˆØ#ˆ
ØÔ!Ð%9Ò9Ð9Ø#'¤:×#:Ò#:¸>È5ÐRSÑ#TÔ#TÐ Ø#Ð/Ø1�
�
Ø”×,Ò,¨^Ô-AÀ!Ô-DÑEÔEÐQð ,�
�
à�ð ”J×0Ò0ØØ?Ð?Ð?Ø!Ð!Ð!ñ
ô 
ˆ	ð
 ˆØÐ Ø=FÑ:ˆQ��; ¨z¨zð œ
×4Ò4ØÐDÐDÐDÀoÀoÀoñô ˆIð Ð$Ø>GÑ;��K °
°
à�àˆÝ'¨
Ô(8Ñ9Ô9ð 	,ð 	,‰NˆB�
ØÐ!4Ð4Ð4Ø”:×.Ò.¨zÑ:Ô:ÐBØà˜Y qœ\Ô0°Ô3Ò3Ð3ØØ×Ò 
Ñ+Ô+Ð+Ð+Ýˆ|ÑÔ Ò!Ð!ØˆFà! !”_ˆ
ð  $œz×6Ò6°zÀ5È!ÑLÔLÐØÐ+Ø.Ð/CÔ/JÈ1Ô/MÔNˆLØÐ'­C°Ñ,=Ô,=ÀÒ,BÐ,BØ!-¨a¤�Ø!Ô)Ð-AÒAÐAØ!/Ô!6°qÔ!9�J�Jà�FØÐ)­c°,Ñ.?Ô.?À1Ò.DÐ.DØ1Ô8¸Ô;�
�
à�ØÔ#Ð'WÐWÐWØ*¨:Ô6ˆHØ!ð 1ð 1�Ø”=Ð$8Ò8Ð8Ø!&¤¨a¤�Jøð Ð,Ð,Ð,Ø-¨jÔ9ˆKØÔ"Ð&>Ò>Ð>Å3À{ÔGYÑCZÔCZÐ^_ÒC_ÐC_Ø(Ô/°Ô2�
à& zÔ2ˆØ>Ð>°XÐ>Ñ>Ô>ˆØ×Ò Ñ)Ô)¨QÒ.Ð.ØˆFà”*×.Ò.¨zÐ;dÐ;dÐ;dÐfuÐfuÐfuÑvÔvˆØˆ?Ý�LŠLÐAÑBÔBÐBØˆFØ")ÑˆˆAˆu�hàˆ
ØˆØ$ÐØˆà9Ð9Ð9¸?¸?¸?ÐKØ9Ð9Ð9¸?¸?¸?ÐKØ;Ð;Ð;¸\¸\¸\ÐJØ;Ð;Ð;¸\¸\¸\ÐJØ2Ð2Ð2°I°I°IÐ>Ø@Ð@Ð@ÐBTÐBTÐBTÐUð
ð 
ˆð ˆØ—N’NÑ$Ô$ð 	ð 	‰DˆAˆqØ”z×3Ò3°JÀÀ!ÄÀaÈÄdÑKÔKˆHØÐØØ�GŠ|ˆ|Ø!�
�
Ø�g’�Ø!%��Ø�g’�Ø'+Ð$Ð$Ø�f’�Ø�ØàÐÝ�LŠLÐBÑCÔCÐCØˆFàˆØˆ	ØˆØˆØð 		1Ø*2Ñ'ˆQ�˜) Q QØð 	1Ø/7Ñ,ˆQ�˜ ) )Ø!ð 	1Ø (ÑˆQ��9�9Øð 	1Ø19Ñ.ˆQ�˜	 7¨A¨Aà(0Ñ%ˆQ�˜˜9àÐ&˜YˆØ”*×.Ò.¨wÐ8aÐ8aÐ8aÐcrÐcrÐcrÑsÔsˆØˆ?Ø”j×2Ò2ØØ@Ð@Ð@Ø"Ð"Ð"ñô ˆGð
 ˆÝ—’ÐEÑFÔFÐFØ�Ø˜B”Kˆ	Ø˜”ˆØ˜2”;ˆàˆØð 	'Øœ*×6Ò6°yÀ5È&À/ÐTUÐW[ÐS\Ñ]Ô]ˆKØÐ"Ý—’ÐNÑOÔOÐOØ�Ø&‰LˆW�aà”*×.Ò.ØÐ>Ð>Ð>ÀgÐATÀÀÐSTÐVWÐYZÐ\`Ð@añ
ô 
ˆð ˆ?Ø”j×2Ò2ØØFÐFÐFØ"Ð"Ð"ñô ˆGð
 ˆÝ—’ÐEÑFÔFÐFØ�Ø˜”ˆØ˜2”;ˆð ˆ
Øˆ
Øð %	Ø#œz×<Ò<Øà3Ð3Ð3°Y°Y°YÐ?Ø8Ð8Ð8¸)¸)¸)ÐDØ;Ð;Ð;¸\¸\¸\ÐJðð
 $ñ ô  ÑˆAˆz˜1˜1ð ð 	Ø#œz×<Ò<Øà@Ð@Ð@À,À,À,ÐOØ8Ð8Ð8¸)¸)¸)ÐDðð $ñ ô  ÑˆAˆz˜1ð Ð!Ø!×0Ò0°Ñ8Ô8�
ØÐ%Ý—L’LÐ!YÐ[aÑbÔbÐbØ�FøØ!ð 	Øà#œz×<Ò<ØàEÐEÐEÐGYÐGYÐGYÐZØ=Ð=Ð=¸¸¸ÐOàQÐQÐQÐShÐShÐShÐiØYÐYÐYÐ[sÐ[sÐ[sÐtðð $ñ
 ô 
 ÑˆAˆz˜1ð $ð 	¨
Ð(:Ý�LŠLÐDÑEÔEÐEØˆFà#ð 
	8­¨J©¬¸!Ò(;Ð(;Øœ×6Ò6°zÀ!´}ÑEÔE‰JˆAˆwð �Ý" 7­B¬JÑ7Ô7ð !Ø<C¼LÈAÒ<MÐ<MØ—L’L‘N”N aÒ'Ð'à�Ø�|Š|‰~Œ~ Ò'Ð'Ø)0¯ª©¬�Ô&àŒ>˜!Ô 
Ò*Ñ*¨x¬~¸aÔ/@ÀJÒ/NÑ/NÐS[ÔSaÐbcÔSdÐhrÒSrÑSrØZnÐx˜Ô,×9Ò9¸*ÀR¼.Ô:NÈqÔ:QÑRÔRÐRÐtxˆJà1<Ð1D + +È-Ðà)-×)KÒ)KÈIÑ)VÔ)VÑ&ˆK˜Ø˜aÒÐ =°AÒ#5Ð#5Ý—’ðCñô ð ð �ð ×1Ò1Ø%Ø!Ø!Ø!ØØØØ%Ø)Ø&Ø*Ô1°!Ô4Ø%ð 2ñ ô ˆHð ÐØ�àÔ×$Ò$ XÑ.Ô.Ð.Ø:>Ô:NˆDÔ(¨¬Ñ7àÐ&Ø*Ô0°Ô3�Ø+¨lÑ:�à#×3Ò3Ø0°<Ñ?Ý)Ô/Ø˜Ø˜Q ­S°ÀÑ1LÑ-MÔ-MÐNØð  4ñ  ô  �ð ”
×#Ò#ÝÔ$Ø!Ø,Ô3°AÔ6¸Ô8IÐJØ!˜
Ø+¨lÑ:ñ	ô ð Ô(ñô ð ð (0�Ô! !Ñ$àÔ ×'Ò'Ð)<¸mÈZÐ(XÑYÔYÐYØÔ ×'Ò'¨Ñ1Ô1Ð1ð Ô ×'Ò'°tÔ7TÐ(f¨¨ÐZaÐbeÐceÐbeÔZfÑgÔgÐgØÔ ×'Ò'°tÔ7TÐ(f¨¨ÐZaÐbeÐceÐbeÔZfÑgÔgÐgØÔ ×'Ò'°tÔ7TÐ(f¨¨ÐZaÐbeÐceÐbeÔZfÑgÔgÐgð  $ˆDÔÐÐðI +Ð*Ð/NÐ/NÐSrÐSrr   )r  r  Fr  r  r  r  F)r  Fr  r  r  r  N)rR   rS   rT   rU   r   r  r   Úboolr™   rV   r   r   Útuplery   rƒ   r‹   r£   r´   rÉ   rà   r  r#  r-  rA  rš  Ú__classcell__)rl   s   @r   rY   rY   g   sª  ø€ € € € € ðð ð 04Ø).Ø27Ø&>Ð@TÐ%Uð%ð %àð%ð ð%ð ð	%ð
 &¨Ñ,ð%ð #'ð%ð ,0ð%ð ˜cœð%ð %ð %ð %ð %ð %ð40À	ð 0ÈeÐTWÐY\ÐT\Ìoð 0ð 0ð 0ð 0ð>,&°yð ,&ÀUÈ3ÐPSÈ8Ä_ð ,&ð ,&ð ,&ð ,&ð\ Yð ð ð ð ð*  Sð  ð  ð  ð  ð25 ð 5¨Sð 5°Sð 5ð 5ð 5ð 5ðn+K sð +K¸Cð +KÈ#ð +Kð +Kð +Kð +KðZàðð ˜4Ñðð ˜4Ñð	ð
 ðð 
�TÑ	ðð ð ð ð<M,àðM,ð ðM,ð ð	M,ð
 ðM,ð ˜4ÑðM,ð ˜4ÑðM,ð 
ˆy˜) YÐ.Ô	/ðM,ð M,ð M,ð M,ðv !#ØØ$ØØØØØ ð%wð wàðwð ˜c‘/ DÑ(ðwð ˜c‘/ DÑ(ð	wð
 ðwð ˜4Ñðwð ˜4Ñðwð ðwð ðwð ðwð ðwð ðwð ðwð ðwð ðwð  ð!wð" ð#wð$ ð%wð& 
�TÑ	ð'wð wð wð wðL ØØØØØØ"ð'hð hà˜$‘Jðhð ðhð ð	hð
 ðhð ðhð ðhð ðhð ðhð ðhð ðhð ðhð ðhð ðhð ðhð  ð!hð" ð#hð$ ð%hð& �t‰|ð'hð( 
�TÑ	ð)hð hð hð hðTx$ð x$ð x$ð x$ð x$ð x$ð x$r   rY   )Úloggingr   Únumpyru   Úfusion_baser   Úfusion_optionsr   Úfusion_utilsr   r   Úonnxr   r	   r
   r   Ú
onnx_modelr   rR   r   r   rY   rW   r   r   ú<module>r¥     s  ðð
 Ð Ð Ð Ð Ð à Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø .Ð .Ð .Ð .Ð .Ð .Ø 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ø =Ð =Ð =Ð =Ð =Ð =Ð =Ð =Ð =Ð =Ð =Ð =Ø  Ð  Ð  Ð  Ð  Ð  à	ˆ�8Ñ	Ô	€ðSð Sð Sð Sð Sñ Sô Sð SðlG$ð G$ð G$ð G$ð G$�fñ G$ô G$ð G$ð G$ð G$r   