§
    Ÿ²Åj$-  ã                   ó  — 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
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dS )é    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                 ó|   — |                      d¦  «        D ]%}t          | |¦  «        rt          | |¦  «        } Œ# d S | S )Nú.)ÚsplitÚhasattrÚgetattr)ÚobjÚnameÚlayers      úLC:\Projects\Historical\venv\Lib\site-packages\torch/fx/passes/split_utils.pyr   r      sJ   € à—’˜C‘”ð ð ˆÝ�3˜ÑÔð 	Ý˜#˜uÑ%Ô%ˆCˆCà�4�4Ø€Jó    c                 óÞ   — d|vrt          | ||¦  «         d S |                     d¦  «        }t          t          | |d         ¦  «        d                     |dd …         ¦  «        |¦  «         d S )Nr   r   r   )Úsetattrr   r   r   Újoin)r   ÚattrÚvaluer   s       r   r   r      sl   € à
�$€€Ý��T˜5Ñ!Ô!Ð!Ð!Ð!à—
’
˜3‘”ˆÝ�' # u¨Q¤xÑ0Ô0°#·(²(¸5ÀÀÀ¼9Ñ2EÔ2EÀuÑMÔMÐMÐMÐMr   c                   ób  — 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<   dS )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  € € € € € € ðð ð Œ8Œ>ÐÐÑØ€J€J�JØ
€I€I�Ið  %˜u°TÐ:Ñ:Ô:Ð˜Ð:Ð:Ñ:ð ˜¨dÐ3Ñ3Ô3€K�Ð3Ð3Ñ3ð ˜¨tÐ4Ñ4Ô4€L�$Ð4Ð4Ñ4ð 8=°uÈTÐ7RÑ7RÔ7R€L�$�u”x”} e¤h¤mÐ3Ô4ÐRÐRÑRØ"' %¸Ð"=Ñ"=Ô"=Ð�d˜3”iÐ=Ð=Ñ=Ø)-€Bˆ�”Ô%Ô&Ð-Ð-Ñ-Ð-Ð-r   r   r.   ÚtagsÚreturn_fqn_mappingÚreturn_tupleÚGraphModuleClsÚreturnc           
      óL	  ‡‡‡‡— dt           j        j        j        dt          fd„}i Ši Ši }g }i Št           j                             ¦   «         }i }	d}
|D ]W}t          t           j                             ¦   «         t          |¦  «        |› ¦  «        Š|                     ‰¦  «         ‰||<   ŒX| j	        j
        D �]4}|j        dk    r|
�t          d¦  «        ‚|}
Œ"|j        dk    rI|                     |j        |j        ¬¦  «        |	|<   t!          j        |j        ¦  «        |	|         _        Œv|j        d	k    rŒ‚t%          |d
¦  «        sJ ‚ˆfd„ ||j        ¦  «         ||j        ¦  «        z   D ¦   «         }||j                 Š‰‰|<   t-          d„ |D ¦   «         d¬¦  «        }‰j        |k    sJ ‚ˆˆˆˆfd„}‰j	                             ||¦  «        }|j        |_        |‰|<   ‰‰|<   �Œ6|
€t          d¦  «        ‚ ||
j        d         ¦  «        D ]7}|j        d	k    r%|                     |j        |j        ¬¦  «        |	|<   Œ2d‰|<   Œ8‰D ]-}|j        dk    r ‰|         j                             |¦  «         Œ.i }|D �]eŠt7          t9          ‰j        ‰j        ¦  «        ¦  «        }|r‰j	                             |¦  «         n5‰j	                             t          |¦  «        dk    r|d         n|¦  «         t?          | ‰j	        ‰j        ¬¦  «        \  ‰_         }| !                    |¦  «         | "                    ‰j        t7          t9          |	j        ‰j#        ¦  «        ¦  «        d¬¦  «        }t          |¦  «        dk    r|s||	‰j        d         <   �ŒtI          ‰j        ¦  «        D ]2\  }}t           j         %                    |¦  «        |         j        |	|<   Œ3�Œg|                     tM          |
j        d         |	j        ¦  «        ¦  «         tO          d„ |D ¦   «         ¦  «        }| j	        j(        |_(         ||
j        d         ¦  «        D ]6}|j        d	k    r)tS          ||j        tU          | |j+        ¦  «        ¦  «         Œ7 |||¦  «        }|r||fS |S )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.
    ÚxrB   c                 ó4   — g }t          | |j        ¦  «         |S )zC
        Stores nodes in x to a list and returns the list.
        )r   Úappend)rD   Úrs     r   Úflattenzsplit_by_tags.<locals>.flatten   s    € ð ˆÝ��1”8ÑÔÐØˆr   NÚoutputzMultiple output nodes in graph!Úplaceholder©Ú	type_exprÚget_attrÚtagc                 ó2   •— g | ]}|j         d v¯‰|         ‘ŒS )>   rM   rJ   )Úop)Ú.0rD   Únode_to_components     €r   ú
