+
    G-jË2  ã                   ó†   € ^ RI Ht ^ RIt^ RIHtHt ^ RIHtHtHtH	t	 ^ RI
Ht ]! ]4      t ! R R4      t ! R R	4      tR# )
é    )Ú	getLoggerN)Úarray_equalÚndarray)Ú	NodeProtoÚTensorProtoÚhelperÚnumpy_helper©Ú	OnnxModelc                   ó\  a € ] tR t^t o V 3R lR ltV 3R lR ltR V 3R lR lltR!V 3R lR	 lltV 3R
 lR ltV 3R lR lt	]
R 4       t]
R"V 3R lR ll4       tV 3R lR lt]
R#V 3R lR ll4       t]
V 3R lR l4       t]
R$V 3R lR ll4       tV 3R lR ltR tR tR tR tRtV tR# )%ÚFusionUtilsc                ó    <€ V ^8„  d   QhRS[ /# ©é   Úmodelr
   )ÚformatÚ__classdict__s   "€Úv/Volumes/fast/ai/experiments/nudenet-smoke/.venv/lib/python3.14/site-packages/onnxruntime/transformers/fusion_utils.pyÚ__annotate__ÚFusionUtils.__annotate__   s   ø€ ÷ &ñ &™iñ &ó    c                ó   € Wn         R # ©N©r   )Úselfr   s   &&r   Ú__init__ÚFusionUtils.__init__   s   € Ø %Ž
r   c                ó<   <€ V ^8„  d   QhRS[ RS[S[S[ 3,          /# )r   Ú
input_nameÚreturn)ÚstrÚtupleÚbool)r   r   s   "€r   r   r      s$   ø€ ÷ !ñ !±Cð !¹EÁ$ÉÀ)Õ<Lñ !r   c                óH  € V P                   P                  V4      pVed   VP                  P                  P                  \
        P                  8w  d1   V P                  V4      w  r4\        P                  RV R24       RV3# \        P                  RV RVR J 24       RV3# )NzCasted graph input z	 to int32TzDid not cast graph input z to int32: found F)
r   Úfind_graph_inputÚtypeÚtensor_typeÚ	elem_typer   ÚINT32Úcast_input_to_int32ÚloggerÚdebug)r   r   Úgraph_inputÚcast_outputÚ	cast_nodes   &&   r   Úcast_graph_input_to_int32Ú%FusionUtils.cast_graph_input_to_int32   s�   € Ø—j‘j×1Ñ1°*Ó=ˆØÒ" {×'7Ñ'7×'CÑ'C×'MÑ'MÔQ\×QbÑQbÔ'bØ%)×%=Ñ%=¸jÓ%IÑ"ˆKÜ�L‰LÐ.¨z¨l¸)ÐDÔEØ˜Ð$Ð$ä�‰Ð0°°Ð<MÈkÐaeÐNeÐMfÐgÔhØ�jÐ Ð r   c                ó    <€ V ^8„  d   QhRS[ /# ©r   r   ©r!   )r   r   s   "€r   r   r      s   ø€ ÷ &ñ &¡Sñ &r   c                ó(  € VR ,           V,           pVR8X  d   \        \        P                  4      pMMVR8X  d   \        \        P                  4      pM,VR8X  d   \        \        P                  4      pM\        R4      hV P                  WV4      pW53# )Ú_Úint32Úfloat32Úfloat16z"Invalid target_type: {target_type})Úintr   r)   ÚFLOATÚFLOAT16Ú
ValueErrorÚadd_cast_node)r   r   Útarget_typeÚoutput_nameÚto_typer/   s   &&&   r   Ú
cast_inputÚFusionUtils.cast_input   s€   € Ø  3Õ&¨Õ4ˆà˜'Ô!Üœ+×+Ñ+Ó,‰GØ˜IÔ%Üœ+×+Ñ+Ó,‰GØ˜IÔ%Üœ+×-Ñ-Ó.‰GäÐAÓBÐBà×&Ñ& z¸KÓHˆ	àÐ%Ð%r   Nc          	      óN   <€ V ^8„  d   QhRS[ RS[RS[ R,          RS[ R,          /# )r   r   rA   r@   NÚ
graph_name)r!   r:   )r   r   s   "€r   r   r   -   s;   ø€ ÷ ñ áðñ ðñ ˜4•Zð	ñ ˜$•Jñr   c                óª  € Vf   VRV 2,           pV.pVf   V P                   P                  4       pW9   d6   WA,          pV'       d&   VP                  R8X  d   VP                  ^ ,          .p\        P
                  ! RWc.R7      pVP                  P                  \        P                  ! RV4      .4       V P                   P                  W…R7       V# )NÚ	_cast_to_ÚCast)ÚinputsÚoutputsÚto)rE   )
