
    Vh+                        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,                  j.                     Zee
j,                  j.                     Zee   Zh dZ ed	
      d        Z ed	
      deee
j>                  j@                  f   de
j,                  j.                  defd       Z! ed	
      de
j,                  j.                  de"fd       Z# ed	
       G d d             Z$ ed	
      de
j,                  jJ                  de
j,                  jJ                  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>   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     L/home/dcms/DCMS/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   R   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nodesr6   )selfr   r6   s      r   __init__zFxNetAccFusionsFinder.__init__e   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;   rB   addrA   discardupdateall_input_nodesr&   r'   )r<   r"   ns      r   add_nodez*FxNetAccFusionsFinder.FusionGroup.add_nodex   s     tzz!##''-JJNN4 KK%KK "11tt00Qdjj5H s   )B5N)r   r   __qualname__int__annotations__NodeSetrI    r    r   FusionGroupr?   j   s%        $#	r    rO   Nfusion_groupr?   rA   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)	rD   r&   r'   r;   indexr@   recursive_add_noderG   rI   )r<   rP   rA   rQ   args        r   rT   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)r@   r;   rA   rB   )rQ   )r9   r6   r&   r'   r/   rO   r;   rS   setrG   rB   poprT   rA   usersrI   minr@   )r<   resultr6   r"   rP   userrU   rH   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    r8   )r   r   rJ   __doc__r2   fxGraphModulerM   r=   r   rO   r   NodeListr   rT   dictNoder^   rN   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
    r      c                     |    S r8   rN   )xenvs    r   <lambda>z legalize_graph.<locals>.<lambda>/  s    c!f r    r   z&Input graph has cycles, unable to add ))operatorrD   mulsubfloordivtruedivmodleltgegteqner2   opsatensym_constrain_rangedefaultsym_constrain_range_for_size_assert_asyncmsgscalar_tensor_assert_scalarrc   fromkeysr:   r;   r`   GraphrZ   collectionsdequeappendlenpopleft	node_copyr&   r)   
appendleftRuntimeError_codegen)	re   PRIORITIZED_OPSindeg	new_graphr"   r]   queuecurrj   s	           @r   r   r      s   * 			**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
)'r   rl   collections.abcr   dataclassesr   typingr   r   r   r2   torch.fxtorch.fx._compatibilityr   torch.fx.noder	   __all__tupler3   r9   TensorsTensorOrTensorsr`   rd   rb   rX   rM   r   Namesr'   r
   nnModuler   boolr   r   ra   r   rN   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,Guxx++ G0D0D G -Gr    