
    :ik                        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 d dl	Z	d dl
mZ d dlmZ d dlmZ d dlmZ d	d
gZ ej        e          xZZ ed           G d d	                      Zde	j        j        dedefdZ ed          	 	 	 	 ddddede	j        j        deegef         deeeef                  dee         dee         dedee         fd            ZdS )    N)OrderedDict)Callable)AnyOptional)compatibility)lazy_format_graph_code)GraphModule)Node	Partitionsplit_moduleT)is_backward_compatiblec                   &    e Zd ZdefdZdefdZdS )r   namec                     || _         d| | _        g | _        i | _        i | _        i | _        i | _        t          j        j	        
                                | _	        i | _        i | _        d S )Nsubmod_)r   submod_name
node_namesinputsoutputsdependencies
dependentstorchfxgraphGraphenvironmenttargets)selfr   s     O/var/www/icac/venv/lib/python3.11/site-packages/torch/fx/passes/split_module.py__init__zPartition.__init__   sg    	+T++%'')(*-/+-+08>+?+?+A+A
-/')    returnc                 f    d| j          d| j         d| j         d| j         d| j         d| j         S )Nzname: z
,
 nodes: z,
 inputs: z,
 outputs: z,
 partitions depended on: z,
 partition dependents: )r   r   r   r   r   r   )r   s    r   __repr__zPartition.__repr__!   sl    8TY 8 88 88 8 8 8 )-(9	8 8
 '+o8 8	
r!   N)__name__
__module____qualname__strr    r$    r!   r   r   r      sJ        
*S 
* 
* 
* 
*
# 
 
 
 
 
 
r!   modqualnamer"   c                     | }|                     d          D ]5}t          ||          st          d| d          t          ||          }6|S )N.zNode target z not found!)splithasattrAttributeErrorgetattr)r*   r+   attr_valatoms       r   _get_attr_from_qualnamer4   ,   se    Hs## + +x&& 	G !E!E!E!EFFF8T**Or!   F)partition_affixmroot_msplit_callbackqualname_mapkeep_original_orderkeep_original_node_namekeep_original_input_namer5   c                j   9:;<=>?@ABCDEF t                               dt          d d                     dt          dt          t
          t          f         dt          t
          t          j        j        j	        f         f: fd}d	d