r   Úoutput_name_to_nodeÚop_typeÚinputr   Ú	make_nodeÚ	attributeÚextendÚmake_attributeÚadd_node)	r   r   rA   r@   rL   rE   rI   Úparent_noder/   s	   &&&&&&   r   r>   ÚFusionUtils.add_cast_node-   sÁ   € ð ÒØ$¨°7°)Ð'<Õ<ˆKð �ˆØÒ&Ø"&§*¡*×"@Ñ"@Ó"BÐØÔ,Ø-Õ9ˆKß˜{×2Ñ2°fÔ<Ø%×+Ñ+¨AÕ.Ð/�ä×$Ò$ V°FÀMÔRˆ	à×Ñ×"Ñ"¤F×$9Ò$9¸$ÀÓ$HÐ#IÔJØ�
‰
×Ñ˜IÐÔ=àÐr   c                ó    <€ V ^8„  d   QhRS[ /# r3   r4   )r   r   s   "€r   r   r   H   s   ø€ ÷ 4ñ 4©cñ 4r   c                ó&   € V P                  VR 4      # ©r7   )rB   )r   r   s   &&r   r*   ÚFusionUtils.cast_input_to_int32H   s   € Ø�‰˜z¨7Ó3Ð3r   c                ó    <€ V ^8„  d   QhRS[ /# r3   r4   )r   r   s   "€r   r   r   K   s   ø€ ÷ Sñ S©Cñ Sr   c                óÐ  € V P                   P                  4       pW!,          pV F½  pVP                  R 8X  g   K  RpVP                   FB  pVP                  R8X  g   K  VP
                  \        \        P                  4      8X  g   K@  Rp M	  V'       g   Kt  VP                  ^ ,          pV P                   P                  V4       V P                   P                  Wq4       K¿  	  R# )rH   FrK   TN)r   Úinput_name_to_nodesrM   rP   ÚnameÚir:   r   r)   ÚoutputÚremove_nodeÚreplace_input_of_all_nodes)r   r   r\   ÚnodesÚnodeÚis_int32Úattr@   s   &&      r   Úremove_cast_int32ÚFusionUtils.remove_cast_int32K   s¨   € Ø"Ÿj™j×<Ñ<Ó>ÐØ#Õ/ˆÛˆDØ�|‰|˜vÖ%Ø �ØŸ>œ>�CØ—x‘x 4Ö'¨C¯E©E´S¼×9JÑ9JÓ5KÖ,KØ#'˜Ùñ *÷ ‘8Ø"&§+¡+¨a¥.�KØ—J‘J×*Ñ*¨4Ô0Ø—J‘J×9Ñ9¸+ÖRó r   c                ón  € ^ pV P                   V,          V9   di   WV P                   V,          ,          9   dK   W0P                   V,          ,          P                  V 4       \        W0P                   V,          ,          4      pW P                   V&   W#9   d   W2,          P                  V 4       V# V .W2&   V# )r   )rN   ÚremoveÚlenÚappend)rc   r^   Únew_input_namer\   Úold_input_references   &&&& r   Úupdate_node_inputÚFusionUtils.update_node_inputZ   s�   € àÐØ�J‰J�q�MÐ0Ô0°dÐRV×R\ÑR\Ð]^ÕR_Õ>`Ô6`Ø§
¡
¨1¥Õ.×5Ñ5°dÔ;Ü"%Ð&9¿*¹*ÀQ½-Õ&HÓ"IÐà&�
‰
�1‰àÔ0ØÕ/×6Ñ6°tÔ<ð #Ð"ð 48°&ÐÑ/à"Ð"r   c                ó    <€ V ^8„  d   QhRS[ /# r   r
   )r   r   s   "€r   r   r   k   s   ø€ ÷ %ñ %™9ñ %r   c                óÄ   € VP                   V,          pVP                   V,          p\        P                  WWs4      pV^ 8H  ;'       d    V P                  V4      '       * p	V	# )zÂ
