
    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	j0                  j2                  dedefdZ ed      	 	 	 	 ddddede	j0                  j2                  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y)    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y)r   namec                     || _         d| | _        g | _        i | _        i | _        i | _        i | _        t        j                  j                  j                         | _	        i | _        i | _        y )Nsubmod_)r   submod_name
node_namesinputsoutputsdependencies
dependentstorchfxgraphGraphenvironmenttargets)selfr   s     V/var/www/html/engine/venv/lib/python3.12/site-packages/torch/fx/passes/split_module.py__init__zPartition.__init__   sc    	$TF+%'')(*-/+-+088>>+?+?+A
-/')    returnc                     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__!   sb    TYYK  ' (} % '((,(9(9': ;&&*oo%68	
r!   N)__name__
__module____qualname__strr    r$    r!   r   r   r      s    
*S 
*
# 
r!   modqualnamer"   c                     | }|j                  d      D ])  }t        ||      st        d| d      t        ||      }+ |S )N.zNode target z not found!)splithasattrAttributeErrorgetattr)r*   r+   attr_valatoms       r   _get_attr_from_qualnamer4   ,   sP    Hs# +x& <z!EFF8T*+ Or!   )partition_affixmroot_msplit_callbackqualname_mapkeep_original_orderkeep_original_node_namekeep_original_input_namer5   c                   2?@ABCDEFGHI t         j                  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 Gi Ei Idt        dt        t           fGIfdHGfd}
t        j                  j                  t        j                  j                  t        j                  j                   g}t#               }t#               }i }d
}t%               } j&                  j(                  D ]  22j*                  j-                  d      x}st/        |t        j0                  t        j2                  f      rIt/        |j4                  j6                  x}|	j8                        r|Ivr2I|j4                  j6                  <   2j:                  dv r |
2       2j:                  dk(  r2j<                  |v r2j<                  t        j                  j                   u rRt?        2j@                        dk(  sJ t/        2j@                  d	   tB              sJ 2}t%         2      h      ||<   n2j<                  t        j                  j                  u rJtE        d 2j@                  D              sJ |jG                  2       t%         2      h      |2<   d
|2<   n2j<                  t        j                  j                  u rqt?        2j@                        dk(  sJ |2j@                  d	      jG                   2             |jI                  2j@                  d	          2|2j@                  d	   <   |||   jG                   2             |D ]  }||   jG                   2               tE        d |jK                         D              sJ d       |jM                         D ci c]  \  }}|tO        |       }}}|jM                         D ci c]  \  }}|tO        |       }}}tP        jS                  tT        jV                        r,tP        j                  d|       tP        j                  d|       tC        |      xs tC        |      }d} j&                  j(                  D ]  22E2jX                  <   2j:                  dv r"2j:                  dk(  r;t        j                  j&                  j[                  2j@                  d	   Hfd       l|r 2      }||k  sJ d| d|        |}2j<                  |vst        j                  j&                  j[                  2j@                  2Hfd       t        j                  j&                  j[                  2j\                  2Hfd        t_        Gja                               }g }GjM                         D ],  \  }Ft?        Fjb                        r|je                  |       . g }|rw|jg                         }|je                  |       G|   jh                  D ]A  }G|   jb                  jg                  |       G|   jb                  r1|je                  |       C |rwt?        |      t?        G      k7  rtk        d       ||fD ]  }|jM                         D ]  \  2} t?        |       d	kD  sJ 2Gt        | d	            jl                  2<   | dd
 D ]  }!Gt        |!         FFj&                  jo                  2j:                  2j<                  tq        d! 2j@                  D              i 2jr                  "      }"2j*                  ju                         |"_        |"Fjl                  2<      |D ]  }G|   Fi Dd	AFjv                  D ]  CEC   }#ACDEFfd#}$|#j:                  d$k(  rt/        |#j<                  t
              sJ ty         |#j<                        }%t/        |%t        jz                  j|                        r?Fj&                  j                  |#j<                        }&|%Fj                  |#j<                  <   n |$       }&n |$       }&EC   j*                  ju                         |&_        |&Fjl                  EC   <    DF_;          j&                  j(                  D ]  2t        2d%      sG2j                     FFjl                  Bt        j                  j&                  j[                  2j@                  Bfd&      }'t        j                  j&                  j[                  2j\                  Bfd'      }(2j:                  d(vr2j<                  })ncty         2j<                        }*2j<                  j                  d)d*      })|*Fj                  |)<   | Fj                   d)|) }+2j<                  ||+<   t/        |'tp              sJ t/        |(t              sJ r2jX                  nd
},Fj&                  jo                  2j:                  |)|'|(2jr                  |,+      }"2j*                  ju                         |"_        |"Fjl                  2<    |fD ]  }t        |      D ]  2|2   } t?        |       d	kD  sJ | d
d D ]  }!Gt        |!         F|2   }-|-J d,       Fj&                  jo                  |-j:                  |-j<                  Fjl                  2   fi |-jr                  "      }"|-j*                  ju                         |"_           i }.i ?t        j                  j&                  j                         @i }/|s) j&                  j(                  D ]  2 |2?|/      \  ?}/ n* j&                  j(                  D ]  22|.2jX                  <    |s|n|}0t%               }1 j&                  j(                  D 2cg c]  }2|2j:                  d-k(  s|2 }3}2|0D ]'  }G|   Ftq        EFfd.Fj                  D              }4t?        |4      }5|5dk(  rFj&                  j                  |4d	          n<|5dkD  rFj&                  j                  |4       nFj&                  j                  d/       |rtFjv                  D 6cg c]  }6|6|3vr|.|6    }7}6|3D ]%  22|1v r |2?|/      \  ?}8|1jG                  2       ' |7D ]%  22|1v r |2?|/      \  ?}/|1jG                  2       ' t        j                  j                  j                  Fj                  Fj&                        |/Fj                  <   @j                  Fj                  tq        ?fd0Fjv                  D                    }9t?        Fj                        }:|:dkD  rZt        j                  j                  j                  |9      };t        Fj                        D ]  \  }<}=|;|<   j4                  ?|=<     |:dk(  s|9?t        t        Fj                              <   * |r*?s( j&                  j(                  D ]  2 |2?|/      \  ?}/  j&                  j(                  D ][  22j:                  dk(  s@j                  t        j                  j&                  j[                  2j@                  d	   ?fd1             ] t        j                  j                  j                  |/@      }>t         j                  dt        d2|>d             |>S c c}}w c c}}w c c}2w c c}6w )3a  
    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                 t   | j                   dk(  r t        | j                        dkD  r| j                  d   nt        j                  j
                  }rX|t        j                  j
                  u rdn|f}j                  d| j                  || j                        || j                  <   n5j                  | j                  | j                  |      || j                  <   | j                  j                         || j                     _        ||fS | j                   dk(  rj                  | j                        || 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   sy   
 77m# #DII 2		!8I8I8O8O  ''7+<+<+B+BBBHX  +9*D*D!II"ii	 +E +TYY' +9*D*DKK"ii"/ +E +TYY'
 ,099>>+;L#( ^++ WW
"&4&=&=dkk&JL#+/99>>+;L#(dkk3///.q$++>H*2N4;;'^++r!   r   Ndef_nodeuse_nodec                    ddl m} t        | dd       }t        |dd       }t        j	                  d| j
                  |||j
                  nd|       ||k7  r||G|   }|j                  j                  | j
                         ||j                  j                  |       |/|   }|j                  j                  | j
                         | j                  j                  d      x}t         ||      t              D ]  }|   }	|j                  j                  |	j
                         |   j                  dk7  s@t        |	dd       }