l
}	i Di Ai Fdt          dt          t                   fDFfdEDfd}
t          j        j        t          j        j        t          j        j        g}t#                      }t#                      }i }d
}t%                      } j        j        D ]g??j                            d          x}Zt/          |t          j        t          j        f          r4t/          |j        j        x}|	j                  r|Fvr?F|j        j        <   ?j        dv r |
?           ?j        dk    r~?j        |v rt?j        t          j        j        u r\t?          ?j                   dk    sJ t/          ?j         d	         tB                    sJ ?}t%           ?          h          ||<   n ?j        t          j        j        u rWtE          d ?j         D                       sJ |#                    ?           t%           ?          h          |?<   d
|?<   n?j        t          j        j        u ryt?          ?j                   dk    sJ |?j         d	                  #                     ?                     |$                    ?j         d	                    ?|?j         d	         <   |$||         #                     ?                     |D ]&}||         #                     ?                     'itE          d |%                                D                       s
J d            d |&                                D             }d |&                                D             }tN          (                    tR          j*                  r6tN                              d|           tN                              d|           tC          |          ptC          |          }d} j        j        D ]ߊ??A?j+        <   ?j        dv r?j        dk    r4t          j        j        ,                    ?j         d	         Efd           U|r# ?          }||k    sJ d| d|             |}?j        |vr\t          j        j        ,                    ?j         ?Efd            t          j        j        ,                    ?j-        ?Efd!           t]          D/                                          }g }D&                                D ].\  }Ct?          Cj0                  s|1                    |           /g }|r}|2                                }|1                    |           D|         j3        D ]D}D|         j0        2                    |           D|         j0        s|1                    |           E|}t?          |          t?          D          k    rti          d"          ||fD ]}|&                                D ]\  ?}t?          |          d	k    sJ ?Dt          |d	                            j5        ?<   |dd
         D ]}Dt          |                   CCj        6                    ?j        ?j        to          d# ?j         D                       i ?j8        $          } ?j        9                                | _        | Cj5        ?<   Ҍ|D ]}D|         Ci >d	;Cj:        D ]=A=         }!;=>ACfd%}"|!j        d&k    rt/          |!j        t
                    sJ tw           |!j                  }#t/          |#t          j<        j=                  r/Cj        >                    |!j                  }$|#Cj?        |!j        <   n |"            }$n
 |"            }$A=         j        9                                |$_        |$Cj5        A=         <   >C_:         j        j        D ]p?t          ?d'          r\D?jA                 CCj5        <t          j        j        ,                    ?j         <fd(          }%t          j        j        ,                    ?j-        <fd)          }&?j        d*vr?j        }'nRtw           ?j                  }(?j        B                    d+d,          }'|(Cj?        |'<   |CjC         d+|' })?j        ||)<   t/          |%tn                    sJ t/          |&t                    sJ r?j+        nd
}*Cj        6                    ?j        |'|%|&?j8        |*-          } ?j        9                                | _        | Cj5        ?<   r|fD ]}t          |          D ]?|?         }t?          |          d	k    sJ |d
d         D ]}Dt          |                   C|?         }+|+
J d.            Cj        6                    |+j        |+j        Cj5        ?         fi |+j8        $          } |+j        9                                | _        i @i 9t          j        j        E                                :i },|s  j        j        D ]? |?9|,          \  9},n j        j        D ]??@?j+        <   |s|n|}-t%                      }.d/  j        j        D             B|-D ]}D|         Cto          ACfd0CjF        D                       }/t?          |/          }0|0dk    r!Cj        G                    |/d	                    n;|0dk    rCj        G                    |/           nCj        G                    d1           |rr@Bfd2Cj:        D             }1BD ],??|.v r |?9|,          \  9}2|.#                    ?           -|1D ],??|.v r |?9|,          \  9},|.#                    ?           -t          j        j        	                    Cj?        Cj                  |,CjC        <   :H                    CjC        to          9fd3Cj:        D                                 }3t?          CjF                  }4|4dk    rPt          j        jI        J                    |3          }5t          CjF                  D ]\  }6}7|5|6         j        9|7<   |4dk    r$|39t          t          CjF                            <   |r!9s j        j        D ]? |?9|,          \  9}, j        j        D ]S??j        dk    rF:G                    t          j        j        ,                    ?j         d	         9fd4                     Tt          j        j        	                    |,:          }8t                               dt          d5|8d                     |8S )6a  
    Creates subgraphs out of main graph

    Args:
        m (GraphModule): Graph module to split
        root_m (torch.nn.Module): root nn module. Not currently used. Included
            because the root nn module is usually transformed via
            torch.fx._symbolic_trace.symbolic_trace (see example below)
        split_callback (Callable[[Node], int]): Callable function
            that maps a given Node instance to a numeric partition identifier.
            split_module will use this function as the policy for which operations
            appear in which partitions in the output Module.
        qualname_map: Optional[Dict[str, str]]: optional output parameter that returns a
            mapping from new target names in the module after split to old target
            names in the original module.
        keep_original_order: Optional[bool]: keep the original order of the GraphModule
            or use the Topological order of the new constructed GraphModule
        keep_original_node_name: Optional[bool]: If the partitioned graphs should
            have the same node names as the original graph.
        keep_original_input_name: bool: If the partitioned graphs should
            have the same input names as the original graph.
        partition_affix: Optional[str]: If specified, the submodules' names will contain
            the affix, e.g. "submod_<affix>_<idx>".

    Returns:
        GraphModule: the module after split.

    Example:

        This is a sample setup:

            import torch
            from torch.fx._symbolic_trace import symbolic_trace
            from torch.fx.graph_module import GraphModule
            from torch.fx.node import Node
            from torch.fx.passes.split_module import split_module

            class MyModule(torch.nn.Module):
                def __init__(self) -> None:
                    super().__init__()
                    self.param = torch.nn.Parameter(torch.rand(3, 4))
                    self.linear = torch.nn.Linear(4, 5)

                def forward(self, x, y):
                    z = self.linear(x + self.param).clamp(min=0.0, max=1.0)
                    w = self.linear(y).clamp(min=0.0, max=1.0)
                    return z + w

            # symbolically trace model
            my_module = MyModule()
            my_module_traced = symbolic_trace(my_module)

            # random mod partitioning
            partition_counter = 0
            NPARTITIONS = 3

            def mod_partition(node: Node):
                global partition_counter
                partition = partition_counter % NPARTITIONS
                partition_counter = (partition_counter + 1) % NPARTITIONS
                return partition

            # split module in module with submodules
            module_with_submodules = split_module(
                my_module_traced, my_module, mod_partition
            )

        Output looks like this. Original graph is broken into partitions

            > print(module_with_submodules)
            GraphModule(
                (submod_0): GraphModule(
                    (linear): Linear(in_features=4, out_features=5, bias=True)
                )
                (submod_1): GraphModule(
                    (linear): Linear(in_features=4, out_features=5, bias=True)
                )
                (submod_2): GraphModule()
            )

            def forward(self, x, y):
                param = self.param
                submod_0 = self.submod_0(x, param, y);  x = param = y = None
                getitem = submod_0[0]
                getitem_1 = submod_0[1];  submod_0 = None
                submod_1 = self.submod_1(getitem, getitem_1);  getitem = getitem_1 = None
                getitem_2 = submod_1[0]
                getitem_3 = submod_1[1];  submod_1 = None
                submod_2 = self.submod_2(getitem_2, getitem_3);  getitem_2 = getitem_3 = None
                return submod_2

        Output of split module is the same as output of input traced module.
        This is an example within a test setting:

            > orig_out = my_module_traced(x, y)
            > submodules_out = module_with_submodules(x, y)
            > self.assertEqual(orig_out, submodules_out)
            True
    z%szpre split_moduleT)colorednodebase_mod_envbase_mod_attrsc                    | j         dk    rt          | j                  dk    r| j        d         nt          j        j        }rD|t          j        j        u rdn|f}                    d| j        || j                  || j        <   n*	                    | j
        | j        |          || j        <   | j                                        || j                 _        n| j         dk    r                    | j
                  || j        <   | j                                        || j                 _        t          | j
        t                    sJ t!          | j
                  }||| j
        <   ||fS )Nplaceholderr   r)   )args	type_expr)rE   default_valueget_attr)oplenrD   inspect	Signatureemptycreate_noder   typerC   targetmetacopyrG   
