
    Vh,                        d dl Z d dlmZ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mZ ddlmZ g d	Z e
d
      d        Z e
d
      d        Z e
d
      e G d d                    Z e
d
      d
d
ej,                  j.                  fdej,                  j.                  dee   dededeej,                  j.                     deej,                  j.                  eej,                  j.                  eeef   f   f   fd       Zy)    N)	dataclassfield)OptionalUnion)compatibility)map_arg)HolderModulelift_subgraph_as_module   )NodeList)getattr_recursivesetattr_recursive	Componentsplit_by_tagsF)is_backward_compatiblec                 f    |j                  d      D ]  }t        | |      rt        | |      }  y  | S )N.)splithasattrgetattr)objnamelayers      K/home/dcms/DCMS/lib/python3.12/site-packages/torch/fx/passes/split_utils.pyr   r      s9    C 3#u%C	
 J    c                     d|vrt        | ||       y |j                  d      }t        t        | |d         dj	                  |dd        |       y )Nr   r   r   )setattrr   r   r   join)r   attrvaluer   s       r   r   r      sH    
$T5!

3'#uQx0#((592EuMr   c                      e Zd ZU dZej
                  j                  ed<   eed<   e	ed<    e
e      Zeed<    e
e      Zeed<    e
e      Zeed<    e
e      Zeej
                  j"                  ej
                  j"                  f   ed	<    e
e      Zee	   ed
<   dZeej
                  j*                     ed<   y)r   zX
    A component serves as a container for a subgraph we want to create afterwards.
    graphorderr   )default_factoryinput_placeholdersorig_inputsorig_outputsgetattr_mapsconstructor_argsNgm)__name__
__module____qualname____doc__torchfxGraph__annotations__intstrr   listr%   r&   r'   dictr(   Noder)   r*   r   GraphModule r   r   r   r   $   s     88>>J
I  %T:: d3K3 t4L$4 8=T7RL$uxx}}ehhmm34R"'"=d3i=)-B%%&-r   r   r*   tagsreturn_fqn_mappingreturn_tupleGraphModuleClsreturnc           
      
   dt         j                  j                  j                  dt        fd}i i i }g }i t         j                  j                         }i }	d}
|D ]K  }t        t         j                  j                         t        |      |       |j                         ||<   M | j                  j                  D ]  }|j                  dk(  r|
t        d      |}
#|j                  dk(  rR|j                  |j                  |j                        |	|<   t!        j                   |j"                        |	|   _        |j                  d	k(  rt%        |d
      sJ d|j'                                  ||j(                         ||j*                        z   D cg c]  }|j                  dvr|    }}||j,                     |<   t/        d |D        d      }j0                  |k\  s$J dj                   dj0                   d|        fd}j                  j3                  ||      }|j,                  |_        ||<   |<    |
t        d       ||
j(                  d         D ]A  }|j                  d	k(  r+|j5                  |j                  |j                        |	|<   =d|<   C D ]0  }|j                  dk7  s|   j6                  j                  |       2 i }|D ]h  t9        t;        j<                  j6                              }|rj                  j?                  |       n.j                  j?                  t        |      dk(  r|d   n|       tA        | j                  j                        \  _!        }|jE                  |       |jG                  j                  t9        t;        |	j<                  jH                              d      }t        |      dk(  r|s||	j6                  d   <   tK        j6                        D ]4  \  }}t         j                  jM                  |      |   j                  |	|<   6 k |j?                  tO        |
j(                  d   |	j<                               tQ        |D ci c]  }|j                  |jB                   c}      }| j                  jR                  |_)         ||
j(                  d         D ]=  }|j                  d	k(  stU        ||j                  tW        | |jX                               ?  |||      }|r||fS |S c c}w c c}w )a9  
    Splits a GraphModule using tags on its graph nodes. We honor the order of
    tags. For example, we have tags = ["a", "b", "c"], the function will create
    the initial submodules in the order of "a", "b", "c".

    To set a tag:
    gm.graph.nodes[idx].tag = "mytag"

    This will result in all nodes with the same tag being extracted and placed in their
    own submodule. For placeholder, output and get_attr node, the tag is ignored. placeholder
    and output nodes are created when needed while get_attr nodes get copied to submodules
    where they are used.

    Given the following module def:

    class SimpleModule(torch.nn.Module):
        def __init__(self) -> None:
            super().__init__()
            self.linear1 = torch.nn.Linear(...)
            self.linear2 = torch.nn.Linear(...)
            self.linear3 = torch.nn.Linear(...)

        def forward(self, in1, in2):
            r1 = self.linear1(in1)
            r2 = self.linear2(in2)
            r3 = torch.cat([r1, r2])
            return self.linear3(r3)

    Marking the node corresponding to in1 with the tag sc.REQUEST_ONLY.lower() results in the following split:

    ro:
    def forward(self, in1):
        self = self.root
        linear1 = self.linear1(in1)
        return linear1

    main:
    def forward(self, in2, linear1):
        self = self.root
        linear2 = self.linear2(in2)
        cat_1 = torch.cat([linear1, linear2])
        linear3 = self.linear3(cat_1)
        return linear3

    main:
    def forward(self, in1, in2):
        self = self.root
        ro_0 = self.ro_0(in1)
        main_1 = self.main_1(in2, ro_0)
        return main_1

    Returns:
        split_gm: torch fx graph after split
        orig_to_split_fqn_mapping: a map between the original fqn and the fqn
            after split for call_module and get_attr.
    xr>   c                 6    g }t        | |j                         |S )zC
        Stores nodes in x to a list and returns the list.
        )r   append)r@   rs     r   flattenzsplit_by_tags.<locals>.flatten   s     188r   NoutputzMultiple output nodes in graph!placeholder	type_exprget_attrtagzNode does not have tag: >   rI   rF   c              3   4   K   | ]  }|j                     y w)N)r#   ).0cs     r   	<genexpr>z split_by_tags.<locals>.<genexpr>   s     7a!''7s   r   )defaultz
