
    ȅil                        S SK r S SKrS SKJr  S SKJr  S SKJrJr  S SK	r	S SK
Jr  S SKJr  S SKJr  S SKJr  S	S
/r\R&                  " \5      =rr\" SS9 " S S	5      5       rS\	R0                  R2                  S\S\4S jr\" SS9    SSS.S\S\	R0                  R2                  S\\/\4   S\\\\4      S\\   S\\   S\S\\   4S jjj5       rg)    N)OrderedDict)Callable)AnyOptional)compatibility)lazy_format_graph_code)GraphModule)Node	Partitionsplit_moduleT)is_backward_compatiblec                   0    \ rS rSrS\4S jrS\4S jrSrg)r      namec                     Xl         SU 3U l        / U l        0 U l        0 U l        0 U l        0 U l        [        R                  R                  R                  5       U l	        0 U l        0 U l        g )Nsubmod_)r   submod_name
node_namesinputsoutputsdependencies
dependentstorchfxgraphGraphenvironmenttargets)selfr   s     V/home/james-whalen/.local/lib/python3.13/site-packages/torch/fx/passes/split_module.py__init__Partition.__init__   sa    	$TF+%'')(*-/+-+088>>+?+?+A
-/')    returnc                     SU R                    SU R                   SU R                   SU R                   SU R                   SU R
                   3$ )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__Partition.__repr__!   sb    TYYK  ' (} % '((,(9(9': ;&&*oo%68	
r#   )
r   r   r   r   r   r   r   r   r   r   N)__name__
__module____qualname____firstlineno__strr!   r&   __static_attributes__ r#   r    r   r      s    
*S 
*
# 
r#   modqualnamer$   c                     U nUR                  S5       H-  n[        X#5      (       d  [        SU S35      e[        X#5      nM/     U$ )N.zNode target z not found!)splithasattrAttributeErrorgetattr)r/   r0   attr_valatoms       r    _get_attr_from_qualnamer9   ,   sJ    Hs#x&& <z!EFF8* $ Or#   )partition_affixmroot_msplit_callbackqualname_mapkeep_original_orderkeep_original_node_namekeep_original_input_namer:   c                V   ^ ^^^^^2^?^@^A^B^C^D^E^F^G^H^I [         R                  S[        ST SS95        S[        S[        [
        [        4   S[        [
        [        R                  R                  R                  4   4U@UU 4S jjnS	S
K
n	0 mG0 mE0 mIS[        S[        [           4UGUI4S jjmHUUGU4S jn
[        R                  R                  [        R                  R                  [        R                  R                   /n[#        5       n[#        5       n0 nS
n[%        5       nT R&                  R(                   GH  m2T2R*                  R-                  S5      =nb  [/        U[        R0                  [        R2                  45      (       aP  [/        UR4                  R6                  =nU	R8                  5      (       a  UTI;  a  T2TIUR4                  R6                  '   T2R:                  S;   a  M  U
" T25        T2R:                  S:X  Ga  T2R<                  U;   Ga  T2R<                  [        R                  R                   L aW  [?        T2R@                  5      S:X  d   e[/        T2R@                  S	   [B        5      (       d   eT2n[%        T" T25      15      X'   GOT2R<                  [        R                  R                  L aO  [E        S T2R@                   5       5      (       d   eURG                  T25        [%        T" T25      15      UT2'   S
UT2'   OT2R<                  [        R                  R                  L ar  [?        T2R@                  5      S:X  d   eUT2R@                  S	      RG                  T" T25      5        URI                  T2R@                  S	   5        T2UT2R@                  S	   '   Ub  X   RG                  T" T25      5        U H  nUU   RG                  T" T25      5        M     GM     [E        S URK                  5        5       5      (       d   S5       eURM                  5        VVs0 s H  u  nnU[O        U5      _M     nnnURM                  5        VVs0 s H  u  nnU[O        U5      _M     nnn[P        RS                  [T        RV                  5      (       a,  [P        R                  SU5        [P        R                  SU5        [C        U5      =(       d    [C        U5      nSnT R&                  R(                   GH  m2T2TET2RX                  '   T2R:                  S;   a  M%  T2R:                  S:X  a=  [        R                  R&                  R[                  T2R@                  S	   UH4S j5        Mr  U(       a  T" T25      nUU::  d   SU SU 35       eUnT2R<                  U;  d  M  [        R                  R&                  R[                  T2R@                  U2UH4S j5        [        R                  R&                  R[                  T2R\                  U2UH4S j5        GM     [_        TGRa                  5       5      n/ nTGRM                  5        H3  u  nmF[?        TFRb                  5      (       a  M"  URe                  U5        M5     / nU(       a  URg                  5       nURe                  U5        TGU   Rh                   HH  nTGU   Rb                  Rg                  U5        TGU   Rb                  (       a  M7  URe                  U5        MJ     U(       a  M  [?        U5      [?        TG5      :w  a  [k        S 5      eX4 H  nURM                  5        H  u  m2n [?        U 5      S	:  d   eT2TG[        U S	   5         Rl                  T2'   U SS
  H  n!TG[        U!5         mFTFR&                  Ro                  T2R:                  T2R<                  [q        S! T2R@                   5       5      0 T2Rr                  S"9n"T2R*                  Ru                  5       U"l        U"TFRl                  T2'   M     M     M     U GH+  nTGU   mF0 mDS	mATFRv                   GH  mCTETC   n#UAUCUUDUEUF4S# jn$U#R:                  S$:X  a  [/        U#R<                  [
        5      (       d   e[y        T U#R<                  5      n%[/        U%[        Rz                  R|                  5      (       a?  TFR&                  R                  U#R<                  5      n&U%TFR                  U#R<                  '   OU$" 5       n&OU$" 5       n&TETC   R*                  Ru                  5       U&l        U&TFRl                  TETC   '   GM	     TDTFl;        GM.     T R&                  R(                   GH  m2[        T2S%5      (       d  M  TGT2R                     mFTFRl                  mB[        R                  R&                  R[                  T2R@                  UB4S& j5      n'[        R                  R&                  R[                  T2R\                  UB4S' j5      n(T2R:                  S(;  a  T2R<                  n)Od[y        T T2R<                  5      n*T2R<                  R                  S)S*5      n)U*TFR                  U)'   Ub   TFR                   S)U) 3n+T2R<                  UU+'   [/        U'[p        5      (       d   e[/        U([        5      (       d   eT(       a  T2RX                  OS
n,TFR&                  Ro                  T2R:                  U)U'U(T2Rr                  U,S+9n"T2R*                  Ru                  5       U"l        U"TFRl                  T2'   GM     U4 H  n[        U5       H  m2UT2   n [?        U 5      S	:  d   eU S
S  H  n!TG[        U!5         mFUT2   n-U-c   S,5       eTFR&                  Ro                  U-R:                  U-R<                  TFRl                  T2   40 U-Rr                  S"9n"U-R*                  Ru                  5       U"l        M     M     M     0 n.0 m?[        R                  R&                  R                  5       m@0 n/U(       d+  T R&                  R(                   H  m2U" T2T?U/5      u  m?n/M     O,T R&                  R(                   H  m2T2U.T2RX                  '   M     U(       d  UOUn0[%        5       n1T R&                  R(                   V2s/ s H  n2U2R:                  S-:X  d  M  U2PM     n3n2U0 GHH  nTGU   mF[q        UEUF4S. jTFR                   5       5      n4[?        U45      n5U5S:X  a  TFR&                  R                  U4S	   5        O=U5S:  a  TFR&                  R                  U45        OTFR&                  R                  S/5        U(       a  TFRv                   V6s/ s H  n6U6U3;  d  M  U.U6   PM     n7n6U3 H)  m2T2U1;   a  M  U" T2T?U/5      u  m?n8U1RG                  T25        M+     U7 H)  m2T2U1;   a  M  U" T2T?U/5      u  m?n/U1RG                  T25        M+     [        R                  R                  R                  TFR                  TFR&                  5      U/TFR                  '   T@R                  TFR                  [q        U?4S0 jTFRv                   5       5      5      n9[?        TFR                  5      n:U:S:  a]  [        R                  R                  R                  U95      n;[        TFR                  5       H  u  n<n=U;U<   R4                  T?U='   M     GM  U:S:X  d  GM'  U9T?[        [        TFR                  5      5      '   GMK     U(       a1  T?(       d*  T R&                  R(                   H  m2U" T2T?U/5      u  m?n/M     T R&                  R(                   H_  m2T2R:                  S:X  d  M  T@R                  [        R                  R&                  R[                  T2R@                  S	   U?4S1 j5      5        Ma     [        R                  R                  R                  U/T@5      n>[         R                  S[        S2U>SS95        U>$ s  snnf s  snnf s  sn2f s  sn6f )3aM  
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                 r  > U R                   S:X  a  [        U R                  5      S:  a  U R                  S   O[        R                  R
                  nT(       aU  U[        R                  R
                  L a  SOU4nTR                  SU R                  UU R                  S9XR                  '   O1TR                  U R                  U R                  US9XR                  '   U R                  R                  5       XR                     l        X4$ U R                   S:X  a  TR                  U R                  5      XR                  '   U R                  R                  5       XR                     l        [        U R                  [        5      (       d   e[!        TU R                  5      nXRU R                  '   X4$ )Nplaceholderr   r.   )args	type_expr)rJ   default_valueget_attr)oplenrI   inspect	Signatureemptycreate_noder   typerH   targetmetacopyrL   
isinstancer,   r9   )	rD   rE   rF   rK   rI   r7   base_mod_graphr@   r;   s	         r    construct_graph%split_module.<locals>.construct_graph   sl   
 77m# #DII 2		!8I8I8O8O  ''7+<+<+B+BBBHX  +9*D*D!II"ii	 +E +YY' +9*D*DKK"ii"/ +E +YY'
 ,099>>+;L#( ++ WW
"&4&=&=dkk&JL#+/99>>+;L#(dkk3////.q$++>H*24;;'++r#   r   Ndef_nodeuse_nodec                   > SSK Jn  [        U SS 5      n[        USS 5      n[        R	                  SU R
                  UUb  UR
                  OSU5        X4:w  Ga  UbH  TU   nUR                  R                  U R
                  5        Ub  UR                  R                  U5        UGb4  TU   nUR                  R                  U R
                  5        U R                  R                  S5      =nb  [        U" U5      [        S9 H  nTU   n	UR                  R                  U	R
                  5        TU   R                  S:w  d  MB  [        U	SS 5      n
U
c  MT  TU
   nUR                  R                  U	R
                  5        UR                  R                  U5        UR                  R                  U
5        M     Ub  UR                  R                  U5        g g g g )	Nr   )free_symbols_fx_partitionz*record_cross_partition_use %s (%s) %s (%s)-example_value)keyrH   )%torch.fx.experimental.symbolic_shapesr^   r6   logdebugr   r   
setdefaultr   r   rU   getsortedr,   rM   r   )r[   r\   r^   defineduseddef_partitionuse_partitiondef_valss_node	s_defineds_def_partition
partitionssymbol_to_nodes               r    record_cross_partition_use0split_module.<locals>.record_cross_partition_use   s   F(OT:x$7		8MM%1HMMs	
 ?" *7 3%%00?#!,,77= *4 0$$//>  (}}00AAGN#L$9sC!/!2%,,77D)!,//=@ )0(NI(42<Y2G / 7 7 B B6;; O / : : E Ed K - : : E Ei P# D$ &!..99'B '3   r#   c                 8  > T" U 5      n[        U5      nTb  SR                  TU/5      n[        R                  SU R                  U5        TR                  U5      nUc  [        U5      =TU'   nUR                  R                  U R                  5        X l	        g )N_z*instantiate_node_partition_mapping %s (%s))
r,   joinrd   re   r   rg   r   r   appendr_   )rD   partition_idxpartition_name	partitionr:   rr   r=   s       r    "instantiate_node_partition_mapping8split_module.<locals>.instantiate_node_partition_mapping  s    &t,]+& !XX&GHN		8$))^	

 NN>2	5>~5NNJ~&##DII.+r#   ra   )rH   rL   outputcall_function   c              3   L   #    U  H  n[        U[        5      (       + v   M     g 7fN)rW   r
   .0args     r    	<genexpr>split_module.<locals>.<genexpr>P  s     J	z#t444	s   "$c              3   (   #    U  H  oS Lv   M
     g 7fr   r.   )r   vs     r    r   r   `  s     >&=}&=s   zautocast must exitzautocast_regions: %szgrad_regions: %s)rH   rL   r   c                    > T" U S 5      $ r   r.   )nrt   s    r    <lambda>split_module.<locals>.<lambda>x  s    (B1d(Kr#   zRautocast or set_grad_enabled require monotonically increasing partitions:highest: z, this node's: c                    > T" U T5      $ r   r.   r[   rD   rt   s    r    r   r     s    ,FxQU,Vr#   c                    > T" U T5      $ r   r.   r   s    r    r   r     s    .HSW.Xr#   z cycle exists between partitions!c              3   $   #    U  H  ov   M     g 7fr   r.   r   s     r    r   r     s     8issis   )rM   rT   rI   kwargsrJ   c                     > T(       a  Tn O
ST 3n TS-  mTR                   R                  U TT   R                  S9nS TT'   U$ )Narg_r   )rJ   )r   rH   rS   )r   rH   counterinprA   
new_inputs
orig_nodesr|   s     r    add_placeholder%split_module.<locals>.add_placeholder  s\    +D "'+DqLG'oo99(o22 :  #'
3""r#   rL   r_   c                    > TU    $ r   r.   r   r   s    r    r   r     s
    TUr#   c                    > TU    $ r   r.   r   s    r    r   r     s	    {1~r#   )call_modulerL   r2   rw   )rM   rT   rI   r   rJ   r   zMissing exit noderH   c              3   H   >#    U  H  nTR                   TU      v   M     g 7fr   )r   )r   r   r   r|   s     r    r   r   A  s%      
@QI!!*T"23@Qs   "r.   c              3   .   >#    U  H
  nTU   v   M     g 7fr   r.   )r   r   rE   s     r    r   r   o  s     B1A,t$1As   c                 "   > TU R                      $ r   )r   )r   rE   s    r    r   r     s    |AFF?Sr#   zpost split_module)Ord   re   r   r
   dictr,   r   r   graph_moduler	   sympyr   amp_enter_autocast_exit_autocast_C_set_grad_enabledr   setr   nodesrU   rg   rW   SymIntSymFloatrD   exprSymbolrM   rT   rN   rI   boolalladdremovevaluesitemsrh   _LOGGERisEnabledForloggingDEBUGr   map_argr   listkeysr   ry   popr   RuntimeErrorr   rR   tuplerS   rV   r   r9   nnModulerL   r   r4   r_   replacer   reversedr   r   r   r   proxyProxy	enumeratenextiter)Jr;   r<   r=   r>   r?   r@   rA   r:   rY   r   r}   GLOBAL_STATE_NODESgrad_regionsautocast_regionsautocast_exitsactive_gradactive_autocastsvals0akr   assert_monotonically_increasinghighest_partitionpidoriginal_partition_orderroot_partitionsr{   sorted_partitionsroot_partition	dependentregions_mappingregionsrnew_node	orig_noder   	orig_attrrH   gathered_argsgathered_kwargsrT   target_attrr0   r   	exit_nodeorig_mod_envrF   construct_order_partitionsalready_constructed_attr_nodesrD   original_orderoutput_valsnum_output_valsrb   orig_mod_attr_nodes_based_mod_attrs
output_valnum_outputsoutput_val_proxyioutput_nameretrE   rX   r   r   r   r   r   r|   rr   rt   rs   sJ   ` `  ```                                          `            @@@@@@@@@@@r    r   r   6   s   ` II11dC
 , ,39o , S%(("7"7"C"CCD ,  ,D ')J"$J/1N/CT /CXd^ /C /Cb,. 			!!		  "" 1<L 5@M13NKu IIMM/22S?3u~~ >??.2==.(,0N388==)77;;*4077o%$++9K*K{{ehh888499~***!$))A,5555",/1E0F,G)		 9 99J		JJJJJ $$T*),nT.B-C)D &'+t$		 8 88499~*** 1.22>$3GH ''		!5/3tyy|,"%)).*>?!AQ##N4$89 "U Z >n&;&;&=>>>T@TT> 2B1G1G1IJ1IA6!91IJ-9-?-?-AB-ATQAvayL-ALBGMM**,.>?(,7&*+;&<&R\@R#  $
499 771177hHHNN""		!K * &C$+ -.ocUD+ !$ ;;00HHNN""		V HHNN""X7 >  $JOO$56!#O%/%5%5%7!	9))**"">2 &8
 $&
(,,.  0#N3>>Iy!..22>Bi(555&&y1 ? / Z0=>> -;,224MD'w<!###<@Js71:'33D9 QR[&s1v.	$??66ww;;8dii88"ii 7  IINN$  /7	%%d+ ! 5 <, ,~.	&(
##C"3I# # ||z)!)"2"2C88883Ay7G7GH	i99"+//":":9;K;K"LK:CI%%i&6&67"1"3K-/)#3388:K5@I!!*S/2? $@ &	M ,R 4))"4#5#56I $//K!HHNN22499>VWM#hhnn445O ww995aE,,S#6,7	!!&)+ #,"7"7!8&BH-1[[L*mU3333ot4444 7499TD 2277"&)) 3 H !IINN,HM*2I!!$'I N --_-D%d+Gw<!###Sb\&s1v.	*40	 ,A.AA,$??66 ||$++#//57'nn 7  NN'')  "	 . .* %'L$&L+088>>+?+?+ANCENGGMMD+:lN,(L. " GGMMD&*L# " "5:R  &)U" ()ww}}Q}t=8Pd}NQ4~.	  
@I@Q@Q
 

 k*aOO"";q>2q OO"";/ OO""2& %++/+Cn, "S!+   / '991@,2.. /2248 ' ,99/>,0,n /2248 , 160E0E0Q0Qy1
y,,-
 $//!!B1A1ABB


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