isinstancer(   r4   )	r?   r@   rA   rF   rD   r2   base_mod_graphr;   r6   s	         r   construct_graphz%split_module.<locals>.construct_graph   sq   
 7m## #DI 2 2	!8I8O  ' '7+<+BBBBBHX  +9*D*D!I"i	 +E + +TY'' +9*D*DK"i"/ +E + +TY'
 ,09>>+;+;L#((W
""&4&=&=dk&J&JL#+/9>>+;+;L#(dk3/////.q$+>>H*2N4;'^++r!   r   Ndef_nodeuse_nodec                    ddl m} t          | dd           }t          |dd           }t                              d| j        |||j        nd|           ||k    rq|C|         }|j                            | j                   ||j                            |           |+|         }|j	                            | j                   | j
                            d          x}t           ||          t                    D ]}|         }	|j	                            |	j                   |         j        dk    rnt          |	dd           }
|
[|
         }|j                            |	j                   |j                            |           |j                            |
           | |j                            |           d S d S d S d S )	Nr   )free_symbols_fx_partitionz*record_cross_partition_use %s (%s) %s (%s)-example_value)keyrC   )%torch.fx.experimental.symbolic_shapesrX   r1   logdebugr   r   
setdefaultr   r   rP   getsortedr(   rH   r   )rU   rV   rX   defineduseddef_partitionuse_partitiondef_valss_node	s_defineds_def_partition
partitionssymbol_to_nodes               r   record_cross_partition_usez0split_module.<locals>.record_cross_partition_use   s   FFFFFF(OT::x$77		8M%1HMMs	
 	
 	
 d??" *7 3%00???#!,77=== *4 0$//>>>  (}00AAAGN#LL$9$9sCCC Q Q!/!2%,77DDD)!,/=@@ )0(N(NI(42<Y2G / 7 B B6; O O O / : E Ed K K K - : E Ei P P P&!.99'BBBBBC ?  2 '&r!   c                 R    |           }t          |          }d                    |g          }t                              d| j        |                               |          }|t          |          x|<   }|j                            | j                   || _	        d S )N_z*instantiate_node_partition_mapping %s (%s))
r(   joinr^   r_   r   ra   r   r   appendrY   )r?   partition_idxpartition_name	partitionr5   rl   r8   s       r   "instantiate_node_partition_mappingz8split_module.<locals>.instantiate_node_partition_mapping  s    &t,,]++& !XX&GHHN		8$)^	
 	
 	

 NN>22	5>~5N5NNJ~&##DI...+r!   r[   )rC   rG   outputcall_function   c              3   B   K   | ]}t          |t                     V  d S N)rR   r
   .0args     r   	<genexpr>zsplit_module.<locals>.<genexpr>P  s/      JJz#t444JJJJJJr!   c              3      K   | ]}|d uV  	d S r{   r)   )r}   vs     r   r   zsplit_module.<locals>.<genexpr>`  s&      >>q}>>>>>>r!   zautocast must exitc                 4    i | ]\  }}|t          |          S r)   rb   r}   kr   s      r   
<dictcomp>z split_module.<locals>.<dictcomp>c  s$    JJJA6!99JJJr!   c                 4    i | ]\  }}|t          |          S r)   r   r   s      r   r   z split_module.<locals>.<dictcomp>e  s$    BBBTQAvayyBBBr!   zautocast_regions: %szgrad_regions: %s)rC   rG   rw   c                      | d           S r{   r)   )nrn   s    r   <lambda>zsplit_module.<locals>.<lambda>x  s    (B(B1d(K(K r!   zRautocast or set_grad_enabled require monotonically increasing partitions:highest: z, this node's: c                      |           S r{   r)   rU   r?   rn   s    r   r   zsplit_module.<locals>.<lambda>  s    ,F,FxQU,V,V r!   c                      |           S r{   r)   r   s    r   r   zsplit_module.<locals>.<lambda>  s    .H.HSW.X.X r!   z cycle exists between partitions!c              3      K   | ]}|V  d S r{   r)   r|   s     r   r   zsplit_module.<locals>.<genexpr>  s"      88ss888888r!   )rH   rO   rD   kwargsrE   c                  ~    r} n
d } dz  j                             |          j                  }d <   |S )Narg_ry   )rE   )r   rC   rN   )r   rC   counterinpr<   
new_inputs
orig_nodesru   s     r   add_placeholderz%split_module.<locals>.add_placeholder  sd    + !DD ,'++DqLG'o99(o2 :   #'
3""r!   rG   rY   c                     |          S r{   r)   r   r   s    r   r   zsplit_module.<locals>.<lambda>  s    TU r!   c                     |          S r{   r)   r   s    r   r   zsplit_module.<locals>.<lambda>  s    {1~ r!   )call_modulerG   r-   rp   )rH   rO   rD   r   rE   r   zMissing exit nodec                 (    g | ]}|j         d k    |S )rC   )rH   )r}   r?   s     r   
<listcomp>z split_module.<locals>.<listcomp>:  s$    QQQt=8P8Pd8P8P8Pr!   c              3   >   K   | ]}j         |                  V  d S r{   )r   )r}   r   r   ru   s     r   r   zsplit_module.<locals>.<genexpr>@  sA       
 
