
    sgs+                        d dl mZmZmZmZmZmZmZmZ d dl	Z	d dl
mZ d dl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>                  j@                  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.                  jJ                  dej.                  jJ                  fd       Z&y)    )ListTupleUnionDictAnySetMappingOptionalN)	dataclass)_get_qualified_name)compatibility)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     O/var/www/html/venv/lib/python3.12/site-packages/torch/fx/passes/tools_common.pyr   r      sd    !S	
)q||3!**&&%%lK@"&+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   E   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nodesr:   )selfr"   r:   s      r#   __init__zFxNetAccFusionsFinder.__init__W   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?   rF   addrE   discardupdateall_input_nodesr*   r+   )r@   r&   ns      r#   add_nodez*FxNetAccFusionsFinder.FusionGroup.add_nodej   s     tzz!##''-JJNN4 KK%KK "11tt00Qdjj5H s   )B5N)r   r   __qualname__int__annotations__NodeSetrM    r$   r#   FusionGrouprC   \   s%        $#	r$   rS   Nfusion_grouprC   rE   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)	rH   r*   r+   r?   indexrD   recursive_add_noderK   rM   )r@   rT   rE   rU   args        r#   rX   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)rD   r?   rE   rF   )rU   )r=   r:   r*   r+   r3   rS   r?   rW   setrK   rF   poprX   rE   usersrM   minrD   )r@   resultr:   r&   rT   userrY   rL   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$   r<   )r   r   rN   __doc__r6   fxGraphModulerQ   rA   r   rS   r   NodeListr
   rX   r   Noderb   rR   r$   r#   r   r   P   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 r<   rR   )xenvs    r#   <lambda>z legalize_graph.<locals>.<lambda>!  s    c!f r$   r   z&Input graph has cycles, unable to add ))operatorrH   mulsubfloordivtruedivmodleltgegteqner6   opsatensym_constrain_rangedefaultsym_constrain_range_for_size_assert_asyncmsgscalar_tensor_assert_scalardictfromkeysr>   r?   rd   Graphr^   collectionsdequeappendlenpopleft	node_copyr*   r-   
appendleftRuntimeError_codegen)	rh   PRIORITIZED_OPSindeg	new_graphr&   ra   queuecurrm   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CV[Dpd_dei_jno_oTDpCqrss**IBHI Eqs   N
N
)'typingr   r   r   r   r   r   r	   r
   r   dataclassesr   ro   r6   torch.fxtorch.fx.noder   torch.fx._compatibilityr   __all__r7   TensorsTensorOrTensorsrd   rg   rf   rQ   r   Namesr+   r   nnModuler   boolr   r   re   r   rR   r$   r#   <module>r      s   H H H  !    - 1
u
ell#T%,,%77
8g-.
ehhmm
S	C  e,: -: e,!UXX__(< = !UXX]] !WZ ! -!F e,A A$ A -A e,U U -Up e,Euxx++ E0D0D E -Er$   