<listcomp>z!split_by_tags.<locals>.<listcomp>½   s6   ø€ ð 
ð 
ð 
àØŒtÐ6Ð6Ð6ð ˜aÔ à6Ð6Ð6r   c              3   ó$   K  — | ]}|j         V — Œd S )N)r'   )rQ   Úcs     r   ú	<genexpr>z split_by_tags.<locals>.<genexpr>Ç   s$   è è € Ð7Ð7˜a�!”'Ð7Ð7Ð7Ð7Ð7Ð7r   r   )Údefaultc                 ó6  •— | j         dk    rD| ‰j        vr.‰j                             | j        | j        ¬¦  «        ‰j        | <   ‰j        |          S | j         dk    r‰|          ‰k    r‰|          S | ‰j        vr}‰j                             | ¦  «         ‰j                             | j	        | j        ¬¦  «        }t          j
        | j        ¦  «        |_        ‰j                             |¦  «         d ‰| <   ‰j        ‰j                             | ¦  «                 S )NrM   rK   rJ   )rP   r,   r&   rM   ÚtargetÚtyper*   rF   rJ   r   ÚcopyÚmetar)   Úindex)rD   rJ   ÚcompÚnode_remappingrR   Úused_in_mains     €€€€r   Ú
remap_funcz!split_by_tags.<locals>.remap_funcÍ   s  ø€ ð Œt�zÒ!Ð!Ø˜DÔ-Ð-Ð-Ø+/¬:×+>Ò+>Øœ¨A¬Fð ,?ñ ,ô ,�DÔ% aÑ(ð Ô(¨Ô+Ð+ð
 Œt�}Ò$Ð$Ð):¸1Ô)=ÀÒ)EÐ)EØ% aÔ(Ð(ð ˜Ô(Ð(Ð(ØÔ ×'Ò'¨Ñ*Ô*Ð*Ø"œj×4Ò4°Q´VÀqÄvÐ4ÑNÔN�Ý#'¤9¨Q¬VÑ#4Ô#4�Ô ØÔ'×.Ò.¨{Ñ;Ô;Ð;Ø"&�˜Q‘àÔ*¨4Ô+;×+AÒ+AÀ!Ñ+DÔ+DÔEÐEr   zGraph had no output node!r   )ÚsubgraphÚ	comp_name)ÚargsÚkwargsc                 ó(   — i | ]}|j         |j        “ŒS r=   )r   r.   )rQ   r^   s     r   ú
