+
    9i.                    F    ^ RI Ht ^ RIHt ^ RIt^RIHt  ! R R4      tR# )    )annotations)dequeN)	ONNXModelc                  ,   ] tR t^tRtR R ltR R ltR R ltR t]	R	 R
 l4       t
]	R R l4       t]	R R l4       t]	R R l4       tR R ltR%R R lltR%R R lltR R ltR. 3R R lltRR. R3R R lltR&R R lltR  R! ltR'R" R# lltR$tR# )(Fusionz
Base class for fusions.
c               $    V ^8  d   QhRRRRRR/# )   modelr   fused_op_typestrsearch_op_type )formats   "e/var/www/html/photoedit/myenv/lib/python3.14/site-packages/onnxruntime/quantization/fusions/fusion.py__annotate__Fusion.__annotate__   s!     * *i * *S *    c                	    W0n         W n        Wn        . V n        . V n        V P                  R ,           V P                   ,           R,           V n        RV n        R# )_fused__N)r   r   r
   nodes_to_removenodes_to_add_new_node_name_prefix_new_node_name_suffix)selfr
   r   r   s   &&&&r   __init__Fusion.__init__   sO    #1"/ %
%'"$%)%7%7)%CdFYFY%Y\_%_"%)"r   c               $    V ^8  d   QhRRRRRR/# )r	   nodeonnx.NodeProtoinput_name_to_nodesdict[str, list[onnx.NodeProto]]output_name_to_nodedict[str, onnx.NodeProto]r   )r   s   "r   r   r      s(     
" 
"
" =
" 7	
"r   c                    \         h)zm
Interface function for derived fusion classes. Tries to fuse a node sequence containing
the specified node.
)NotImplementedError)r   r   r!   r#   s   &&&&r   fuseFusion.fuse   s
     "!r   c                   V ^8  d   QhRR/# )r	   returnboolr   )r   s   "r   r   r   *   s      t r   c                8   V P                   P                  4       pV P                   P                  4       pV P                   P                  4        F2  pVP                  V P
                  8X  g   K   V P                  W1V4       K4  	  V P                   P                  V P                  4       V P                   P                  V P                  4       \        V P                  ;'       g    V P                  4      pV'       d   V P                   P                  4        V# )z/
Apply graph fusion on the entire model graph.
)r
   r!   r#   nodesop_typer   r'   remove_nodesr   	add_nodesr   r+   remove_unused_constant)r   r!   r#   r   graph_updateds   &    r   applyFusion.apply*   s     #jj<<>"jj<<>JJ$$&D||t222		$5HI ' 	

 4 45

T../T11FFT5F5FGJJ--/r   c                	    V P                   pV P                  f*   V P                  P                  V4      pV^,           V n        V V P                  : 2pV ;P                  ^,          un        V# N)r   r   r
   get_largest_node_name_suffix)r   prefixlargest_suffixnew_names   &   r   create_unique_node_nameFusion.create_unique_node_name?   se    ++%%-"&**"I"I&"QN)7!);D&Xd88;<""a'"r   c          
     ,    V ^8  d   QhRRRRRRRRR	R
/# )r	   r   list[onnx.NodeProto]keep_outputs	list[str]r!   r"   r#   r$   r*   r+   r   )r   s   "r   r   r   L   s:      - = 7	
 