8<I!*T"23
 
 
 
 
 
r!   r)   c                 (    g | ]}|v|         S r)   r)   )r}   r\   orig_mod_envoriginal_orders     r   r   z split_module.<locals>.<listcomp>P  s3     / / /n,, S!,,,r!   c              3   (   K   | ]}|         V  d S r{   r)   )r}   r   r@   s     r   r   zsplit_module.<locals>.<genexpr>n  s(      BB,t$BBBBBBr!   c                     | j                  S r{   )r   )r   r@   s    r   r   zsplit_module.<locals>.<lambda>  s    |AF?S r!   zpost split_module)Nr^   r_   r   r
   dictr(   r   r   graph_moduler	   sympyr   amp_enter_autocast_exit_autocast_C_set_grad_enabledr   setr   nodesrP   ra   rR   SymIntSymFloatr?   exprSymbolrH   rO   rI   rD   boolalladdremovevaluesitems_LOGGERisEnabledForloggingDEBUGr   map_argr   listkeysr   rr   popr   RuntimeErrorr   rM   tuplerN   rQ   r   r4   nnModulerG   r   r/   rY   replacer   reversedr   r   rw   r   proxyProxy	enumeratenextiter)Gr6   r7   r8   r9   r:   r;   r<   r5   rT   r   rv   GLOBAL_STATE_NODESgrad_regionsautocast_regionsautocast_exitsactive_gradactive_autocastsvals0aassert_monotonically_increasinghighest_partitionpidoriginal_partition_orderroot_partitionsrt   sorted_partitionsroot_partition	dependentregions_mappingregionsrnew_node	orig_noder   	orig_attrrC   gathered_argsgathered_kwargsrO   target_attrr+   r   	exit_noderA   construct_order_partitionsalready_constructed_attr_nodesoutput_valsnum_output_valsorig_mod_attr_nodes_based_mod_attrs
