+
    9i2                         ^ 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   "c/var/www/html/photoedit/myenv/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    jj11*="{'7'7'C'C'M'MQ\QbQb'b%)%=%=j%I"KLL.zl)DE$$0<MkaeNeMf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&&zK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;        4Z	 $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                  WR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,-9K{22f<%++A./$$VFM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 4c 4r   c                &    V P                  VR 4      # r7   )rB   )r   r   s   &&r   r*   FusionUtils.cast_input_to_int32H   s    z7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    "jj<<>#/D||v% >>Cxx4'CEES9J9J5K,K#' * 8"&++a.KJJ**40JJ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    JJqM00dRVR\R\]^R_>`6`

1.55d;"%&9**Q-&H"I&

10/66t< #" 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$**+=>);;DTbx "5!9 j j5CZCZ[iCj?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 tzz?Q::00A??NNDyyF"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     NNDyyN*2248 # nd++uwo6ooK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)zTranspose 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     &+..QRVW]R^Q_`aav{{q F$4$48H8H$HFGG???u'7'7v'VX^XcXcdJ$)OOJA$G!3;;=FO
  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LLFt||nUV((A7 = $)::?#_#_uzzQ7^7^5;;WX>]^K^ -6N tzz?a --djjm<
 ::( yy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  # )zVerify 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::,,,

--djj.EFnd++uwo6ooK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    !ZZ??AJJ$$&D||z);;q>);;JJ99$++a.$**UV-X#**40	 ' JJ##O4KK(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   jj44D4AJJ$$&D||y()88AG*99$++a.I;<<K4OKK.tyyk9cdocpq $**40 ' ? #DJJ$E$E$G H!$TZZ%G%G%I!J'DKK(+==>> TZZ3D!DEE

 > > @A OPTUU

>>tzz!}dkkZ[n] JJ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     kk55f6F6F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   