
    i&6                     b   d dl Z d dlZd dlZd dlmZ d dlmZ d dlmZm	Z	m
Z
 d dlZd dlZd dlmZ d dlmZ g dZe
eej&                     eej&                     f   Ze
ej&                  ef   Zeej.                  j0                     Zeej.                  j0                     Zee   Zh dZ ed	
      d        Z ed	
      deeej@                  jB                  f   dej.                  j0                  defd       Z" ed	
      dej.                  j0                  de#fd       Z$ ed	
       G d d             Z% ed	
      dej.                  jL                  dej.                  jL                  fd       Z' ed	
      dej.                  jL                  dej.                  jL                  fd       Z(y)    N)Mapping)	dataclass)AnyOptionalUnion)compatibility)_get_qualified_name)get_acc_ops_nameget_node_targetis_node_output_tensorFxNetAccFusionsFinderlegalize_graphstable_topological_sort>   call_methodcall_modulecall_functionF)is_backward_compatiblec                     t        | t              r| S | j                  rd| j                  v rd| j                   S | j                  j	                  dd      }|r|nd d| j                   S )Nacc_opsacc_ops.z
torch._opsz	torch.ops .)
isinstancestr
__module____name__replace)kmodules     V/var/www/html/engine/venv/lib/python3.12/site-packages/torch/fx/passes/tools_common.pyr
   r
       si    !S	
)q||3!**&&%%+
 #&+1QZZL99    
submodulesnodereturnc                 $   |j                   t        v s-J ddj                  t              z   d|j                    z          |j                   dk(  rLt        |j                  t
              sJ | |j                     }t        |dt        |            }t        |      S |j                   dk(  r@|j                  }|j                  d|j                  v rd|j                   S t        |      S t        |j                  t
              sJ |j                  S )	a,  
    Given a `node` returns its target typename.

    For "call_method" node, return node.target which is the name of that method being called.
    This could potential lead to conflict but should be okay because normally it's on a tensor.

    For "call_function" node, return typename of node.target.

    For "call_module" node, return typename of the module that node.target point to.

    If seeing "_VariableFunctionsClass" in the target name string, it will be replaced by
    "torch". e.g. _VariableFunctionsClass.relu would become torch.relu.
    zExpect op types of z, z, but found r   _base_class_originr   r   r   )opCALLABLE_NODE_OPSjoinr   targetr   getattrtyper
   r   r   r	   )r"   r#   submodsubmod_typer*   s        r    r   r   -   s   $ 77'' 		*; <<dggY?WW' ww-$++s+++DKK(f&:DLI,,	O	#kk   ,f>O>O1O v'(	
 %V,	
 $++s+++{{r!   c                 z    | j                   j                  dd      }|duxr t        |t        j                        S )a  Checks if the node output produces a Tensor or not.

    NOTE: This requires to run `ShapeProp` on the containing fx graph before
    calling this function. This is because it works by checking the `type`
    metadata on the node. This metadata is produced by the `ShapeProp`.
    r,   N)metaget
issubclasstorchTensor)r#   type_s     r    r   r   T   s3     IIMM&$'E@E5<<!@@r!   c                       e Zd ZdZdej
                  j                  defdZe	 G d d             Z
	 ddd	d
eeef   dee   fdZdeej
                  j                   ef   fdZy)r   z
    Finds groups of connected ACC nodes that pass non-tensor data between each other.
    Such groups are called fusion groups.
    r   	acc_nodesc                 h    || _         t        |j                  j                        | _        || _        y N)r   listgraphnodesr7   )selfr   r7   s      r    __init__zFxNetAccFusionsFinder.__init__g   s&    &,,,,-