Before:
      (input)-->parent-->node-->(output)
After:
      (input)-->parent-->
        |
        +----->node-->(output)

This function returns a flag whether the parent node can be removed.
)rN   r   rn   Úfind_graph_output)
r   rc   rT   r\   Únode_input_indexÚparent_input_indexÚold_input_namerl   rm   Úparent_can_be_removeds
   &&&&&&    r   Úskip_parentÚFusionUtils.skip_parentj   sb   € ð Ÿ™Ð$4Õ5ˆØ$×*Ñ*Ð+=Õ>ˆÜ)×;Ñ;¸DÐTbÓxÐð "5¸Ñ!9× jÐ jÀ5×CZÑCZÐ[iÓCjÔ?jÐà$Ð$r   c                ó4   <€ V ^8„  d   QhRS[ RS[R,          /# )r   rc   r    N)r   r   )r   r   s   "€r   r   r   €   s   ø€ ÷ ñ ±)ð ÁÈ$Åñ r   c                ó4  € VP                   R9   g   Q h\        VP                  4      ^8”  d-   V P                  P	                  VP                  ^,          4      # RpVP
                   F,  pVP                  R8X  g   K  \        P                  ! V4      pK.  	  V# )ÚSqueezeNÚaxes)r{   Ú	Unsqueeze)	rM   rj   rN   r   Úget_constant_valuerP   r]   r   Úget_attribute_value)r   rc   r|   Úattrs   &&  r   Úget_squeeze_or_unsqueeze_axesÚ)FusionUtils.get_squeeze_or_unsqueeze_axes€   sz   € Ø�|‰|Ð7Ô7Ð7Ð7ô ˆt�z‰z‹?˜QÔØ—:‘:×0Ñ0°·±¸AµÓ?Ð?àˆØ—N”NˆDØ�y‰y˜FÖ"Ü×1Ò1°$Ó7’ñ #ð ˆr   c                ó    <€ V ^8„  d   QhRS[ /# )r   Úattribute_namer4   )r   r   s   "€r   r   r   Ž   s   ø€ ÷ +ñ +±3ñ +r   c                ó  € TpV P                    F,  pVP                  V8X  g   K  \        P                  ! V4      pK.  	  \	        V\
        4      '       d,   \	        V\        \
        34      ;'       d    \        W$RR7      # WB8H  # )af  Verify that a node has expected value for an attribute.

Args:
    node (NodeProto): a node to check
    attribute_name (str): name of attribute
    expected_value (Any): expected value of the attribute
    default_value (Any, optional): default value if the attribute does not exist. Defaults to None.

Returns:
    bool: whether the check is passed or not
F©Ú	equal_nan)rP   r]   r   r   Ú
isinstanceÚlistr   r   )rc   r„   Úexpected_valueÚdefault_valueÚvaluer€   s   &&&&  r   Úcheck_node_attributeÚ FusionUtils.check_node_attribute�   sl   € ð ˆØ—N”NˆDØ�y‰y˜NÖ*Ü×2Ò2°4Ó8’ñ #ô �n¤d×+Ò+Ü˜u¤w´ oÓ6×oÐo¼KÈÐinÔ<oÐoàÑ*Ð*r   c                ó    <€ V ^8„  d   QhRS[ /# )r   Útensor)r   )r   r   s   "€r   r   r   ¥   s   ø€ ÷ ñ ©ñ r   c                ó   € \        V \        4      '       g   \        R\        V 4       24      h\	        V P
                  4      ^8w  g    V P                  \        P                  8w  d   \        R4      hV P                  '       dr   \        P                  ! \        P                  ! V P                  RR7      V P
                  4      p\        P                  ! V^^ .4      pVP                  4       V n	        V # \        R4      h)zŽTranspose a 2-D INT8 TensorProto