r   c                	    V  F@  pVP                    F-  pWQ9   d   K  WR9   g   K  W%,           F  pW`9  g   K     R # 	  K/  	  KB  	  R# )FT)output)r   r?   r!   r#   node_to_removeoutput_to_removeimpacted_nodes   &&&&   r   is_safe_to_fuse_nodesFusion.is_safe_to_fuse_nodesK   sM     .N$2$9$9 #3#:)<)N)N(?#( *O %: . r   c                    V ^8  d   QhRRRR/# )r	   r   r    attribute_namer   r   )r   s   "r   r   r   _   s        r   c                	    V P                    F7  pVP                  V8X  g   K  \        P                  P	                  V4      pVu # 	  R # r6   )	attributenameonnxhelperget_attribute_value)r   rI   attrvalues   &&  r   get_node_attributeFusion.get_node_attribute^   s:    NNDyyN*77= # r   c               $    V ^8  d   QhRRRRRR/# )r	   node_outputr   
child_noder    r*   intr   )r   s   "r   r   r   g   s!       . S r   c                	V    \        VP                  4       F  w  r#W08X  g   K  Vu # 	  R# )   )	enumerateinput)rU   rV   index
input_names   &&  r   input_indexFusion.input_indexf   s,    !*:+;+;!<E( "= 	r   c                   V ^8  d   QhRR/# )r	   r*   z	list[int]r   )r   s   "r   r   r   n   s     	 	Y 	r   c                	6   . pV P                   P                   F|  pVP                  R 4      '       d   VP                  VP                  4       K7  VP                  R4      '       d   VP                  VP
                  4       Kk  VP                  R4       K~  	  V# )	dim_value	dim_param?)shapedimHasFieldappendrc   rd   )tensor_type
shape_listds   &  r   tensor_shape_to_listFusion.tensor_shape_to_listm   su    
""&&Azz+&&!!!++.K((!!!++.!!#& ' r   c                   V ^8  d   QhRR/# )r	   r   r    r   )r   s   "r   r   r   y   s      ~ r   c                	    \        VP                  4       F)  w  r#V P                  P                  V4      pVf   K&  W$3u # 	  R# )NNN)r[   r\   r
   get_constant_value)r   r   iinprQ   s   &&   r   get_constant_inputFusion.get_constant_inputy   s@    

+FAJJ11#6E x ,
 r   c               (    V ^8  d   QhRRRRRRRR/# )r	   r   r    expected_valuefloatdeltar*   rW   r   )r   s   "r   r   r      s*        V[ kn r   c                	    V P                  V4      w  rEVe*   VP                  ^8X  d   \        WR,
          4      V8  d   V# R# )NrZ   )ru   sizeabs)r   r   rx   rz   rs   rQ   s   &&&&  r   find_constant_inputFusion.find_constant_input   s>    **40qS9O5PSX5XH	r   c               (    V ^8  d   QhRRRRRRRR/# )r	   r   r    rx   ry   rz   r*   r+   r   )r   s   "r   r   r      s0     J J~ Ju JUZ Jjn Jr   c                	,    V P                  WV4      ^ 8  # )r   )r~   )r   r   rx   rz   s   &&&&r   has_constant_inputFusion.has_constant_input   s    ''eDIIr   c               $    V ^8  d   QhRRRRRR/# )r	   output_namer   rankrW   r*   r+   r   )r   s   "r   r   r      s!      3 c d r   c                	    V P                   P                  V4      pVf   R# \        VP                  4      V8w  d   R# R# )NFT)r
   rr   lenrf   )r   r   r   rQ   s   &&& r   is_constant_with_specified_rank&Fusion.is_constant_with_specified_rank   s5    

--k:=u{{t#r   Nc          
     ,    V ^8  d   QhRRRRRRRRR	R
/# )r	   r   r    parent_op_typer   r#    dict[str, onnx.NodeProto] | Noneexcluder>   r*   z(tuple[onnx.NodeProto | None, int | None]r   )r   s   "r   r   r      s<        >	
 & 
2r   c                    Vf   V P                   P                  4       p\        VP                  4       F3  w  rVWc9   g   K  W6,          pVP                  V8X  g   K(  Wt9  g   K0  Wu3u # 	  R# )a  
Find parent node based on constraints on op_type.

Args:
    node: current node.
    parent_op_type (str): constraint of parent node op_type.
    output_name_to_node (dict): dictionary with output name as key, and node as value.
    exclude (list): list of nodes that are excluded (not allowed to match as parent).

Returns:
    parent: The matched parent node. None if not found.
    index: The input index of matched parent node. None if not found.
rq   )r
   r#   r[   r\   r.   )r   r   r   r#   r   rs   rt   parents   &&&&&   r   match_first_parentFusion.match_first_parent   sa    ( &"&**"@"@"B

+FA),1>>^38M!9$	 , r   c               4    V ^8  d   QhRRRRRRRRR	R
RRRR/# )r	   r   r    r   r   r_   z
int | Noner#   r   r   r>   return_indicelist[int] | Noner*   onnx.NodeProto | Noner   )r   s   "r   r   r      sP     - -- -  	-
 >- &- (- 
-r   c                p   Vf   Q hVe
   V^ 8  g   Q hVf   V P                   P                  4       pVf,   V P                  WWE4      w  rxVe   VP                  V4       V# V\	        VP
                  4      8  d   R# V P                   P                  WV4      pVe   VP                  V8X  d	   Wu9  d   V# R# )a  
Find parent node based on constraints on op_type and index.
When input_index is None, we will find the first parent node based on constraints,
and return_indice will be appended the corresponding input index.

Args:
    node (str): current node name.
    parent_op_type (str): constraint of parent node op_type.
    input_index (int or None): only check the parent given input index of current node.
    output_name_to_node (dict): dictionary with output name as key, and node as value.
    exclude (list): list of nodes that are excluded (not allowed to match as parent).
    return_indice (list): a list to append the input index when input_index is None.

Returns:
    parent: The matched parent node.
N)r
   r#   r   ri   r   r\   
get_parentr.   )	r   r   r   r_   r#   r   r   r   r]   s	   &&&&&&&  r   match_parentFusion.match_parent   s    2 "kQ&666&"&**"@"@"B 33DJ]gMF($$U+M#djj/)&&t:MN&..N"BvG\Mr   c               0    V ^8  d   QhRRRRRRRRR	RR
R/# )r	   r   r    parent_op_typesr@   parent_input_indexr   r#   r   r   r*   zlist[onnx.NodeProto] | Noner   )r   s   "r   r   r      sF     / // #/ -	/
 >/ (/ 
%/r   c           
     *   Ve   \        V4      \        V4      8X  g   Q hVf   V P                  P                  4       pTp. p\        V4       FB  w  rT P	                  TT	Ve	   W8,          MRV. VR7      p
V
f    R# VP                  V
4       T
pKD  	  V# )a  
Find a sequence of input edges based on constraints on parent op_type and index.
When input_index is None, we will find the first parent node based on constraints,
and return_indice will be appended the corresponding input index.

Args:
    node (str): current node name.
    parent_op_types (str): constraint of parent node op_type of each input edge.
    parent_input_index (list): constraint of input index of each input edge. None means no constraint.
    output_name_to_node (dict): dictionary with output name as key, and node as value.
    return_indice (list): a list to append the input index
                          When there is no constraint on input index of an edge.

Returns:
    parents: a list of matched parent node.
N)r   r   )r   r
   r#   r[   r   ri   )r   r   r   r   r#   r   current_nodematched_parentsrs   r.   matched_parents   &&&&&&     r   match_parent_pathFusion.match_parent_path   s    0 ))*c/.BBBB&"&**"@"@"B#O4JA!..);)G"%T#+ / N %"">2)L 5 r   c               (    V ^8  d   QhRRRRRRRR/# )	r	   r   r    pathsz!list[tuple[list[str], list[int]]]r#   r$   r*   z9tuple[int, list[onnx.NodeProto] | None, list[int] | None]r   )r   s   "r   r   r     s3       1 7	
 
Cr   c                    \        V4       F6  w  rE. pV P                  W^ ,          V^,          W64      pV'       g   K2  WGV3u # 	  R# )z0
Find a matching parent path to the given node.
)rZ   NN)r[   r   )r   r   r   r#   rs   pathr   matcheds   &&&&    r   match_parent_pathsFusion.match_parent_paths  sO     !'GAM,,T7DGEXhGw=00	 (
 r   c          
     ,    V ^8  d   QhRRRRRRRRR	R
/# )r	   r   r    
child_typer   r!   z&dict[str, list[onnx.NodeProto]] | None	recursiver+   r*   r   r   )r   s   "r   r   r   $  s=        D	
  
r   c                	:   V P                   P                  W4      p\        V4      p\        V4      ^ 8  de   VP	                  4       pVP
                  V8X  d   V# V'       g   K=  V P                   P                  Ws4      pV F  pVP                  V4       K  	  Kt  R# )r   N)r
   get_childrenr   r   popr.   
appendleft)	r   r   r   r!   r   childrendqr   childs	   &&&&&    r   find_first_child_by_typeFusion.find_first_child_by_type$  s     ::**4E8_"gk668L##z1##y::22<U%EMM%( & r   )r   r   r   r
   r   r   r   )gư>)NNN)NT)__name__
__module____qualname____firstlineno____doc__r   r'   r3   r;   staticmethodrF   rR   r_   rm   ru   r~   r   r   r   r   r   r   r   __static_attributes__r   r   r   r   r      s    *
"*
  $     	 	J AE(*F #'@D(**.-^/b  r   r   )
__future__r   collectionsr   rM   
onnx_modelr   r   r   r   r   <module>r      s    #   "h hr   