"r!   c                   <    e Zd ZU eed<   eed<   eed<   eed<   d Zy)!FxNetAccFusionsFinder.FusionGrouptop_node_idxr<   inputsnodes_need_processc                 t   || j                   v ry| j                  j                  |       | j                   j                  |       | j                  j	                  |       | j                  j                  |j                  D ch c]$  }|j                  t        v r|| j                   vr|& c}       yc c}w )z5
            Add a node to fusion group.
            N)	r<   rC   addrB   discardupdateall_input_nodesr'   r(   )r=   r#   ns      r    add_nodez*FxNetAccFusionsFinder.FusionGroup.add_nodez   s     tzz!##''-JJNN4 KK%KK "11tt00Qdjj5H s   )B5N)r   r   __qualname__int__annotations__NodeSetrJ    r!   r    FusionGroupr@   l   s%        $#	r!   rP   Nfusion_groupr@   rB   visitedc                 :   |D ]  }|||v r
|j                  |       |j                  t        vr.| j                  j	                  |      |j
                  k  rW||j                  v r y| j                  ||j                  |      s|j                  |        y y)z
        Start from inputs and going reverse topological order. If any upstream node
        is in the fusion group, add all the nodes in this path to fusion group.
        TF)	rE   r'   r(   r<   indexrA   recursive_add_noderH   rJ   )r=   rQ   rB   rR   args        r    rU   z(FxNetAccFusionsFinder.recursive_add_node   s      	C"'>C  vv.. zz$|'@'@@ l((( &&|S5H5H'R%%c*1	4 r!   r$   c                    i }t        | j                        }|D ]_  }||v r	|j                  t        vrd|j                  v r+|| j                  vr:| j                  | j                  j                  |      |ht        |j                        |h      }|j                  rs|j                  j                         }| j                  ||j                  t                      d|j                  vrj|j                  D ][  }|j                  t        vr||j                  v r%|j                  |       | j                  ||j                  t                      ] |j                  D ]  }|j                  t        vrd|j                  v r%||j                  v r4|j                  |       t!        |j"                  | j                  j                  |            |_        | j                  ||j                  t                       |j                  rst        |j                        | j                  k  s!| xj                  |j                  z  c_        @|j                  D ]  }|j                  ||<    b |S )Ntensor_meta)rA   r<   rB   rC   )rR   )r:   r7   r'   r(   r0   rP   r<   rT   setrH   rC   poprU   rB   usersrJ   minrA   )r=   resultr7   r#   rQ   userrV   rI   s           r    __call__zFxNetAccFusionsFinder.__call__   s[   /1(	 >	3Dv~ww//		)4>>)>B>N>N!ZZ--d3f4//0$(6	 ?O ?L 11#66::<''  ''E (  !		1 $

 77*;;$<#5#55$$--d3//((//$'E 0   // Cvv%66 $0 l000  ))#.03$114::3C3CC3H1L- ++$$++ # , 1 11T **+t~~=,"4"44%++ 3A , 2 2F1I3{>	3@ r!   r9   )r   r   rK   __doc__r3   fxGraphModulerN   r>   r   rP   r   NodeListr   rU   dictNoder_   rO   r!   r    r   r   `   s    
#uxx33 # #
   F &*	$9$ gx'($ '"	$LD$uxx}}g56 Dr!   r   gmc                 (   t         j                  t         j                  t         j                  t         j                  t         j
                  t         j                  t         j                  t         j                  t         j                  t         j                  t         j                  t         j                  t        j                  j                  j                   j"                  t        j                  j                  j$                  j"                  t        j                  j                  j&                  j(                  t        j                  j                  j*                  j"                  t        j                  j                  j,                  j"                  g}t.        j1                  | j2                  j4                  d      }t        j6                  j9                         }| j2                  j4                  D ]   }|j:                  D ]  }||xx   dz  cc<    " t=        j>                         }| j2                  j4                  D ]  }||   dk(  s|jA                  |        i tC        |      dkD  r|jE                         }|jG                  |fd      |<   |j:                  D ]X  }||xx   dz  cc<   ||   dk(  s|jH                  dk(  r |jJ                  |v r|jM                  |       H|jA                  |       Z tC        |      dkD  rtC        |j4                        tC        | j2                  j4                        k  r%tO        d|D cg c]  }||   dk7  s| c}       | j2                  jP                  |_(        || _        | S c c}w )a  
    Replace the graph of the given GraphModule with one that contains the same nodes as the
    original, but in topologically sorted order.

    This is used by the merge_matmul transformation below, which disturbs the topologically sorted
    order of its input GraphModule, so that this order is restored before further transformation.

    Arguments:
        gm: The graph module to topologically sort. It is modified in-place.

    Returns:
        The graph module in-place sorted

    Warning:
        This topological sort is NOT stable, it will NOT preserve the original node order.
        If you need a stable topological sort, use stable_topological_sort instead.
    r      c                     |    S r9   rO   xenvs    r    <lambda>z legalize_graph.<locals>.<lambda>5      c!f r!   r   &Input graph has cycles, unable to add ))operatorrE   mulsubfloordivtruedivmodleltgegteqner3   opsatensym_constrain_rangedefaultsym_constrain_range_for_size_assert_asyncmsgscalar_tensor_assert_scalarrd   fromkeysr;   r<   ra   Graphr[   collectionsdequeappendlenpopleft	node_copyr'   r*   
appendleftRuntimeError_codegen)	rf   PRIORITIZED_OPSindeg	new_graphr#   r^   queuecurrl   s	           @r    r   r      s   2 			**22		33;;		$$((		$$,,		%%--#O( MM"((..!,E I JJ 	D$K1K	  +002E ;!LL /1C e*q.mmo&&s,<=CII 	'D$K1KT{a77o-$++2P$$T*LL&	' e*q. 9??c"((..114u5atPUVZP[_`P`d5a4bc
 	
 **IBHI	 6bs   N