output_valnum_outputsoutput_val_proxyioutput_nameretr@   rS   r   r   r   r   r?   r   r   r   ru   rl   rn   rm   sG   ` `  ```                                                 @@@@@@@@@@@@@@r   r   r   6   s   ` II11dCCC  
 , ,39o , S%("7"CCD ,  ,  ,  ,  ,  ,  ,  ,D LLL')J"$J/1N/CT /CXd^ /C /C /C /C /C /C /Cb, , , , , , ,. 		!	 " 1<L 5@MM13NKuu +: +: IMM/222S?3u~ >?? @.2== @ .((,0N38=)7;;;**40007o%%$+9K*K*K{eh88849~~****!$)A,55555",/1E1E0F,G,G[))	 999JJ	JJJJJJJJ $$T***),nnT.B.B-C)D)D &'+t$$	 88849~~**** 1.22>>$3G3GHHH ''	!555/3ty|,"%))..*>*>???! 	: 	:AQ##NN4$8$89999	: >>n&;&;&=&=>>>>>TT@TTTT KJ1A1G1G1I1IJJJBB\-?-?-A-ABBBLGM** 8,.>???(,777&*+;&<&<&R\@R@R#    $
49 71117hHN""	!KKKK   * 	$ .&&C$+++D-D D>AD D ,++ !$ ;000HN""	VVVVV   HN""XXXXX    $JOO$5$566!#O%/%5%5%7%7 3 3!	9)** 	3"">222 $&
 2(,,..  000#N3> 	2 	2Iy!.22>BBBi(5 2&&y111  2 Z00=>>> -l; 7 7,2244 	7 	7MD'w<<!####<@Js71:'3D9QRR[ 7 7&s1vv.	$?66w;88di88888"i 7   INN$$  /7	%d++7	7( , && &&~.	&(
# 	A 	AC"3I# # # # # # # # # # |z))!)"2C888883Ay7GHH	i99 4"+/":":9;K"L"LK:CI%i&677"1/"3"3KK-o//)#388::K5@I!*S/22%	  $3 $34)) #	3"4#56I $/K!HN2249>V>V>V>VWWM#hn445555 O w9995aEE,,S#66,7	!&)+ #,"7BB&BBH-1[L*mU33333ot44444 7A499TD 227"&) 3  H !INN,,HM*2I!$' --  _-- 	 	D%d+Gw<<!####SbS\  &s1vv.	*40	 ,,.A,,,$?66 |$+#/57'n 7   N'')) 		( %'L$&L+08>+?+?+A+ANCEN 	+GM 	 	D+:?lN, ,(L..	 GM 	+ 	+D&*L## "5R:R  &)UU" RQqw}QQQN4 <E <E~.	  
 
 
 
 
@I@Q
 
 
 
 

 k**aO"";q>2222q  O"";//// O""2&&& 	9/ / / / /$+/ / / ' 9 99991@,2 2.. /2248888 , 9 9999/>,0 0,n /2248888050E0Q0Qy1
 1
y,-
 $//!BBBB1ABBBBB
 


 )+,,??$x~33J??"+I,=">"> E E;,<Q,?,D[))EA:DLd9#455667  < GM 	 	D+:?lN, ,(L..
   7h!!&&ty|5S5S5S5STT   (

+
+NN
K
KCII2CFFF   Jr!   )NFFT) rJ   r   collectionsr   collections.abcr   typingr   r   r   torch.fx._compatibilityr   torch.fx._utilsr   torch.fx.graph_moduler	   torch.fx.noder
   __all__	getLoggerr%   r^   r   r   r   r   r(   r4   intr   r   r   r)   r!   r   <module>r      s     # # # # # # $ $ $ $ $ $                  1 1 1 1 1 1 2 2 2 2 2 2 - - - - - -       
'!!(++ +g d+++
 
 
 
 
 
 
 ,+
0 C C     d+++
 .2*/.3%)Y	 &*Y	 Y	 Y	Y	HOY	 dVS[)Y	 4S>*	Y	
 "$Y	 &d^Y	 #Y	 c]Y	 Y	 Y	 ,+Y	 Y	 Y	r!   