
    &Vji+                        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        j%        de
j        j%        fd            Z&dS )    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                            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/root/voice-cloning/.venv/lib/python3.11/site-packages/torch/fx/passes/tools_common.pyr
   r
      s|    !S :	
 :)q|33&!*&&&%%+
 
 #*&&99QZ999    
submodulesnodereturnc                    |j         t          v s0J dd                    t                    z   d|j          z               |j         dk    rVt          |j        t
                    sJ | |j                 }t          |dt          |                    }t          |          S |j         dk    r0|j        }|j	        d|j	        v r
d	|j
         n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   Nr   r   )opCALLABLE_NODE_OPSjoinr   targetr   getattrtyper
   r   r   r	   )r!   r"   submodsubmod_typer)   s        r   r   r   +   s   $ 7''''		*; < <<?Wdg?W?WW ('' w-$+s+++++DK(f&:DLLII,,,	O	#	#k  ,f>O1O1O )v((($V,,	
 $+s+++++{r    c                 t    | j                             dd          }|duo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   s5     IMM&$''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dS )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                 ^    || _         t          |j        j                  | _        || _        d S 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dS )!FxNetAccFusionsFinder.FusionGrouptop_node_idxr;   inputsnodes_need_processc                     | j         v rdS  j                            |            j                             |            j                            |            j                             fd|j        D                        dS )z5
            Add a node to fusion group.
            Nc                 B    h | ]}|j         t          v |j        v|S  )r&   r'   r;   ).0nr<   s     r   	<setcomp>z=FxNetAccFusionsFinder.FusionGroup.add_node.<locals>.<setcomp>   s=       t000Qdj5H5H 5H5H5Hr    )r;   rB   addrA   discardupdateall_input_nodes)r<   r"   s   ` r   add_nodez*FxNetAccFusionsFinder.FusionGroup.add_nodex   s     tz!!#''---JNN4   K%%%K   !1      r    N)r   r   __qualname__int__annotations__NodeSetrM   rE   r    r   FusionGroupr?   j   sW             $###	 	 	 	 	r    rR   Nfusion_groupr?   rA   visitedc                 .   |D ]}|||v r	|                     |           |j        t          vr-| j                            |          |j        k     rQ||j        v r dS |                     ||j        |          r|                    |            dS dS )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.
        NTF)	rI   r&   r'   r;   indexr@   recursive_add_noderL   rM   )r<   rS   rA   rT   args        r   rW   z(FxNetAccFusionsFinder.recursive_add_node   s      	 	C"'>>C    v... z$$|'@@@ l(((tt &&|S5H'RR %%c***tt ur    r#   c                 \   i }t          | j                  }|D ]}||v r|j        t          vrd|j        v r!|| j        vr+|                     | j                            |          |ht          |j	                  |h          }|j
        rQ|j
                                        }|                     ||j        t                                 d|j        vra|j        D ]Y}|j        t          vr||j        v r|                    |           |                     ||j        t                                 Z|j	        D ]}|j        t          vrd|j        v r||j        v r%|                    |           t!          |j        | j                            |                    |_        |                     ||j        t                                 |j
        Qt          |j                  | j        k    s| xj        |j        z  c_        |j        D ]}|j        ||<   |S )Ntensor_meta)r@   r;   rA   rB   )rT   )r9   r6   r&   r'   r/   rR   r;   rV   setrL   rB   poprW   rA   usersrM   minr@   )r<   resultr6   r"   rS   userrX   rG   s           r   __call__zFxNetAccFusionsFinder.__call__   s   /1((	 >	3 >	3Dv~~w///	))4>))>B>N>N!Z--d33f4/00$(6	 ?O ? ?L 1 (#6::<<''  'EE (    !	11 $
  7*;;;$<#555$$--d333//((/$'EE 0      /  Cv%666 $00 l000  ))#...03$14:3C3CC3H3H1 1L- ++$$+ # ,    I 1 (T *++t~==,"44%+ 3 3A , 2F1II3 r    r8   )r   r   rN   __doc__r2   fxGraphModulerQ   r=   r   rR   r   NodeListr   rW   dictNodera   rE   r    r   r   r   ^   s         
#ux3 # # # # #
        YF &*	$ $9$ gx'($ '"	$ $ $ $LD$ux}g56 D D D D D 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.                              | j        j        d          t          j                                        }| j        j        D ]}|j        D ]}|xx         dz  cc<   t=          j                    }| j        j        D ]#}|         dk    r|                     |           $i tC          |          dk    r|"                                }|#                    |fd          |<   |j        D ]]}|xx         dz  cc<   |         dk    r?|j$        dk    r|j%        |v r|&                    |           H|                     |           ^tC          |          dk    tC          |j                  tC          | j        j                  k     rtO          dfdD                        | j        j(        |_(        || _        | S )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   rE   )xenvs    r   <lambda>z legalize_graph.<locals>.<lambda>/  s    c!f r    r   z&Input graph has cycles, unable to add c                 ,    g | ]}|         d k    |S )r   rE   )rF   r"   indegs     r   
<listcomp>z"legalize_graph.<locals>.<listcomp>;  s+    5a5a5atPUVZP[_`P`P`dP`P`P`r    ))operatorrI   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_scalarrf   fromkeysr:   r;   rc   Graphr]   collectionsdequeappendlenpopleft	node_copyr&   r)   
appendleftRuntimeError_codegen)	rh   PRIORITIZED_OPS	new_graphr"   r`   queuecurrm   rp   s	          @@r   r   r      sz   * 		*2	3;	$(	$,	%-#O( MM"(.!,,E  I  J 	 	D$KKK1KKKK	*022E  ;!LL.0C e**q..mmoo&&s,<,<,<,<==CI 	' 	'D$KKK1KKKT{a7o--$+2P2P$$T****LL&&& e**q.. 9?c"(.1111c5a5a5a5au5a5a5acc
 
 	
 *IBHIr    )'r   rr   collections.abcr   dataclassesr   typingr   r   r   r2   torch.fxtorch.fx._compatibilityr   torch.fx.noder	   __all__tupler3   r9   TensorsTensorOrTensorsrc   rg   re   r[   rQ   r   Namesr'   r
   nnModuler   boolr   r   rd   r   rE   r    r   <module>r      so        # # # # # # ! ! ! ! ! ! ' ' ' ' ' ' ' ' ' '   1 1 1 1 1 1 - - - - - -   el#T%,%77
8g-.
ehm
S	CCC  e,,,	: 	: -,	: e,,,#UX_,-#5:X]## # # -,#L e,,,A A$ A A A -,A e,,,U U U U U U U -,Up e,,,Gux+ G0D G G G -,G G Gr    