
    קgs+                        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        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 )    )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                            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     X/var/www/html/ai-engine/env/lib/python3.11/site-packages/torch/fx/passes/tools_common.pyr   r      su    !S :	
 :)q|33&!*&&&%%lK@@"*&&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   E   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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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>u   s=       t000Qdj5H5H 5H5H5Hr$   )r?   rF   addrE   discardupdateall_input_nodes)r@   r&   s   ` r#   add_nodez*FxNetAccFusionsFinder.FusionGroup.add_nodej   s     tz!!#''---JNN4   K%%%K   !1      r$   N)r   r   __qualname__int__annotations__NodeSetrQ   rI   r$   r#   FusionGrouprC   \   sW             $###	 	 	 	 	r$   rV   Nfusion_grouprC   rE   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)	rM   r*   r+   r?   indexrD   recursive_add_noderP   rQ   )r@   rW   rE   rX   args        r#   r[   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)rD   r?   rE   rF   )rX   )r=   r:   r*   r+   r3   rV   r?   rZ   setrP   rF   popr[   rE   usersrQ   minrD   )r@   resultr:   r&   rW   userr\   rK   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$   r<   )r   r   rR   __doc__r6   fxGraphModulerU   rA   r   rV   r   NodeListr
   r[   r   Nodere   rI   r$   r#   r   r   P   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 r<   rI   )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   rI   )rJ   r&   indegs     r#   
<listcomp>z"legalize_graph.<locals>.<listcomp>,  s+    DpDpDpd_dei_jno_o_oT_o_o_or$   ))operatorrM   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?   rg   Graphra   collectionsdequeappendlenpopleft	node_copyr*   r-   
appendleftRuntimeError_codegen)	rk   PRIORITIZED_OPS	new_graphr&   rd   queuecurrp   rs   s	          @@r#   r   r      ss   * 		*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rDpDpDpDpV[DpDpDprrsss*IBHIr$   )'typingr   r   r   r   r   r   r	   r
   r   dataclassesr   ru   r6   torch.fxtorch.fx.noder   torch.fx._compatibilityr   __all__r7   TensorsTensorOrTensorsrg   rj   ri   rU   r   Namesr+   r   nnModuler   boolr   r   rh   r   rI   r$   r#   <module>r      sq   H H H H H H H H H H H H H H H H H H H H     ! ! ! ! ! !    - - - - - - 1 1 1 1 1 1
u
u
u
el#T%,%77
8g-.
ehm
S	CCC  e,,,: : -,: e,,,!UX_(< = !UX] !WZ ! ! ! -,!F e,,,A A$ A A A -,A e,,,U U U U U U U -,Up e,,,Eux+ E0D E E E -,E E Er$   