N
c                   
 t         j                  | j                  j                  d      }t        j
                  j                         }t        | j                  j                        D ci c]  \  }}||
 }}}| j                  j                  D ]   }|j                  D ]  }||xx   dz  cc<    " g }| j                  j                  D ]&  }||   dk(  st        j                  |||   |f       ( i 
|rut        j                  |      \  }}	|j                  |	
fd      
|	<   |	j                  D ]3  }||xx   dz  cc<   ||   dk(  st        j                  |||   |f       5 |rut        |j                        t        | j                  j                        k(  s!J d|D cg c]  }||   dk7  s| c}        | j                  j                  |_        || _        | S c c}}w c c}w )aR  
    Replace the graph of the given GraphModule with one that contains the same nodes as the
    original, but in topologically sorted order while preserving the original node order
    as much as possible.

    This function performs a stable topological sort where nodes appear in an order that:
    1. Respects data dependencies (topological ordering)
    2. Preserves the original node order when there are no dependency constraints

    The algorithm uses Kahn's algorithm with a priority queue: nodes with all dependencies
    satisfied are added to a min-heap, ordered by their original position. This ensures
    we always process the earliest node in the original order among ready nodes.

    Arguments:
        gm: The graph module to topologically sort. It is modified in-place.

    Returns:
        The graph module in-place sorted
    r   rh   c                     |    S r9   rO   rj   s    r    rm   z)stable_topological_sort.<locals>.<lambda>w  rn   r!   ro   )rd   r   r;   r<   r3   ra   r   	enumerater[   heapqheappushheappopr   r   r   )rf   r   r   idxr#   
node_to_idr^   ready_queue_r   rl   s             @r    r   r   H  s   * MM"((..!,E I $-RXX^^#<,c4c	,J ,
  JJ 	D$K1K	 46K B;!NN;D)94(@AB /1C {+3&&s,<=C II 	FD$K1KT{a{Z-=t,DE	F  y3rxx~~#66 
051]4ERVK[\L\$1]0^_6 **IBHIK,@ 2^s   ,G)*G/8G/))r   r   rp   collections.abcr   dataclassesr   typingr   r   r   r3   torch.fxtorch.fx._compatibilityr   torch.fx.noder	   __all__tupler4   r:   TensorsTensorOrTensorsra   re   rc   rY   rN   r   Namesr(   r
   nnModuler   boolr   r   rb   r   r   rO   r!   r    <module>r      s      # ! ' '   1 - ell#T%,,%77
8g-.
ehhmm
S	C  e,	: -	: e,#UXX__,-#5:XX]]## -#L e,A A$ A -A e,U U -Up e,Kuxx++ K0D0D K -K\ e,= 4 4 =9M9M = -=r!   