Component z8 order must be >= max of its upstream components, order=z	 and max=c                    | j                   dk(  r| j                  vroj                  j                  | j                  | j
                        j                  | <   t        j                  | j                        j                  |    _        j                  |    S | j                   dk7  r|    k(  r|    S | j                  vrj                  j                  |        j                  j                  | j                  | j
                        }t        j                  | j                        |_        j                  j                  |       d | <   j                  j                  j                  |          S )NrI   rG   rF   )opr(   r"   rI   targettypecopymetar&   rB   rF   r   r%   index)r@   rF   compnode_remappingnode_to_componentused_in_mains     r   
remap_funcz!split_by_tags.<locals>.remap_func   sB    ttz!D---+/::+>+>AFF ,? ,D%%a( 15		!&&0AD%%a(-((++
 tt}$):1)=)E%a(( (((  ''*"jj44QVVqvv4N#'99QVV#4 ''..{;"&Q**4+;+;+A+A!+DEEr   zGraph had no output node!r   )subgraph	comp_name)argskwargs)-r/   r0   nodeArgumentr   r1   r   lenrB   r"   nodesrQ   RuntimeErrorrF   r   rS   rT   rU   r   format_noder^   r_   rJ   maxr#   	node_copyrI   r'   tuplemap__getitem__rE   r
   r*   updatecall_moduler&   	enumerateProxyr   r	   _codegenr   r   rR   )r*   r:   r;   r<   r=   rD   tag_to_componentall_componentsmain_gmain_remappingoutput_noderJ   r`   r@   upstream_componentsmxr[   norig_to_split_fqn_mappingoutscomp_orig_to_split_fqn_mapping	main_nodeiorW   	main_root	result_gmrX   rY   rZ   s                           `  @@@r   r   r   >   s0   B588==)) h  :<N 9; .0 ')N /1L XX^^F :<N ,0K  %)3~+>3%Id# $%  G$77h&"#DEEK 77m##)#5#5dii499#5#UN4 (,		$))(<N4 % 77j  tU#T'?@P@P@R?S%TT# TYY''$++*>>
tt66 a 
 
  )"&$ 7#67C JJ"	u		{"Z[_[e[eZffoprost	u	F8 JJ  z2 t#!OG$R 677[%%a() 	#44: !'!&& IN1 #LO	#  844= a --44Q78
 13 FS33T5F5FGHJJd# JJTad1gTB2Ityy3
// 	"(()GH &&IIs>55t7G7GHI ' 
	 t9>,3<N4,,Q/0!$"3"34 F1$)HHNN9$=a$@$E$Eq!F7F> MM'+**1-~/I/IJK^LTdii0LMIhh''FO [%%a() H44:Iqvv'8QXX'FGH y&1I333m
R Ms   $U	#U)rT   dataclassesr   r   typingr   r   torch.fxr/   torch.fx._compatibilityr   torch.fx.graphr   torch.fx.passes.utilsr	   r
   tools_commonr   __all__r   r   r   r0   r8   r5   r4   boolrS   rh   r6   r   r9   r   r   <module>r      s:    ( "  1 " G " S e, - e,N -N e,
. .  -.0 e,  %161E1Ett
s)t t 	t
 --.t 588uxx';';T#s(^'K!LLMt -tr   