
    Ph=,                        d dl Z d dlmZmZ d dlmZmZmZmZ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
ej4                  j6                  fdej4                  j6                  dee   dede	ej4                  j6                     de
ej4                  j6                  eej4                  j6                  eeef   f   f   f
d       Zy)    N)	dataclassfield)DictListOptionalTupleType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      fC:\Users\daisl\Desktop\realtime-object-detection\venv\Lib\site-packages\torch/fx/passes/split_utils.pyr   r      s4    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*   r+   dictr,   r   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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  ||j&                         ||j(                        z   D cg c]  }|j                  dvr|    }}||j*                     |<   t-        d |D        d      }j.                  |k\  sJ fd}j                  j1                  ||      }|j*                  |_        ||<   |<   _ |	t        d       ||	j&                  d         D ]A  }|j                  d	k(  r+|j3                  |j                  |j                        ||<   =d|<   C D ]0  }|j                  dk7  s|   j4                  j                  |       2 i }|D ]G  t7        t9        j:                  j4                              }j                  j=                  t        |      dk(  r|d   n|       t?        | j                  j                        \  _         }|jC                  |       |jE                  j                  t7        t9        |j:                  jF                              d      }t        |      dk(  r||j4                  d   <   tI        j4                        D ]4  \  }}t         j                  jK                  |      |   j                  ||<   6 J |j=                  tM        |	j&                  d   |j:                               tO        |D ci c]  }|j                  |j@                   c}      } ||	j&                  d         D ]=  }|j                  d	k(  stQ        ||j                  tS        | |jT                               ?  |||      }|r||fS |S c c}w c c}w )a1  
    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):
            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.
    xrA   c                 6    g }t        | |j                         |S )zC
        Stores nodes in x to a list and returns the list.
        )r   append)rC   rs     r   flattenzsplit_by_tags.<locals>.flatten|   s     188r   NoutputzMultiple output nodes in graph!placeholder	type_exprget_attrtag>   rL   rI   c              3   4   K   | ]  }|j                     y w)N)r'   ).0cs     r   	<genexpr>z split_by_tags.<locals>.<genexpr>   s     7#6a!''#6s   r   )defaultc                    | j                   dk(  r[| j                  vr>j                  j                  | 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 )NrL   rJ   rI   )opr,   r&   rL   targettyper*   rE   rI   r   copymetar)   index)rC   rI   compnode_remappingnode_to_componentused_in_mains     r   
remap_funcz!split_by_tags.<locals>.remap_func   s"    ttz!D---+/::+>+>AFF ,? ,D%%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)+r3   r4   nodeArgumentr   r5   r   lenrE   r&   nodesrT   RuntimeErrorrI   r   rV   rW   rX   r   ra   rb   rM   maxr'   	node_copyrL   r+   tuplemap__getitem__rH   r   r.   updatecall_moduler*   	enumerateProxyr   r   r!   r   rU   )r.   r>   r?   r@   rG   tag_to_componentall_componentsmain_gmain_remappingoutput_noderM   rc   rC   upstream_componentsmxr^   norig_to_split_fqn_mappingoutscomp_orig_to_split_fqn_mapping	main_nodeiorZ   	main_root	result_gmr[   r\   r]   s                          `  @@@r   r   r   <   s   @588==)) h  :<N 9; .0 ')N /1L XX^^F :<N ,0K )3~+>3%Id# $  77h&"#DEEK 77m##)#5#5dii499#5#UN4 (,		$))(<N4 % 77j  tU### TYY''$++*>>
>tt66 a > 	 
  )"&$ 7#67C zzR	F6 JJ  z2 t#!I L 677[%%a()44: !'!&& IN1 #LO * 44= a --44Q7 
 13S33T5F5FGH 	

SY!^$q'>2Ityy3
// 	"(()GH &&IIs>55t7G7GHI ' 
	 t9>3<N4,,Q/0!$"3"341$)HHNN9$=a$@$E$Eq! 51 8 MM'+**1-~/I/IJK^L^Tdii0^LMI [%%a()44:Iqvv'8QXX'FG * y&1I333_
F Ms   S
S)rW   dataclassesr   r   typingr   r   r   r   r	   r
   torch.fxr3   torch.fx._compatibilityr   torch.fx.graphr   torch.fx.passes.utilsr   r   tools_commonr   __all__r   r   r   r4   r<   r8   boolr   r=   r   r   <module>r      s,    ( ; ;  1 " G "
R e, - e,N -N e,
. .  -.0 e,  %161E1E	ll
s)l l --.	l
 588uxx';';T#s(^'K!LLMl -lr   