<dictcomp>z!split_by_tags.<locals>.<dictcomp>#  s   € ÐLÐLÐL°T˜dœi¨¬ÐLÐLÐLr   ),r3   r4   ÚnodeÚArgumentr   r5   r   ÚlenrF   r&   ÚnodesrP   ÚRuntimeErrorrJ   r   rZ   r[   r\   r   rd   re   rN   Úmaxr'   Ú	node_copyrM   r+   ÚtupleÚmapÚ__getitem__rI   r   r.   ÚupdateÚcall_moduler*   Ú	enumerateÚProxyr   r   Ú_codegenr!   r   rY   )r.   r>   r?   r@   rA   rH   Útag_to_componentÚall_componentsÚmain_gÚmain_remappingÚoutput_noderN   rh   Úupstream_componentsÚmxra   ÚnrD   Úorig_to_split_fqn_mappingÚoutsÚcomp_orig_to_split_fqn_mappingÚ	main_nodeÚiÚoÚ	main_rootÚ	result_gmr^   r_   rR   r`   s                             @@@@r   r   r   >   s}  øøøø€ ðB•5”8”=Ô)ð ­hð ð ð ð ð :<€Nð 9;Ðð .0Ðð ')€Nð /1€Lõ ŒX�^Š^ÑÔ€Fð :<€Nð ,0€Kð ð %ð %ˆÝ�œŸšÑ)Ô)­3¨~Ñ+>Ô+>À3ÀÑIÔIˆØ×Ò˜dÑ#Ô#Ð#Ø $Ð˜ÑÐð ””ð D$ñ D$ˆØŒ7�hÒÐØÐ&Ý"Ð#DÑEÔEÐEØˆKØð Œ7�mÒ#Ð#Ø#)×#5Ò#5°d´iÈ4Ì9Ð#5Ñ#UÔ#UˆN˜4Ñ Ý(,¬	°$´)Ñ(<Ô(<ˆN˜4Ô Ô%Øð Œ7�jÒ Ð Øõ �t˜UÑ#Ô#Ð#Ð#Ð#ð
ð 
ð 
ð 
à�W˜TœYÑ'Ô'¨'¨'°$´+Ñ*>Ô*>Ñ>ð
ñ 
ô 
Ðð   ¤Ô)ˆØ"&Ð˜$Ñõ Ð7Ð7Ð#6Ð7Ñ7Ô7ÀÐCÑCÔCˆð Œz˜RÒÐÐÐð	Fð 	Fð 	Fð 	Fð 	Fð 	Fð 	Fð 	Fð6 ŒJ× Ò   zÑ2Ô2ˆØ”ˆŒØ ˆ�tÑØ#Ð˜!ÑÑàÐÝÐ6Ñ7Ô7Ð7àˆW�[Ô% aÔ(Ñ)Ô)ð 	#ð 	#ˆØŒ4�:ÒÐð !'§¢°´À!Ä& Ñ IÔ IˆN˜1ÑÐð #ˆL˜‰OˆOð ð 8ð 8ˆØŒ4�=Ò Ð Ø˜aÔ Ô-×4Ò4°QÑ7Ô7Ð7øð 13ÐØð Fñ FˆÝ•S˜Ô3°TÔ5FÑGÔGÑHÔHˆàð 	CØŒJ×Ò˜dÑ#Ô#Ð#Ð#ð ŒJ×Ò­¨T©¬°aª¨˜d 1œg˜g¸TÑBÔBÐBå2IØ˜œ¨t¬yð3
ñ 3
ô 3
Ñ/ˆŒÐ/ð 	"×(Ò(Ð)GÑHÔHÐHð ×&Ò&ØŒIÝ•s˜>Ô5°tÔ7GÑHÔHÑIÔIØð 'ñ 
ô 
ˆ	õ ˆt‰9Œ9˜Š>ˆ> ,ˆ>Ø3<ˆN˜4Ô,¨QÔ/Ñ0Ñ0å! $Ô"3Ñ4Ô4ð Fð F‘��1å$)¤H§N¢N°9Ñ$=Ô$=¸aÔ$@Ô$E�˜qÑ!Ð!ñFð ‡M‚M•'˜+Ô*¨1Ô-¨~Ô/IÑJÔJÑKÔKÐKÝÐLÐL¸^ÐLÑLÔLÑMÔM€IØ”hÔ'€F„Oð ˆW�[Ô% aÔ(Ñ)Ô)ð Hð HˆØŒ4�:ÒÐÝ�I˜qœvÕ'8¸¸Q¼XÑ'FÔ'FÑGÔGÐGøà�˜y¨&Ñ1Ô1€IØð 4ØÐ3Ð3Ð3àÐr   )r[   Ú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Ð 1Ð 1Ð 1Ð 1Ð 1Ø "Ð "Ð "Ð "Ð "Ð "Ø GÐ GÐ GÐ GÐ GÐ GÐ GÐ Gà "Ð "Ð "Ð "Ð "Ð "ð SÐ
RÐ
R€ð € eÐ,Ñ,Ô,ðð ñ -Ô,ðð € eÐ,Ñ,Ô,ðNð Nñ -Ô,ðNð € eÐ,Ñ,Ô,Ø
ð.ð .ð .ð .ð .ñ .ô .ñ „ñ -Ô,ð.ð0 € eÐ,Ñ,Ô,ð  %ØØ16´Ô1Eðqð qØŒÔðqà
ˆsŒ)ðqð ðqð ð	qð
 ˜œÔ-Ô.ðqð ˆ5Œ8Ô  u¤xÔ';¸TÀ#ÀsÀ(¼^Ð'KÔ!LÐLÔMðqð qð qñ -Ô,ðqð qð qr   