Args:
    tensor (TensorProto): tensor to be transposed
Returns:
    tensor (TensorProto): transposed tensor
z3Expected input type is an ONNX TensorProto but got z'Only INT8 2-D tensors can be transposedÚint8)Údtypezonly raw buffer supported)rˆ   r   Ú	TypeErrorr&   rj   ÚdimsÚ	data_typeÚINT8r=   Úraw_dataÚnumpyÚreshapeÚ
frombufferÚ	transposeÚtobytes)r�   Ú
int32_dataÚint32_transposed_datas   &  r   Útranspose_2d_int8_tensorÚ$FusionUtils.transpose_2d_int8_tensor¤   sÇ   € ô ˜&¤+×.Ò.ÜÐQÔRVÐW]ÓR^ÐQ_Ð`ÓaÐaäˆv�{‰{Ó˜qÔ  F×$4Ñ$4¼×8HÑ8HÔ$HÜÐFÓGÐGà�?�?ˆ?ÜŸš¤u×'7Ò'7¸¿¹ÈvÔ'VÐX^×XcÑXcÓdˆJÜ$)§O¢O°JÀÀAÀÓ$GÐ!Ø3×;Ñ;Ó=ˆFŒOð
 ˆô Ð8Ó9Ð9r   c                ó&   <€ V ^8„  d   QhRS[ RS[/# )r   rc   r   )r   r   )r   r   s   "€r   r   r   ½   s   ø€ ÷ (*ñ (*©	ð (*¹)ñ (*r   c                óX  € V P                   R9  d#   \        P                  RV P                    24       VP                  V P                  ^,          4      pVf   R# VP
                  ^ 8H  ;'       g.    VP
                  ^8H  ;'       d    VP                  ^ ,          ^8H  pV'       d   V'       g   R# \        V P                  4      ^8X  d   R# VP                  V P                  ^,          4      pVP
                  VP
                  8w  d   R# Vf   R# \        P                  ! V^ 8H  4      # )a¼  Verify if a provided QuantizeLinear (Q) / DequantizeLinear (DQ) node is a good candidate for fusion.
   It is a good candidate for fusion if:
   (1) The Q/DQ node is for per-tensor quantization if allow_per_tensor_quantization_only is `True`
   (2) The Q/DQ node should have constant scale
   (3) The Q/DQ node should have a zero point of 0
Args:
    node (NodeProto): a Q/DQ node to check
Returns:
    bool: whether the check is passed or not
z+Provided node is not a Q/DQ node. Op Type: FT>   ÚQuantizeLinearÚDequantizeLinear)
rM   r+   r,   r~   rN   ÚndimÚshaperj   r™   Úall)rc   r   Ú"allow_per_tensor_quantization_onlyÚscaleÚscale_has_single_elementÚ
zero_points   &&&   r   Úcheck_qdq_node_for_fusionÚ%FusionUtils.check_qdq_node_for_fusion¼   sí   € ð �<‰<ÐEÔEÜ�L‰LÐFÀtÇ|Á|ÀnÐUÔVà×(Ñ(¨¯©°A­Ó7ˆð Š=Ùð $)§:¡:°¡?×#_Ð#_°u·z±zÀQ±×7^Ð7^È5Ï;É;ÐWXÍ>Ð]^ÑK^Ð ß-×6NÙô ˆt�z‰z‹?˜aÔÙð ×-Ñ-¨d¯j©j¸­mÓ<ˆ
ð �:‰:˜Ÿ™Ô(Ùð ÒÙä�yŠy˜ q™Ó)Ð)r   c                ó    <€ V ^8„  d   QhRS[ /# )r   Úinput_index)r:   )r   r   s   "€r   r   r   ç   s   ø€ ÷ +ñ +¹ñ +r   c                ó  € \        VP                  4      V8”  g   Q hV P                  P                  VP                  V,          4      p\	        V\
        4      '       d,   \	        V\        \
        34      ;'       d    \        W4RR7      # WC8H  # )zÿVerify that a node has expected input value

Args:
    node (NodeProto): a node to check
    input_index (int): index of its input to be verified
    expected_value (Any): expected value of the input

Returns:
    bool: whether the check is passed or not
Fr†   )rj   rN   r   r~   rˆ   r‰   r   r   )r   rc   r°   rŠ   rŒ   s   &&&& r   Úcheck_node_input_valueÚ"FusionUtils.check_node_input_valueç   sn   € ô �4—:‘:‹ Ô,Ð,Ð,à—
‘
×-Ñ-¨d¯j©j¸Õ.EÓFˆä�n¤d×+Ò+Ü˜u¤w´ oÓ6×oÐo¼KÈÐinÔ<oÐoàÑ*Ð*r   c                ó  € . pV P                   P                  4       pV P                   P                  4        F  pVP                  R8X  g   K  VP                  ^ ,          V9  g   K0  V P                   P                  VP                  ^ ,          VP                  ^ ,          4       VP                  V4       K�  	  V'       d@   V P                   P                  V4       \        P                  R\        V4       R24       R# R# )z>Remove Identity nodes, except those right before graph output.ÚIdentityzRemoved z Identity nodesN)r   Úget_graphs_output_namesrb   rM   r_   ra   rN   rk   Úremove_nodesr+   Úinforj   )r   Únodes_to_removeÚgraph_output_namesrc   s   &   r   Úremove_identity_nodesÚ!FusionUtils.remove_identity_nodesû   s¸   € àˆØ!ŸZ™Z×?Ñ?ÓAÐØ—J‘J×$Ñ$Ö&ˆDØ�|‰|˜zÖ)Ø—;‘;˜q•>Ð);Ö;Ø—J‘J×9Ñ9¸$¿+¹+Àa½.È$Ï*É*ÐUVÍ-ÔXØ#×*Ñ*¨4Ö0ñ	 '÷ Ø�J‰J×#Ñ# OÔ4Ü�K‰K˜(¤3 Ó#7Ð"8¸ÐHÖIñ r   c                ó:   € V P                   P                  4        R # r   )r   Úremove_cascaded_cast_nodes©r   s   &r   r¾   Ú&FusionUtils.remove_cascaded_cast_nodes	  s   € Ø�
‰
×-Ñ-Ö/r   c                ó:   € V P                   P                  4        R # r   )r   Úremove_useless_cast_nodesr¿   s   &r   rÂ   Ú%FusionUtils.remove_useless_cast_nodes  s   € Ø�
‰
×,Ñ,Ö.r   c                óú  € V P                   P                  RR7      pVf   R# . pV P                   P                  4        F¬  pVP                  R8X  g   K  VP	                  VP
                  ^ ,          4      pVP	                  VP                  ^ ,          4      pV'       g   Kd  V'       g   Kn  WE8X  g   Kv  \        P                  RVP                   RV 24       VP                  V4       K®  	  V'       Ed„   \        V P                   P                  4       4      p\        V P                   P                  4       4      pV EF4  p\        \        VP                  4      V,          4      '       d­   \        \        VP
                  4      V,          4      '       g€   \        V P                   P!                  4       VP
                  ^ ,          ,          4      ^8X  d@   V P                   P#                  VP
                  ^ ,          VP                  ^ ,          4       M@KÛ  V P                   P%                  VP                  ^ ,          VP
                  ^ ,          4       V P                   P'                  V4       EK7  	  R# R# )ziRemove reshape node that is not needed based on symbolic shape inference: input and output has same shapeT)ÚupdateNÚReshapezRemove reshape node z* since its input shape is same as output: )r   Úinfer_runtime_shaperb   rM   Úget_edge_shaperN   r_   r+   r¸   r]   rk   ÚsetÚget_graphs_input_namesr¶   r#   rj   r\   Úreplace_output_of_all_nodesra   r`   )r   Úshape_inferr¹   rc   Úinput_shapeÚoutput_shapeÚgraph_input_namesrº   s   &       r   Úremove_useless_reshape_nodesÚ(FusionUtils.remove_useless_reshape_nodes  s»  € à—j‘j×4Ñ4¸DÐ4ÓAˆØÒÙàˆØ—J‘J×$Ñ$Ö&ˆDØ�|‰|˜yÖ(Ø)×8Ñ8¸¿¹ÀA½ÓG�Ø*×9Ñ9¸$¿+¹+Àa½.ÓI�ß‘;§<¡<°KÖ4OÜ—K‘KØ.¨t¯y©y¨kÐ9cÐdoÐcpÐqôð $×*Ñ*¨4Ö0ñ '÷ ˆ?Ü # D§J¡J×$EÑ$EÓ$GÓ HÐÜ!$ T§Z¡Z×%GÑ%GÓ%IÓ!JÐÜ'�Üœ˜DŸK™KÓ(Ð+=Õ=×>Ò>ä ¤ T§Z¡Z£Ð3DÕ!D×EÒEÜ §
¡
× >Ñ >Ó @ÀÇÁÈAÅÕ OÓPÐTUÔUàŸ
™
×>Ñ>¸t¿z¹zÈ!½}ÈdÏkÉkÐZ[ÍnÕ]á à—J‘J×9Ñ9¸$¿+¹+Àa½.È$Ï*É*ÐUVÍ-ÔXØ—
‘
×&Ñ& t×,ó (ñ r   r   rX   )NNN)r   r   r   )T)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__r   r0   rB   r>   r*   rf   Ústaticmethodrn   rw   r�   r�   r    r­   r²   r»   r¾   rÂ   rÐ   Ú__static_attributes__Ú__classdictcell__©r   s   @r   r   r      så   ø‡ € ÷&ð &÷!ð !÷&ò &÷ ò ÷64ð 4÷Sð Sð ñ#ó ð#ð ÷%ñ %ó ð%÷*ð ð ÷+ñ +ó ð+ð, ÷ó ðð. ÷(*ñ (*ó ð(*÷T+ð +ò(Jò0ò/÷-ð -r   r   c                   ó@   a € ] tR tRt o ]RV 3R lR ll4       tRtV tR# )ÚNumpyHelperi1  c                ó,   <€ V ^8„  d   QhRS[ RS[RS[/# )r   r�   Ú
fill_zerosr    )r   r#   r   )r   r   s   "€r   r   ÚNumpyHelper.__annotate__3  s"   ø€ ÷ -ñ -™ð -±$ð -Á7ñ -r   c                ó,  € V'       d6   \        V P                  \        P                  ! V P                  4      R 7      # V P                  \
        P                  8X  d$   ^ RIpVP                  V 4      P                  4       # \        P                  ! V 4      # ))r§   r“   N)r   r•   r   Útensor_dtype_to_np_dtyper–   r   ÚBFLOAT16Úonnx_irÚ
from_protor™   r	   Úto_array)r�   rÝ   Úirs   && r   rä   ÚNumpyHelper.to_array2  ss   € ÷ ÜØ—k‘kÜ×5Ò5°f×6FÑ6FÓGôð ð
 ×Ñœ{×3Ñ3Ô3Û ð —=‘= Ó(×.Ñ.Ó0Ð0Ü×$Ò$ VÓ,Ð,r   © N)F)rÒ   rÓ   rÔ   rÕ   rÖ   rä   r×   rØ   rÙ   s   @r   rÛ   rÛ   1  s   ø‡ € Ø÷-ñ -ó ö-r   rÛ   )Úloggingr   r™   r   r   Úonnxr   r   r   r	   Ú
onnx_modelr   rÒ   r+   r   rÛ   rç   r   r   Ú<module>rë      s:   ðõ
 ã ß &ß =Ó =Ý  á	�8Ó	€÷_-ñ _-÷D	-ó -r   