|
P|
   }|j                  j                  |	j
                         |j                  j                  |       |j                  j                  |
        ||j                  j                  |       y y y y )	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(OT:x$7		8MM%1HMMs	
 d?" *7 3%%00?#!,,77= *4 0$$//>  (}}00AAGN#L$9sC Q!/!2%,,77D)!,//=@ )0(NI(42<Y2G / 7 7 B B6;; O / : : E Ed K - : : E Ei P#Q$ &!..99'B '3   r!   c                 6    |       }t        |      }dj                  |g      }t        j                  d| j                  |       j                  |      }|t        |      x|<   }|j                  j                  | j                         || _	        y )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HN		8$))^	

 NN>2	5>~5NNJ~&##DII.+r!   r[   )rC   rG   outputcall_function   c              3   >   K   | ]  }t        |t                 y wN)rR   r
   .0args     r   	<genexpr>zsplit_module.<locals>.<genexpr>P  s     Jz#t44Js   c              3   $   K   | ]  }|d u 
 y wr{   r)   )r}   vs     r   r   zsplit_module.<locals>.<genexpr>`  s     >q}>s   zautocast must exitz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    (B1d(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    ,FxQU,V r!   c                      |       S r{   r)   r   s    r   r   zsplit_module.<locals>.<lambda>  s    .HSW.X r!   z cycle exists between partitions!c              3       K   | ]  }|  y wr{   r)   r|   s     r   r   zsplit_module.<locals>.<genexpr>  s     8ss8s   )rH   rO   rD   kwargsrE   c                      r} n
d } dz  j                   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  s\    +D "'+DqLG'oo99(o2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 noderC   c              3   B   K   | ]  }j                   |        y wr{   )r   )r}   r   r   ru   s     r   r   zsplit_module.<locals>.<genexpr>@  s&      
8<I!!*T"23
s   r)   c              3   (   K   | ]	  }|     y wr{   r)   )r}   r   r@   s     r   r   zsplit_module.<locals>.<genexpr>n  s     B,t$Bs   c                 "    | j                      S r{   )r   )r   r@   s    r   r   zsplit_module.<locals>.<lambda>  s    |AFF?S r!   zpost split_module)Or^   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itemsrb   _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)Jr6   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kr   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_nodeorig_mod_envrA   construct_order_partitionsalready_constructed_attr_nodesr?   original_orderoutput_valsnum_output_valsr\   orig_mod_attr_nodes_based_mod_attrs
output_valnum_outputsoutput_val_proxyioutput_nameretr@   rS   r   r   r   r   r   ru   rl   rn   rm   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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",/1E0F,G[)		 9 99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JA6!9JJ-9-?-?-ABTQAvayLBL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 3!	9))*"">23
 $&
(,,.  0#N3>> 	2Iy!..22>Bi(55&&y1	2  Z0=>> -l; 7,224 	7MD'w<!###<@Js71:'33D9QR[ 7&s1v.	$??66ww;;8dii88"ii 7  IINN$  /7	%%d+7	77* , &&~.	&(
## 	AC"3I# # ||z)!)"2"2C8883Ay7G7GH	i9"+//":":9;K;K"LK:CI%%i&6&67"1"3K-/)#3388:K5@I!!*S/2?	A@ &	M&&R  $3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ot444 7499TD 2277"&)) 3 H !IINN,HM*2I!!$'I$3N -- _- 	D%d+Gw<!###Sb\ &s1v.	*40	 ,A.AA,$??66 ||$++#//57'nn 7  NN'') 		* %'L$&L+088>>+?+?+ANCENGGMM 	D+:lN,(L.	 GGMM 	+D&*L#	+ "5:R  &)U" ()ww}}Qt=8PdQNQ4 <E~.	  
@I@Q@Q
 

 k*aOO"";q>2q OO"";/ OO""2& %++/n, S!/ / ' 9991@,2.. /22489 , 999/>,0,n /22489 160E0E0Q0Qy1
y,,-
 $//!!B1A1ABB


 )++,?$xx~~33J?"+I,=,="> E;,<Q,?,D,D[)EA:DLd9#4#4567y<ED <GGMM 	D+:lN,(L.	  77h!!&&tyy|5ST ((


+
+NN
KCII2CF J[	 KBj R,/s   9|4%|:>} } >})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 2 -  
'!!!(+ +g d+
 
 ,
0 C C  d+
 .2*/.3%)Y	 &*Y	Y	HHOOY	 dVS[)Y	 4S>*	Y	
 "$Y	 &d^Y	 #Y	 c]Y	 ,Y	r!   