§
    ŠŠtj²  ã                   óè  — U d dl Z d dlZd dlZd dlZd dlmZ d dlmZmZm	Z	 d dl
mZ d dl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 d d	lmZ d
dlmZ d
dlmZmZ d
dlm Z  d
dl!m"Z"m#Z# d
dl$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z* g d¢Z+d
Z,dZ-dZ.dZ/dZ0dZ1dZ2dZ3dZ4ej5         6                    e3e/¦  «        Z7	 ej5         6                    e2d¦  «        Z8ed         e9d<    G d„ d¦  «        Z: ed¬¦  «         G d„ d¦  «        ¦   «         Z; ed¬¦  «         G d „ d!¦  «        ¦   «         Z< ed¬¦  «         G d"„ d#¦  «        ¦   «         Z= ed¬¦  «         G d$„ d%e>¦  «        ¦   «         Z? ed¬¦  «        e G d&„ d'¦  «        ¦   «         ¦   «         Z@ ed¬¦  «         G d(„ d)e¦  «        ¦   «         ZA ed¬¦  «        	 d2d*ejB        jC        d+e	e         d,eeD         d-eEd.eFeDef         f
d/„¦   «         ZG G d0„ d1¦  «        ZHdS )3é    N)Údefaultdict)ÚCallableÚIterableÚSequence)Ú	dataclass)ÚAnyÚIOÚLiteralÚ
NamedTuple)Útrace_structured)Úcompatibility)Úmap_arg)Úget_size_of_nodeé   )ÚFxGraphDrawer)Úget_node_targetÚOperatorSupportBase)Ú	ShapeProp)Ú!move_non_tensor_nodes_on_boundaryÚsplit_by_tags)ÚCALLABLE_NODE_OPSÚFxNetAccFusionsFinderÚis_node_output_tensorÚNodeListÚNodeSetÚTensors)ÚFxNetAccNodesFinderÚFxNetSplitterInternalErrorÚSubgraphÚSplitResultÚgenerate_inputs_for_submodulesÚ	NodeEventÚNodeEventTrackerFÚ_fx_net_trackerz
_nodes.txtz_all.txtÚ FX_NET_ACC_SPLITTER_TRACKER_MODEÚ%FX_NET_ACC_SPLITTER_TRACKER_DUMP_PATHÚ)FX_NET_ACC_SPLITTER_TRACKER_TRACKED_NODESÚ0)r(   Ú1Ú2Ú3ÚTRACKER_MODEc                   ó:   — e Zd Zeeeddfdedededededd	fd
„Zd	S )Ú_SplitterSettingBaseéÿÿÿÿFÚmin_acc_module_sizeÚskip_fusionÚallow_non_tensorÚmax_acc_splitsr   ÚreturnNc                 ó(  — t          j        ¦   «         }|                     dddt          d¬¦  «         |                     dddt          d¬¦  «         |                     d	d
ddd¬¦  «         |                     ddddd¬¦  «         |                     ddddd¬¦  «         |                     ¦   «         \  }}|j        r|j        n|| _        |j        r|j        n|| _        |j        r|j        n|| _        || _        |j	        r|j	        n|| _	        d S )Nz--min-acc-module-sizez--min_acc_module_sizeFz.Minimum size limit of an accelerator subgraph.)ÚrequiredÚtypeÚhelpz--max-acc-splitsz--max_acc_splitsz,Enforce a maximum number of split subgraphs.z--skip-fusionz--skip_fusionÚ
store_truezÌIf true then no fusion groups. Fusion group is used to enforce no non-tensor data flow between submodules. If we don't have this constraint, setting this to false is recommended as it can reduce overhead.)ÚdefaultÚactionr8   z--allow-non-tensorz--allow_non_tensora˜  For some backends non-tensor data flow between cpu and them are not allowed. Therefore, if a node supported by accelerator but it has non-tensor inputs or outputs to a cpu node we would want to consider it as a cpu node during splitting. However, for some backends we might not care about non-tensor data flow and we can set this option to true to disable the functionality that prevent non-tensor data flow.z#--move-non-tensor-nodes-on-boundaryz#--move_non_tensor_nodes_on_boundarya=  AOTI does not support non-tensor nodes on acc->acc, acc->gpu and gpu->acc boundary. For non-tensor nodes on acc->acc boundary and acc->gpu, we move the nodes from upstream to downstream. For non-tensor nodes on gpu->acc boundary, it is handled by the pre-split process. (by method reduce_acc_nodes_non_tensor_input). )r6   r;   r8   )
ÚargparseÚArgumentParserÚadd_argumentÚintÚparse_known_argsr0   r1   r2   r3   r   )	Úselfr0   r1   r2   r3   r   ÚparserÚargsÚ_unknowns	            ú[/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/torch/fx/passes/splitter_base.pyÚ__init__z_SplitterSettingBase.__init__L   sš  € õ Ô(Ñ*Ô*ˆØ×ÒØ#Ø#ØÝØAð 	ñ 	
ô 	
ð 	
ð 	×ÒØØØÝØ?ð 	ñ 	
ô 	
ð 	
ð 	×ÒØØØØð#ð 	ñ 		
ô 		
ð 		
ð 	×ÒØ Ø ØØðVð 	ñ 	
ô 	
ð 	
ð 	×ÒØ1Ø1ØØð>ð 	ñ 		
ô 		
ð 		
ð  ×0Ò0Ñ2Ô2‰ˆˆhð Ô'ð%ˆDÔ$Ð$à$ð 	Ô ð
 6:Ô5EÐ!V Ô!1Ð!1È;ˆÔà%)Ô%:ÐPˆDÔ!Ð!Ð@Pð 	Ôð $2ˆÔð Ô5ð3ˆDÔ2Ð2à2ð 	Ô.Ð.Ð.ó    )	Ú__name__Ú
__module__Ú__qualname__ÚDEFAULT_MIN_ACC_MODULE_SIZEÚDEFAULT_SKIP_FUSIONÚDEFAULT_ALLOW_NON_TENSORr?   ÚboolrF   © rG   rE   r.   r.   K   s…   € € € € € ð $?Ø/Ø!9Ø Ø27ðG
ð G
à ðG
ð ðG
ð ð	G
ð
 ðG
ð ,0ðG
ð 
ðG
ð G
ð G
ð G
ð G
ð G
rG   r.   )Úis_backward_compatiblec            	       óh   — e Zd ZdZ	 d	dej        j        dedej        j        dz  ddfd„Zdefd„Z	dS )
r"   zÀ
    An event in graph split that happened on a node.
    source: Subject of the event
    desc: readable description
    dep: Optional dependency, usually the node that caused the event.
    NÚsourceÚdescÚdepr4   c                 ó0   — || _         || _        || _        d S ©N)rR   rS   rT   )rA   rR   rS   rT   s       rE   rF   zNodeEvent.__init__Ÿ   s   € ð ˆŒØˆŒ	ØˆŒˆˆrG   c                 óZ   — | j         j        › d| j        › d| j        r| j        j        nd› �S )Nú: ú ú#)rR   ÚnamerS   rT   ©rA   s    rE   Úto_strzNodeEvent.to_str¦   s7   € ð
 ”+Ô"ÐVÐV d¤iÐVÐVÀ4Ä8Ð2T°$´(´-°-ÐQTÐVÐVÐVrG   rV   )
rH   rI   rJ   Ú__doc__ÚtorchÚfxÚNodeÚstrrF   r]   rO   rG   rE   r"   r"   –   s�   € € € € € ðð ð MQðð Ø”h”mðØ+.ðØ5:´X´]ÀTÑ5Iðà	ðð ð ð ðW˜ð Wð Wð Wð Wð Wð WrG   r"   c                   ó  — e Zd ZdZdededdfd„Z	 ddej        j	        ded	ej        j	        dz  ddfd
„Z
	 	 	 ddedededeegef         dz  ddf
d„Zdeeee         f         fd„Zddeegef         dz  ddfd„Zdd„ZdS )r#   z;
    Tracks node events during the splitter execution.
    Útracker_modeÚdump_prefixr4   Nc                 óV   — || _         || _        g | _        i | _        t          | _        d S rV   )rd   re   ÚeventsÚnode_eventsÚprintÚwriter)rA   rd   re   s      rE   rF   zNodeEventTracker.__init__´   s,   € Ø(ˆÔØ&ˆÔàˆŒàˆÔÝˆŒˆˆrG   ÚnoderS   rT   c                 ó
  — t          |||¦  «        }| j                             |¦  «         |j        | j        vrg | j        |j        <   | j        |j                                      t          | j        ¦  «        dz
  ¦  «         dS )z1
        Add a new event to the tracker.
        r   N)r"   rg   Úappendr[   rh   Úlen)rA   rk   rS   rT   Úevents        rE   ÚaddzNodeEventTracker.add½   s}   € õ ˜$  cÑ*Ô*ˆØŒ×Ò˜5Ñ!Ô!Ð!ØŒ9˜DÔ,Ð,Ð,Ø*,ˆDÔ˜TœYÑ'ØÔ˜œÔ#×*Ò*­3¨t¬{Ñ+;Ô+;¸aÑ+?Ñ@Ô@Ð@Ð@Ð@rG   FÚ Ú	node_nameÚ	recursiveÚtabrj   c                 ó  — |s| j         }| j                             |g ¦  «        D ]^}| j        |         } |||                     ¦   «         z   ¦  «         |r-|j        �&|                      |j        j        dd|z   |¬¦  «         Œ_dS )a  
        Print a node and its events.
        @param recursive: if True, print nodes that caused the events on this current node.
        @param tab: Indentation for dependencies.
        @param writer: function to write to file. If None, use print.
        NTz| ©rs   rt   rj   )rj   rh   Úgetrg   r]   rT   Ú
print_noder[   )rA   rr   rs   rt   rj   Úidxro   s          rE   rx   zNodeEventTracker.print_nodeÉ   s¤   € ð ð 	!Ø”[ˆFØÔ#×'Ò'¨	°2Ñ6Ô6ð 	ð 	ˆCØ”K Ô$ˆEØˆF�3˜Ÿš™œÑ'Ñ(Ô(Ð(Øð ˜UœYÐ2Ø—’Ø”I”N¨d¸¸s¹
È6ð  ñ ô ð øð		ð 	rG   c                 óØ   — i }| j         D ]_}g ||<   | j                              |g ¦  «        D ]<}| j        |         }||                              |                     ¦   «         ¦  «         Œ=Œ`|S )z1
        Create dict dump on all events.
        )rh   rw   rg   rm   r]   )rA   Úretr[   ry   ro   s        rE   Úto_dictzNodeEventTracker.to_dictà   s�   € ð %'ˆØÔ$ð 	1ð 	1ˆDØˆC�‰IØÔ'×+Ò+¨D°"Ñ5Ô5ð 1ð 1�Øœ CÔ(�Ø�D”	× Ò  §¢¡¤Ñ0Ô0Ð0Ð0ð1ð ˆ
rG   c                 ó|   — |s| j         }| j        D ]*} |d|› d�¦  «         |                      |dd|¬¦  «         Œ+dS )zr
        Print all nodes in a list.
        @param writer: function to write to file. If None, use print.
        zNode: ú:Fz  rv   N)rj   rh   rx   )rA   rj   r[   s      rE   Ú	print_allzNodeEventTracker.print_allì   sl   € ð
 ð 	!Ø”[ˆFØÔ$ð 	Lð 	LˆDØˆFÐ#˜DÐ#Ð#Ð#Ñ$Ô$Ð$Ø�OŠO˜D¨E°tÀFˆOÑKÔKÐKÐKð	Lð 	LrG   c                 óš  ‡ ‡— t          dd„ ˆ fd„¬¦  «         dt          t                   dt          t          gt          f         fd„Š‰ j        dk    rSt          ‰ j        t          z   d	¦  «        5 }‰  	                     ‰|¦  «        ¦  «         d
d
d
¦  «         n# 1 swxY w Y   dt          t                   dd
fˆˆ fd„}‰ j        dk    s‰ j        dk    rs‰ j        dk    r8t          j                             t          d¦  «                             d¦  «        n"d„ ‰ j                             ¦   «         D ¦   «         } ||¦  «         d
S d
S )z}
        Function to be invoked at the end of the finder execution to printout tracked events specified by the mode.
        Úartifactc                  ó   — dddœS )NÚ!fx_net_acc_splitter_finder_eventsÚjson)r[   ÚencodingrO   rO   rG   rE   ú<lambda>z'NodeEventTracker.dump.<locals>.<lambda>þ   s   € Ø;Ø"ð!ð !€ rG   c                  óP   •— t          j        ‰                      ¦   «         ¦  «        S rV   )r„   Údumpsr|   r\   s   €rE   r†   z'NodeEventTracker.dump.<locals>.<lambda>  s   ø€ �tœz¨$¯,ª,©.¬.Ñ9Ô9€ rG   )Úmetadata_fnÚ
payload_fnÚfr4   c                 ó0   ‡ — dt           dt          fˆ fd„}|S )NÚxr4   c                 ó4   •— ‰                      | dz   ¦  «        S )Nú
)Úwrite)r�   r‹   s    €rE   Úfnz6NodeEventTracker.dump.<locals>.make_writer.<locals>.fn  s   ø€ Ø—w’w˜q 4™xÑ(Ô(Ð(rG   )rb   r?   )r‹   r‘   s   ` rE   Úmake_writerz*NodeEventTracker.dump.<locals>.make_writer  s6   ø€ ð)•cð )�cð )ð )ð )ð )ð )ð )ð ˆIrG   r   ÚwNÚnodesc                 ó  •— t          ‰j        t          z   d¦  «        5 } ‰|¦  «        }| D ]9} |d|› d�¦  «         ‰                     |dd|¬¦  «          |d|› d�¦  «         Œ:	 d d d ¦  «         d S # 1 swxY w Y   d S )Nr“   z===== Tracking node z =====Tz|-rv   z===== End of tracking node )Úopenre   ÚNODES_SUFFIXrx   )r”   r‹   rj   rr   r’   rA   s       €€rE   Údump_selected_nodesz2NodeEventTracker.dump.<locals>.dump_selected_nodes  s	  ø€ Ý�dÔ&­Ñ5°sÑ;Ô;ð L¸qØ$˜ Q™œ�Ø!&ð Lð L�IØ�FÐC°)ÐCÐCÐCÑDÔDÐDØ—O’O I¸À4ÐPV�OÑWÔWÐWØ�FÐJ¸ÐJÐJÐJÑKÔKÐKÐKðLðLð Lð Lñ Lô Lð Lð Lð Lð Lð Lð Lð Løøøð Lð Lð Lð Lð Lð Ls   ŸAA5Á5A9Á<A9é   é   rq   ú,c                 ó>   — g | ]\  }}t          |¦  «        d k    ¯|‘ŒS )r   )rn   )Ú.0r[   rg   s      rE   ú
<listcomp>z)NodeEventTracker.dump.<locals>.<listcomp>!  s/   € ð ð ð Ù)˜T 6ÍÈVÉÌÐWXÊÈ�DÈÈÈrG   )r   r	   rb   r   r?   rd   r–   re   Ú
ALL_SUFFIXr   ÚlistÚosÚenvironrw   Ú-ENV_FX_NET_ACC_SPLITTER_TRACKER_TRACKED_NODESÚsplitrh   Úitems)rA   r‹   r˜   r”   r’   s   `   @rE   ÚdumpzNodeEventTracker.dump÷   sç  øø€ õ
 	Øðð ð :Ð9Ð9Ð9ð	
ñ 	
ô 	
ð 	
ð	�2�cœ7ð 	¥xµ°µs°
Ô';ð 	ð 	ð 	ð 	ð Ô Ò!Ð!Ý�dÔ&­Ñ3°SÑ9Ô9ð /¸QØ—’˜{˜{¨1™~œ~Ñ.Ô.Ð.ð/ð /ð /ñ /ô /ð /ð /ð /ð /ð /ð /øøøð /ð /ð /ð /ð	L¥t­C¤yð 	L°Tð 	Lð 	Lð 	Lð 	Lð 	Lð 	Lð 	Lð Ô Ò!Ð! TÔ%6¸!Ò%;Ð%;ð
 Ô$¨Ò)Ð)õ ”
—’ÕLÈbÑQÔQ×WÒWØñô ð ðð Ø-1Ô-=×-CÒ-CÑ-EÔ-Eðñ ô ð ð  Ð Ñ&Ô&Ð&Ð&Ð&ð &<Ð%;s   Á1BÂB Â#B rV   )Frq   N©r4   N)rH   rI   rJ   r^   r?   rb   rF   r_   r`   ra   rp   rN   r   Úobjectrx   Údictr    r|   r   r¦   rO   rG   rE   r#   r#   ®   s{  € € € € € ðð ð Sð °sð ¸tð ð ð ð ð KOð
Að 
AØ”H”Mð
AØ),ð
AØ38´8´=À4Ñ3Gð
Aà	ð
Að 
Að 
Að 
Að  ØØ15ðð àðð ðð ð	ð
 ˜#˜ ˜Ô'¨$Ñ.ðð 
ðð ð ð ð.
˜˜c 4¨¤9˜nÔ-ð 
ð 
ð 
ð 
ð	Lð 	L ¨#¨°¨Ô 7¸$Ñ >ð 	LÈ$ð 	Lð 	Lð 	Lð 	Lð.'ð .'ð .'ð .'ð .'ð .'rG   r#   c                   ój   — e Zd ZdZdej        j        dededdfd„Z	de
ddfd	„Zdd
„Zdd„Zdefd„ZdS )r   a¼  
    Finds a set of nodes that can be supported on ACC, excluding nodes that have non-tensor
    input/output to cpu nodes to prevent non-tensor data flow between backends and cpu.

    I.e. if we have a chain:

    ACC_NODE_1 -> ACC_NODE_2 -> ACC_NODE_3 -> CPU_NODE_1

    where every ACC node produces non-tensor output, then they all should be treated as CPU nodes.

    This behavior can be turned off by passing allow_non_tensor=True.
    ÚmoduleÚoperator_supportr2   r4   Nc                 ó®   — || _         || _        || _        t          ¦   «         | _        t          t          t          ¦  «        t          ¦  «        | _	        d S rV   )
r«   r¬   r2   ÚsetÚ	acc_nodesr#   r?   r,   ÚDUMP_PREFIXÚtracker)rA   r«   r¬   r2   s       rE   rF   zFxNetAccNodesFinder.__init__7  sC   € ð ˆŒØ 0ˆÔØ 0ˆÔÝ"%¡%¤%ˆŒå'­­LÑ(9Ô(9½;ÑGÔGˆŒˆˆrG   Úcpu_worklistc                 óL  — |r¡|                      d¦  «        }|j        D ]€}|| j        v ru| j                             |¦  «         | j                             |d|¦  «         t          |¦  «        s0| j                             |d¦  «         |                     |¦  «         Œ�|°ŸdS dS )a!  
        Transitively excludes nodes from ACC supported set.
        For every node in the worklist:
        - removes its downstream ACC nodes from ACC supported set,
        - if any downstream ACC node produces non-tensor output,
          then it gets added into the worklist.
        r   zacc_del|user_of_new_cpu_nodeznew_cpu_node|non_tensor_outputN)ÚpopÚusersr¯   Úremover±   rp   r   rm   )rA   r²   rk   Úusers       rE   Ú(reduce_acc_nodes_non_tensor_input_helperz<FxNetAccNodesFinder.reduce_acc_nodes_non_tensor_input_helperD  sÊ   € ð ð 		2Ø×#Ò# AÑ&Ô&ˆDàœ
ð 2ð 2�Ø˜4œ>Ð)Ð)Ø”N×)Ò)¨$Ñ/Ô/Ð/Ø”L×$Ò$ TÐ+IÈ4ÑPÔPÐPÝ0°Ñ6Ô6ð 2Øœ×(Ò(¨Ð/OÑPÔPÐPØ$×+Ò+¨DÑ1Ô1Ð1øð ð 		2ð 		2ð 		2ð 		2ð 		2rG   c                 ó  — g }| j         j        j        D ][}|j        t          vrŒ|| j        v rŒt          |¦  «        rŒ+| j                             |d¦  «         | 	                    |¦  «         Œ\|  
                    |¦  «         dS )z„
        Excludes nodes from ACC supported set that have direct
        upstream CPU nodes that produce non-tensor outputs.
        z&new_cpu_node|callable_non_tensor_inputN)r«   Úgraphr”   Úopr   r¯   r   r±   rp   rm   r¸   )rA   Únon_tensor_cpu_nodesrk   s      rE   Ú!reduce_acc_nodes_non_tensor_inputz5FxNetAccNodesFinder.reduce_acc_nodes_non_tensor_inputW  s    € ð
 *,Ðà”KÔ%Ô+ð 	.ð 	.ˆDØŒwÕ/Ð/Ð/ØØ�t”~Ð%Ð%ØÝ$ TÑ*Ô*ð ØØŒL×Ò˜TÐ#KÑLÔLÐLØ ×'Ò'¨Ñ-Ô-Ð-Ð-à×5Ò5Ð6JÑKÔKÐKÐKÐKrG   c                 ó:  — 	 g }| j         D ]X}t          |¦  «        rŒ|j        D ]>}|| j         vr3|                     |¦  «         | j                             |d|¦  «          nŒ?ŒY|sdS |D ]}| j                              |¦  «         Œ|                      |¦  «         Œ›)z~
        Excludes nodes from ACC supported set that produce non-tensor
        outputs and have downstream CPU nodes.
        Tz'acc_del|non_tensor_output_with_cpu_userN)r¯   r   rµ   rm   r±   rp   r¶   r¸   )rA   Únew_cpu_nodesÚacc_noder·   Únew_cpu_nodes        rE   Ú"reduce_acc_nodes_non_tensor_outputz6FxNetAccNodesFinder.reduce_acc_nodes_non_tensor_outputj  sä   € ð
	IØ&(ˆMà œNð 	ð 	�Ý(¨Ñ2Ô2ð ØØ$œNð ð �DØ 4¤>Ð1Ð1Ø%×,Ò,¨XÑ6Ô6Ð6Øœ×(Ò(Ø$Ð&OÐQUñô ð ð ˜ð 2øð !ð Ø�à -ð 4ð 4�Ø”×%Ò% lÑ3Ô3Ð3Ð3à×9Ò9¸-ÑHÔHÐHð)	IrG   c                 óf  — t          | j                             ¦   «         ¦  «        }t          ¦   «         | _        | j        j        j        D ]˜}|j        t          vr| j	         
                    |d¦  «         Œ,| j                             ||¦  «        s| j	         
                    |d¦  «         Œc| j	         
                    |d¦  «         | j         
                    |¦  «         Œ™| j        s(|                      ¦   «          |                      ¦   «          | j	                             ¦   «          | j        S )Nzinit_cpu|not_callablezinit_cpu|operator_supportz(init_acc|callable_and_operator_supported)r©   r«   Únamed_modulesr®   r¯   rº   r”   r»   r   r±   rp   r¬   Úis_node_supportedr2   r½   rÂ   r¦   )rA   Ú
submodulesÚns      rE   Ú__call__zFxNetAccNodesFinder.__call__…  s  € Ý˜$œ+×3Ò3Ñ5Ô5Ñ6Ô6ˆ
Ý™œˆŒØ”Ô"Ô(ð 		"ð 		"ˆAØŒtÕ,Ð,Ð,Ø”× Ò  Ð$;Ñ<Ô<Ð<ØØÔ(×:Ò:¸:ÀqÑIÔIð Ø”× Ò  Ð$?Ñ@Ô@Ð@ØàŒL×Ò˜QÐ JÑKÔKÐKØŒN×Ò˜qÑ!Ô!Ð!Ð!àÔ$ð 	6Ø×2Ò2Ñ4Ô4Ð4Ø×3Ò3Ñ5Ô5Ð5ØŒ×ÒÑÔÐØŒ~ÐrG   r§   )rH   rI   rJ   r^   r_   r`   ÚGraphModuler   rN   rF   r   r¸   r½   rÂ   r   rÈ   rO   rG   rE   r   r   (  sÓ   € € € € € ðð ðHà”Ô$ðHð .ðHð ð	Hð
 
ðHð Hð Hð Hð2ÀXð 2ÐRVð 2ð 2ð 2ð 2ð&Lð Lð Lð Lð&Ið Ið Ið Ið6˜'ð ð ð ð ð ð rG   r   c                   ó   — e Zd ZdS )r   N)rH   rI   rJ   rO   rG   rE   r   r   š  s   € € € € € à€DrG   r   c                   ó8   — e Zd ZU eed<   eed<   dZedz  ed<   dS )r   Úis_accr”   NÚdevice_ordinal)rH   rI   rJ   rN   Ú__annotations__r   rÍ   r?   rO   rG   rE   r   r   Ÿ  s:   € € € € € € ð €L€L�LØ€O€O�OØ!%€N�C˜$‘JÐ%Ð%Ñ%Ð%Ð%rG   r   c                   óV   — e Zd ZU dZej        j        ed<   ee	e
f         ed<   e	ed<   dS )r    aB  
    Stores the results of the splitter.

    Attributes:
        split_module: root module after splitting.
        submodule_inputs: a dict that maps submodule name to its inputs.
        non_acc_submodule_prefix: the prefix for non acc submodules. For
            acc submodule the prefix is always "_run_on_acc_".
    Úsplit_moduleÚsubmodule_inputsÚnon_acc_submodule_prefixN)rH   rI   rJ   r^   r_   r`   rÉ   rÎ   r©   rb   r   rO   rG   rE   r    r    §  sO   € € € € € € ðð ð ”(Ô&Ð&Ð&Ñ&Ø˜3 ˜8”nÐ$Ð$Ñ$Ø!Ð!Ð!Ñ!Ð!Ð!rG   r    ÚmodelÚinputsÚtarget_submodulesÚdeepcopyr4   c                 ó:  ‡‡	‡
‡— g Š	i Š
d„ |                       ¦   «         D ¦   «         Šdt          j        j        dt          t
          df         ddfˆˆ
ˆfd„}|                       ¦   «         D ]P\  }}||v rGt          |t          j        j        ¦  «        s(‰	 	                    | 
                    |¦  «        ¦  «         ŒQd	ˆ	fd„}	 t          j        ¦   «         5   | |Ž  ddd¦  «         n# 1 swxY w Y   n# t          $ r} |¦   «          |‚d}~ww xY w |¦   «          ‰
S )
a~  
    Generate inputs for targeting submodules in the given model. Note that if two submodules refer to the same obj, this
    function doesn't work.

    Args:
        model: root model.
        inputs: inputs to the root model.
        target_submodules: submodules that we want to generate inputs for.

    Returns:
        A dict that maps from submodule name to its inputs.
    c                 ó   — i | ]\  }}||“Œ	S rO   rO   )r�   r[   Úmods      rE   ú
<dictcomp>z2generate_inputs_for_submodules.<locals>.<dictcomp>Î  s   € ÐKÐKÐK©	¨¨c˜#˜tÐKÐKÐKrG   r«   Úmodule_inputs.r4   Nc                 óJ   •— ‰rt          j        |¦  «        n|‰‰|          <   d S rV   )ÚcopyrÖ   )r«   rÛ   rÖ   ÚresultsÚsubmodule_to_namess     €€€rE   Úpre_forwardz3generate_inputs_for_submodules.<locals>.pre_forwardÐ  s0   ø€ à,4ÐG�DŒM˜-Ñ(Ô(Ð(¸-ð 	Ð" 6Ô*Ñ+Ð+Ð+rG   c                  ó:   •— ‰D ]} |                       ¦   «          Œd S rV   )r¶   )ÚhÚhandless    €rE   Úclean_up_handlesz8generate_inputs_for_submodules.<locals>.clean_up_handlesÚ  s+   ø€ Øð 	ð 	ˆAØ�HŠH‰JŒJˆJˆJð	ð 	rG   r§   )rÄ   r_   ÚnnÚModuleÚtupler   Ú
isinstanceÚjitÚScriptModulerm   Úregister_forward_pre_hookÚno_gradÚ	Exception)rÓ   rÔ   rÕ   rÖ   rà   r[   rÙ   rä   Úerã   rÞ   rß   s      `     @@@rE   r!   r!   ¸  s½  øøøø€ ð( €GØ €GØKÐK°U×5HÒ5HÑ5JÔ5JÐKÑKÔKÐð
�EœHœOð 
½EÅ#ÀsÀ(¼Oð 
ÐPTð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð
 ×(Ò(Ñ*Ô*ð Kð K‰	ˆˆcØÐ$Ð$Ð$Ý˜c¥5¤9Ô#9Ñ:Ô:ð KØ—’˜s×<Ò<¸[ÑIÔIÑJÔJÐJøðð ð ð ð ð ðÝŒ]‰_Œ_ð 	ð 	ØˆE�6ˆNˆNð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	øøåð ð ð ØÐÑÔÐØˆøøøøðøøøð ÐÑÔÐØ€Ns<   ÃC3 ÃC'ÃC3 Ã'C+Ã+C3 Ã.C+Ã/C3 Ã3
DÃ=D	Ä	Dc                   óÔ  — e Zd ZdZdZ	 	 	 d,dej        j        dee	         de
d	ed
edededz  ddfd„Zdeeef         fd„Zdeej        j        ef         fd„Zd-d„Zd-d„Zdej        j        dedej        j        fd„Zdej        j        dedefd„Zdej        j        deddfd„Zd.dedefd„Zd.dedefd„Z	 d/de dz  deej        j        ef         fd„Z!deej        j        ef         ddfd„Z"d edefd!„Z#d eddfd"„Z$de%eef         fd#„Z&de'e(         fd$„Z)d%e'e(         de'e(         fd&„Z*d%e'e(         ddfd'„Z+d.d(edej        j        fd)„Z,dej        j        fd*„Z-de.fd+„Z/dS )0Ú_SplitterBasea  
    Splits a GraphModule into sub-GraphModules for execution on CPU or the accelerator.
    Output is a GraphModule with supported and unsupported operators grouped into as few sub-GraphModules as possible.
    Assumes that only "call_module", "call_function" and "call_method" from FX IR can potentially be executed on the accelerator.

    Given the following graph:
          ==> b ==>
        //         \
       a             d
        \         //
          ==> c ==>

    class SimpleModule(torch.nn.Module):
        def forward(self, a):
            b = torch.sin(a)
            c = torch.cos(a)
            d = b + c
            return d

    and providing "operator_support" that indicates that 'b' and 'c' can be executed on the accelerator,
    we will get the following split result:

    main:
    def forward(self, a):
        run_on_acc_0_0 = self._run_on_acc_0_0(a)
        getitem = run_on_acc_0_0[0]
        getitem_1 = run_on_acc_0_0[1]
        run_on_cpu_1_1 = self._run_on_cpu_1_1(getitem, getitem_1)
        return run_on_cpu_1_1

    _run_on_acc_0_0:
    def forward(self, a):
        sin_1 = torch.sin(a)
        cos_1 = torch.cos(a)
        return (sin_1, cos_1)

    _run_on_cpu_1_1:
    def forward(self, sin_1, cos_1):
        add_1 = sin_1 + cos_1
        return add_1
    l       d Ú_run_on_cpu_FNr«   Úsample_inputr¬   ÚsettingsÚnon_acc_submodule_nameÚreturn_tupleÚnodes_finderr4   c                 ó„  — t          |t          j        j        ¦  «        st	          dt          |¦  «        › �¦  «        ‚|| _         t          | j        ¦  «        j        |Ž  || _	        || _
        || _        |€%t          | j        | j
        | j	        j        ¦  «        } |¦   «         | _        | j	        j        ri | _        n6 t#          || j        ¦  «        ¦   «         | _        |                      ¦   «          |                      ¦   «         | _        |                      ¦   «          || _        i | _        || _        g | _        dS )aP  
        Preprocesses graph before splitting:
        - finds nodes supported by ACC,
        - finds fusion groups for ACC nodes having non-tensor IO,
        - builds a graph of direct dependencies,
        - builds a map of fused nodes to their fusions.
        As a result we get self.acc_nodes, self.deps and self.fusions.
        zExpected GraphModule, got N)rè   r_   r`   rÉ   ÚAssertionErrorr7   r«   r   Ú	propagateró   r¬   rò   r   r2   r¯   r1   Úfusionsr   Ú_merge_overlapping_fusionsÚ	find_depsÚdepsÚupdate_deps_for_fusionsrô   Ú_node_submodule_mapÚ_return_tupleÚtags)rA   r«   rò   r¬   ró   rô   rõ   rö   s           rE   rF   z_SplitterBase.__init__  s2  € õ$ ˜&¥%¤(Ô"6Ñ7Ô7ð 	NÝ Ð!L½dÀ6¹l¼lÐ!LÐ!LÑMÔMÐMàˆŒØ(�	�$”+ÑÔÔ(¨,Ð7Ð7à ˆŒØ 0ˆÔØ(ˆÔØÐÝ.Ø”˜TÔ2°D´MÔ4Rñô ˆLð &˜™œˆŒàŒ=Ô$ð 	.ØˆDŒLˆLàHÕ0°¸¼ÑHÔHÑJÔJˆDŒLØ×+Ò+Ñ-Ô-Ð-ð —N’NÑ$Ô$ˆŒ	Ø×$Ò$Ñ&Ô&Ð&à&<ˆÔ#Ø35ˆÔ Ø)ˆÔà!ˆŒ	ˆ	ˆ	rG   c                 ó   — | j         S )a  Returns a map from node name to submodule name, e.g.
        node: main_module_impl_impl_over_arch_unary_multiple_embedding
          _pooling_embedding_pooling_sparse_entity_equivalence_key
          _proxy_embedding_bag
        maps to submodule name of: _run_on_acc_1
        )rÿ   r\   s    rE   Úget_node_submodule_mapz$_SplitterBase.get_node_submodule_mapL  s   € ð Ô'Ð'rG   c                 óÔ   — t          t          ¦  «        }| j        j        j        D ]A}|j        t          vrŒ|j        D ](}|j        dk    r||                              |¦  «         Œ)ŒB|S )a	  
        Builds a graph of node dependencies. Leaf nodes don't have any
        dependencies and the "output" node doesn't have nodes depending on it.

        Resulting graph has only direct dependencies, i.e. there are no
        transitive dependencies.
        Úoutput)	r   r®   r«   rº   r”   r»   r   rµ   rp   )rA   rý   rk   r·   s       rE   rü   z_SplitterBase.find_depsU  sz   € õ .9½Ñ-=Ô-=ˆØ”KÔ%Ô+ð 	)ð 	)ˆDØŒwÕ/Ð/Ð/Øàœ
ð )ð )�Ø”7˜hÒ&Ð&Ø˜”J—N’N 4Ñ(Ô(Ð(øð)ð ˆrG   c                 óö   — | j         D ]p}| j         |         }|D ]^}| j        |                              | j        |         |z
  ¦  «         |j        D ]&}||vr | j        |                              |¦  «         Œ'Œ_ŒqdS )zÔ
        Updates graph of dependencies so that:
        - nodes from the same fusion depend on the same set of outer nodes,
        - outer nodes depending on a fusion depend on all nodes in that fusion.
        N)rú   rý   Úupdaterµ   rp   )rA   rk   ÚfusionÚfused_neighborr·   s        rE   rþ   z%_SplitterBase.update_deps_for_fusionsg  s¢   € ð ”Lð 	2ð 	2ˆDØ”\ $Ô'ˆFØ"(ð 2ð 2�Ø”	˜$”×&Ò& t¤y°Ô'@À6Ñ'IÑJÔJÐJà*Ô0ð 2ð 2�DØ 6Ð)Ð)Øœ	 $œ×+Ò+¨DÑ1Ô1Ð1øð2ð2ð	2ð 	2rG   c                 óº  ‡— t           j                             dd¦  «        dk    rdS | j        sdS i }| j                             ¦   «         D ]}||t          |¦  «        <   Œt          |¦  «        dk    rdS t          t          ¦  «        }| 	                    ¦   «         D ]%\  }}|D ]}||          
                    |¦  «         ŒŒ&d„ |D ¦   «         Šdt          dt          fˆfd	„}d
}|                     ¦   «         D ]d}t          |¦  «        dk    rO ||d         ¦  «        }	t          dt          |¦  «        ¦  «        D ] }
 |||
         ¦  «        }||	k    r|	‰|<   d}Œ!Œe|sdS t          t          ¦  «        }| 	                    ¦   «         D ])\  }}| ||¦  «                                      |¦  «         Œ*|                     ¦   «         D ]}|D ]}|| j        |<   ŒŒdS )a   
        Merge fusion groups that share nodes.

        FxNetAccFusionsFinder can produce overlapping fusion groups when a
        node is absorbed into multiple groups during expansion. When
        update_deps_for_fusions() later propagates deps, shared nodes act
        as bridges between groups, creating bidirectional dependency cycles
        that crash the splitter with "Subgraph can't be empty".

        This method detects overlapping groups via union-find and merges
        them into single groups before dep propagation.
        Ú#_SPLITTER_MERGE_OVERLAPPING_FUSIONSr(   r)   Nr   c                 ó   — i | ]}||“ŒS rO   rO   )r�   Úgids     rE   rÚ   z<_SplitterBase._merge_overlapping_fusions.<locals>.<dictcomp>˜  s   € Ð!DÐ!DÐ!D¨s # sÐ!DÐ!DÐ!DrG   r�   r4   c                 ój   •— ‰|          | k    r%‰‰|                   ‰| <   ‰|          } ‰|          | k    °%| S rV   rO   )r�   Úparents    €rE   Úfindz6_SplitterBase._merge_overlapping_fusions.<locals>.findš  sA   ø€ Ø˜”)˜q’.�.Ø" 6¨!¤9Ô-��q‘	Ø˜1”I�ð ˜”)˜q’.�.ð ˆHrG   Fr   T)r¡   r¢   rw   rú   ÚvaluesÚidrn   r   r    r¥   rm   r?   Úranger®   r  )rA   Úunique_groupsÚgroupÚnode_to_gidsr  rk   r  Úneeds_mergeÚgidsÚrootÚiÚotherÚmergedÚmerged_groupr  s                 @rE   rû   z(_SplitterBase._merge_overlapping_fusionsv  sU  ø€ õ Œ:�>Š>Ð?ÀÑEÔEÈÒLÐLØˆFàŒ|ð 	ØˆFð -/ˆØ”\×(Ò(Ñ*Ô*ð 	-ð 	-ˆEØ',ˆM�"˜U™)œ)Ñ$Ð$åˆ}ÑÔ Ò"Ð"ØˆFõ 8CÅ4Ñ7HÔ7HˆØ'×-Ò-Ñ/Ô/ð 	/ð 	/‰JˆC�Øð /ð /�Ø˜TÔ"×)Ò)¨#Ñ.Ô.Ð.Ð.ð/ð "EÐ!D°mÐ!DÑ!DÔ!Dˆð	•Cð 	�Cð 	ð 	ð 	ð 	ð 	ð 	ð ˆØ ×'Ò'Ñ)Ô)ð 	+ð 	+ˆDÝ�4‰yŒy˜1Š}ˆ}Ø�t˜D œG‘}”}�Ý˜q¥# d¡)¤)Ñ,Ô,ð +ð +�AØ ˜D  a¤™MœM�EØ ’}�}Ø(,˜˜u™Ø&*˜øøàð 	ØˆFõ &1µÑ%5Ô%5ˆØ'×-Ò-Ñ/Ô/ð 	,ð 	,‰JˆC�Ø�4�4˜‘9”9Ô×$Ò$ UÑ+Ô+Ð+Ð+ð #ŸMšM™OœOð 	2ð 	2ˆLØ$ð 2ð 2�Ø%1�”˜TÑ"Ð"ð2ð	2ð 	2rG   rÙ   rÔ   c                 ó   — |S )z/
        Lower the model to a backend.
        rO   ©rA   rÙ   rÔ   s      rE   Ú_lower_model_to_backendz%_SplitterBase._lower_model_to_backend»  s	   € ð ˆ
rG   c                 ó   — dS )z¤
        When an error occurs during lowering or running the lowered mod, we use this
        function to find culprits in the `mod` that causes the error.
        zMUnable to find a culprit because _find_culprit() function is not implemented.rO   r  s      rE   Ú_find_culpritz_SplitterBase._find_culpritÄ  s   € ð _Ð^rG   Úsupported_nodesc                 ó°   ‡‡— ddddœŠ G ˆˆfd„dt           ¦  «        } ||dd¬	¦  «        }|                     ¦   «         }|                     d
¦  «         d S )NÚ	AliceBlueÚchartreuse1Úcrimson)r:   Ú	supportedÚunsupportedc                   óR   •‡ — e Zd Zdej        j        deeef         fˆ ˆˆfd„Zˆ xZ	S )úE_SplitterBase._draw_graph_based_on_node_support.<locals>.CustomDrawerrk   r4   c                 ó´   •— t          ¦   «                              |¦  «        }|‰v r‰d         |d<   n%|j        t          v r‰d         |d<   n‰d         |d<   |S )Nr(  Ú	fillcolorr)  r:   )ÚsuperÚ_get_node_styler»   r   )rA   rk   ÚtemplateÚ	__class__Ú	color_mapr#  s      €€€rE   r/  zU_SplitterBase._draw_graph_based_on_node_support.<locals>.CustomDrawer._get_node_styleÖ  sk   ø€ Ý ™7œ7×2Ò2°4Ñ8Ô8�Ø˜?Ð*Ð*Ø,5°kÔ,B�H˜[Ñ)Ð)Ø”WÕ 1Ð1Ð1Ø,5°mÔ,D�H˜[Ñ)Ð)à,5°iÔ,@�H˜[Ñ)à�rG   )
rH   rI   rJ   r_   r`   ra   r©   rb   r/  Ú__classcell__)r1  r2  r#  s   @€€rE   ÚCustomDrawerr+  Õ  sb   øø€ € € € € ð	 ¨E¬H¬Mð 	 ¸dÀ3ÈÀ8¼nð 	 ð 	 ð 	 ð 	 ð 	 ð 	 ð 	 ð 	 ð 	 ð 	 ð 	 ð 	 rG   r4  Únode_supportT©Úignore_getattrznode_support.dot)r   Úget_main_dot_graphÚ	write_raw)rA   rÙ   r#  r4  ÚdrawerÚ	dot_graphr2  s     `   @rE   Ú!_draw_graph_based_on_node_supportz/_SplitterBase._draw_graph_based_on_node_supportÌ  s˜   øø€ ð #Ø&Ø$ð
ð 
ˆ	ð
	 ð 
	 ð 
	 ð 
	 ð 
	 ð 
	 ð 
	 ð 
	 �=ñ 
	 ô 
	 ð 
	 ð �˜c >À$ÐGÑGÔGˆØ×-Ò-Ñ/Ô/ˆ	à×ÒÐ.Ñ/Ô/Ð/Ð/Ð/rG   Ú
dump_graphc           
      óæ  ‡— t          | j                             ¦   «         ¦  «        }g }t          t          ¦  «        }t          t          ¦  «        }dt
          j        j        dt
          j        d z  fd„Š| j        j	        j
        D �];}|j        t          vrŒt          ||¦  «        }ˆfd„|j        D ¦   «         }t          |¦  «        t!          d„ t#          t%          |¦  «        ¦  «        D ¦   «         t          |¦  «        ¦  «        z
  }	t'          |d |	…         ¦  «        }
t'          ˆfd„|j                             ¦   «         D ¦   «         ¦  «        }| j                             ||¦  «        r4|                     |¦  «         ||                              |
|f¦  «         �Œ||                              |
|f¦  «         �Œ=|r|                      | j        |¦  «         d}|                     ¦   «         D ](\  }}|D ] \  }
}||› d|
› d	t          |¦  «        › d
�z  }Œ!Œ)|dz  }|                     ¦   «         D ](\  }}|D ] \  }
}||› d|
› d	t          |¦  «        › d
�z  }Œ!Œ)t7          |¦  «         |S )NÚargr4   c                 óX   — | j                              d¦  «        }t          |dd ¦  «        S )NÚtensor_metaÚdtype)Úmetarw   Úgetattr)r?  rA  s     rE   Ú	get_dtypez5_SplitterBase.node_support_preview.<locals>.get_dtypeí  s'   € Øœ(Ÿ,š, }Ñ5Ô5ˆKÝ˜;¨°Ñ6Ô6Ð6rG   c                 óh   •— g | ].}t          |t          j        j        ¦  «        r ‰|¦  «        nd ‘Œ/S rV   ©rè   r_   r`   ra   )r�   r?  rE  s     €rE   rž   z6_SplitterBase.node_support_preview.<locals>.<listcomp>ø  sH   ø€ ð ð ð àõ #-¨Sµ%´(´-Ñ"@Ô"@ÐJ�	�	˜#‘”�Àdðð ð rG   c              3   ó$   K  — | ]\  }}|®|V — Œd S rV   rO   )r�   r  rB  s      rE   ú	<genexpr>z5_SplitterBase.node_support_preview.<locals>.<genexpr>ÿ  s8   è è € ð ð á ˜˜5ØÐ(ð à(Ð(Ð(Ð(ðð rG   c              3   óv   •K  — | ]3\  }}t          |t          j        j        ¦  «        ¯$| ‰|¦  «        fV — Œ4d S rV   rG  )r�   Úkr?  rE  s      €rE   rI  z5_SplitterBase.node_support_preview.<locals>.<genexpr>	  s\   øè è € ð 'ð 'á�A�sÝ˜c¥5¤8¤=Ñ1Ô1ð'Ø�I�I˜c‘N”NÐ#ð'ð 'ð 'ð 'ð 'ð 'rG   z$
Supported node types in the model:
z: (z, z)
z&
Unsupported node types in the model:
)r©   r«   rÄ   r   r®   r_   r`   ra   rB  rº   r”   r»   r   r   rC   rn   ÚnextÚ	enumerateÚreversedrç   Úkwargsr¥   r¬   rÅ   rm   rp   r<  ri   )rA   r=  rÆ   r#  Úsupported_node_typesÚunsupported_node_typesrk   ÚtargetÚ
arg_dtypesÚ
last_indexÚarg_dtypes_tupleÚkwarg_dtypes_tupleÚreportsÚtÚdtypesrE  s                  @rE   Únode_support_previewz"_SplitterBase.node_support_previewæ  s%  ø€ Ý˜$œ+×3Ò3Ñ5Ô5Ñ6Ô6ˆ
à$&ˆÝ*­3Ñ/Ô/ÐÝ!,­SÑ!1Ô!1Ðð	7�5œ8œ=ð 	7­U¬[¸4Ñ-?ð 	7ð 	7ð 	7ð 	7ð ”KÔ%Ô+ð $	ñ $	ˆDØŒwÕ/Ð/Ð/Øå$ Z°Ñ6Ô6ˆFðð ð ð àœ9ðñ ô ˆJõ ˜Z™œ­4ðð å$-­h°zÑ.BÔ.BÑ$CÔ$Cðñ ô õ
 �J‘”ñ,ô ,ñ ˆJõ  % Z°°°Ô%<Ñ=Ô=ÐÝ!&ð 'ð 'ð 'ð 'à"œk×/Ò/Ñ1Ô1ð'ñ 'ô 'ñ "ô "Ðð Ô$×6Ò6°zÀ4ÑHÔHð Ø×&Ò& tÑ,Ô,Ð,Ø$ VÔ,×0Ò0Ð2BÐDVÐ1WÑXÔXÐXÑXà& vÔ.×2Ò2Ø%Ð'9Ð:ñô ð ñ ð ð 	QØ×2Ò2°4´;ÀÑPÔPÐPà:ˆØ-×3Ò3Ñ5Ô5ð 	Vð 	V‰IˆAˆvØ8>ð Vð VÑ4Ð Ð"4Ø˜aÐUÐUÐ$4ÐUÐU½Ð=OÑ8PÔ8PÐUÐUÐUÑU��ðVð 	Ð=Ñ=ˆØ/×5Ò5Ñ7Ô7ð 	Vð 	V‰IˆAˆvØ8>ð Vð VÑ4Ð Ð"4Ø˜aÐUÐUÐ$4ÐUÐU½Ð=OÑ8PÔ8PÐUÐUÐUÑU��ðVõ 	ˆg‰Œˆð ˆrG   c                 óæ  ‡‡‡— dŠ|                       ¦   «         }t          d„ |D ¦   «         ¦  «        }t          |¦  «        |z
  }‰dt          |¦  «        › d�z  Š‰d|› d|› d�z  Š|                      |¦  «        }t          d„ |D ¦   «         ¦  «        }t          |¦  «        |z
  }‰d	t          |¦  «        › d�z  Š‰d|› d|› d�z  Št          |¦  «        D ];\  }}‰|j        rd
|› d�n| j        › |› d�z  Š‰t          |j        ¦  «        › d�z  ŠŒ<|                      |¦  «         |                      d¬¦  «        }| 	                    ¦   «          |rXt          |dd¬¦  «        }|                     ¦   «         }	|	                     ¦   «         D ]\  }
}|                     |
› d�¦  «         Œ| j        }d}|j        j        D �]}|j        dk    �rýd|j        v �ró‰d|j        › d�z  Št%          ||j        ¦  «        Šdt&          j        j        dt&          j        j        dt,          t.                   dt0          t.          df         fd„} ||‰| j        ¦  «        } t5          ‰¦  «        j        |Ž  d}dŠ‰dz  Š‰j        j        D ]Q}|j        dk    r7t9          |¦  «        s‰d|j        › d �z  Šn|t=          ‰|¦  «        d         z  }|j        d!k    r|}ŒR‰d"z  Šd#t&          j        j        dd fˆˆˆfd$„}tA          |j!        |¦  «         | j        tE          |‰¦  «        z  }‰d%|› d&‰› d'�z  Š‰d(|› d)�z  Š||k     r	|}|j        }	 |  #                    ‰|¦  «        }n/# tH          $ r" ‰d*z  Š‰|  %                    ‰|¦  «        z  ŠY �ŒÌw xY w	  ||Ž  ‰d+z  Š�ŒÝ# tH          $ r" ‰d,z  Š‰|  %                    ‰|¦  «        z  ŠY �Œw xY w�Œ‰d-|› d'�z  Š‰d.|› d/�z  ŠtM          ‰¦  «         ‰S )0Nrq   c                 ó    — g | ]}|j         ¯	|‘ŒS rO   ©rÌ   ©r�   Úgs     rE   rž   z/_SplitterBase.split_preview.<locals>.<listcomp>,  ó   € Ð BÐ BÐ B q¸¼Ð B Ð BÐ BÐ BrG   z+Before removing small acc subgraphs, total z subgraphs are created:rY   ú acc subgraphs and z cpu subgraphs.
c                 ó    — g | ]}|j         ¯	|‘ŒS rO   r]  r^  s     rE   rž   z/_SplitterBase.split_preview.<locals>.<listcomp>2  r`  rG   z*After removing small acc subgraphs, total Ú_run_on_acc_rX   z	 node(s)
T)Ú
remove_tagÚpreviewr6  z.dotÚcall_moduleÚaccz
Processing acc submodule r�   Úmain_modÚsubmodÚexample_inputsr4   .c                 óä   ‡— d Šdt           j        j        dt          t          df         dd fˆfd„}|                     |¦  «        } | |Ž  |                     ¦   «          ‰€t          d¦  «        ‚‰S )NrA   rÔ   .r4   c                 ó   •— |Šd S rV   rO   )rA   rÔ   Ú
sub_inputss     €rE   Ú
get_inputszJ_SplitterBase.split_preview.<locals>.get_submod_inputs.<locals>.get_inputsZ  s   ø€ ð &,˜
˜
˜
rG   z'Forward pre-hook did not capture inputs)r_   rå   ræ   rç   r   rë   r¶   rø   )rh  ri  rj  rn  Úhandlerm  s        @rE   Úget_submod_inputsz6_SplitterBase.split_preview.<locals>.get_submod_inputsS  s–   ø€ ð
 :>�Jð,Ý#œhœoð,Ý7<½SÀ#¸X´ð,àð,ð ,ð ,ð ,ð ,ð ,ð $×=Ò=¸jÑIÔI�FØ�H˜nÐ-Ð-Ø—M’M‘O”O�OØ!Ð)Ý,Ð-VÑWÔWÐWØ%Ð%rG   r   zChecking inputs...
ÚplaceholderzInput ú= is not a tensor, this might cause problems during lowering!
r  zChecking outputs...
rk   c                 óx   •— t          | ¦  «        s‰d| j        › d�z  Šd S ‰t          ‰| ¦  «        d         z  Šd S )NzOutput rr  r   )r   r[   r   )rk   rW  ri  Útotal_output_bytess    €€€rE   Ú	get_bytesz._SplitterBase.split_preview.<locals>.get_bytesy  sS   ø€ õ 1°Ñ6Ô6ð PØÐ#v¨T¬YÐ#vÐ#vÐ#vÑv˜˜˜à*Õ.>¸vÀtÑ.LÔ.LÈQÔ.OÑOÐ*Ð*Ð*rG   zTotal input size in bytes is z , total output size in bytes is r›   zF theoretical max qps (bounds by PCIe bandwidth) for this submodule is z.
z#Run into an error during lowering!
zLowering and running succeed!
z$Run into an error during inference!
zB
Theoretical max qps (bounds by PCIe bandwidth) for this model is z bottleneck is submodule ú.)'Úput_nodes_into_subgraphsrn   Úremove_small_acc_subgraphsrM  rÌ   rô   r”   Útagr¤   Úevalr   Úget_all_dot_graphsr¥   r9  ÚPCIe_BWrº   r»   rR  rD  r_   r`   rÉ   r   r   rç   rò   r   rù   r   r[   r   ra   r   rC   Úmaxr   ÚRuntimeErrorr"  ri   )rA   r=  Ú	subgraphsÚacc_subgraphs_numÚcpu_subgraphs_numr  ÚsubgraphÚ	split_modr:  Ú
dot_graphsr[   r;  Úmax_qpsÚbottleneck_modulerk   rp  Úsubmod_inputsÚtotal_input_bytesrÇ   Úoutput_noderu  ÚqpsÚlowered_submodrW  ri  rt  s                          @@@rE   Úsplit_previewz_SplitterBase.split_preview)  s€  øøø€ ØˆØ×1Ò1Ñ3Ô3ˆ	ÝÐ BÐ B¨IÐ BÑ BÔ BÑCÔCÐÝ 	™NœNÐ->Ñ>ÐØÐhÅÀYÁÄÐhÐhÐhÑhˆØÐaÐ(ÐaÐaÐ=NÐaÐaÐaÑaˆà×3Ò3°IÑ>Ô>ˆ	ÝÐ BÐ B¨IÐ BÑ BÔ BÑCÔCÐÝ 	™NœNÐ->Ñ>ÐØÐgÅÀIÁÄÐgÐgÐgÑgˆØÐaÐ(ÐaÐaÐ=NÐaÐaÐaÑaˆå$ YÑ/Ô/ð 	:ð 	:‰KˆAˆxØà”?ð;Ð$˜qÐ$Ð$Ð$Ð$àÔ3Ð:°QÐ:Ð:Ð:ñˆGð
 �#˜hœnÑ-Ô-Ð9Ð9Ð9Ñ9ˆGˆGà�Š�ÑÔÐØ—J’J¨$�JÑ/Ô/ˆ	Ø�ŠÑÔÐàð 	3Ý" 9¨iÈÐMÑMÔMˆFØ×2Ò2Ñ4Ô4ˆJØ#-×#3Ò#3Ñ#5Ô#5ð 3ð 3‘��ià×#Ò# t M M MÑ2Ô2Ð2Ð2àœˆØÐà”OÔ)ð J	Añ J	AˆDØŒw˜-Ò'Ñ'¨E°T´[Ð,@Ñ,@ØÐH¸¼ÐHÐHÐHÑH�å  ¨D¬KÑ8Ô8�ð&Ý#œhÔ2ð&å!œHÔ0ð&õ %-­S¤Mð&õ �3 ˜8”_ð	&ð &ð &ð &ð( !2Ð 1°)¸VÀTÔEVÑ WÔ W�Ø+•	˜&Ñ!Ô!Ô+¨]Ð;Ð;à$%Ð!Ø%&Ð"àÐ1Ñ1�ØœÔ+ð (ð (�AØ”t˜}Ò,Ð,Ý4°QÑ7Ô7ð PØ#Ð'v°´Ð'vÐ'vÐ'vÑv˜G˜Gà-Õ1AÀ&È!Ñ1LÔ1LÈQÔ1OÑOÐ-Ø”t˜xÒ'Ð'Ø&'˜øàÐ2Ñ2�ðP¥E¤H¤Mð P°dð Pð Pð Pð Pð Pð Pð Pð Põ ˜Ô(¨)Ñ4Ô4Ð4Ø”l¥SÐ):Ð<NÑ%OÔ%OÑO�Øð  DÐ;Lð  Dð  Dð  oAð  Dð  Dð  Dñ  D�ØÐlÐdgÐlÐlÐlÑl�à˜’=�=Ø!�GØ(,¬Ð%ðØ%)×%AÒ%AÀ&È-Ñ%XÔ%X�N�NøÝ#ð ð ð ØÐEÑE�GØ˜t×1Ò1°&¸-ÑHÔHÑH�GØ‘Hðøøøð
AØ"�N MÐ2Ð2ð
 Ð@Ñ@�G‘Gøõ	 $ð Ið Ið IØÐFÑF�GØ˜t×1Ò1°&¸-ÑHÔHÑH�G�G‘GðIøøøùð 	ÐcÐY`ÐcÐcÐcÑcˆØÐCÐ/@ÐCÐCÐCÑCˆÝˆg‰Œˆð ˆs$   ÍM#Í#(NÎNÎNÎ(OÏ
OÚtag_idc                 óB  — t          t          ¦  «        }| j        j        j        D ]x}|j        t          vrŒ|j        D ]_}|j        t          vrŒ|�1t          |j	         
                    d¦  «        d         ¦  «        |k     r||                              |¦  «         Œ`Œy|S )z«
        Builds reversed topological node dependencies, if tag_id is specified,
        we ignore nodes that are in later subgraph i.e. nodes have greater tag_id.
        NÚ_r/   )r   r®   r«   rº   r”   r»   r   rµ   r?   ry  r¤   rp   )rA   r�  Úresultrk   r·   s        rE   Úfind_reverse_depsz_SplitterBase.find_reverse_deps¤  sª   € õ 0;½3Ñ/?Ô/?ˆà”KÔ%Ô+ð 		+ð 		+ˆDØŒwÕ/Ð/Ð/Øàœ
ð +ð +�Ø”7Õ"3Ð3Ð3Øà�>¥c¨$¬(¯.ª.¸Ñ*=Ô*=¸bÔ*AÑ&BÔ&BÀVÒ&KÐ&KØ˜4”L×$Ò$ TÑ*Ô*Ð*øð+ð ˆrG   rý   c                 ó€  — t          ¦   «         }| j                             ¦   «         D ]•\  }}||v rŒ
t          ¦   «         }|D ]}|                     ||         ¦  «         Œ|                     |¦  «         |D ]E}|||<   |j        D ]!}||vr||                              |¦  «         Œ"|                     |¦  «         ŒFŒ–d S rV   )r®   rú   r¥   r  Údifference_updateÚall_input_nodesrp   )rA   rý   Úprocessed_noderk   r  Únew_deprÇ   r?  s           rE   Úupdate_reverse_deps_for_fusionsz-_SplitterBase.update_reverse_deps_for_fusionsº  sû   € õ ™œˆà œL×.Ò.Ñ0Ô0ð 	&ð 	&‰LˆD�&Ø�~Ð%Ð%Øå‘e”eˆGð ð (ð (�Ø—’˜t AœwÑ'Ô'Ð'Ð'ð ×%Ò% fÑ-Ô-Ð-ð ð &ð &�Ø!��Q‘àÔ,ð 1ð 1�CØ &Ð(Ð(Ø˜Sœ	×(Ò(¨Ñ0Ô0Ð0øà×"Ò" 1Ñ%Ô%Ð%Ð%ð&ð	&ð 	&rG   ry  c                 óì   — t          ¦   «         }| j        j        j        D ]S}|j        t
          v rC|j        |k    r8|j        D ]0}|j        t
          v r |j        |k    r|                     |¦  «         Œ1ŒT|S )zï
        Finds parent nodes of the `tag` subgraph.

        Traverse the inputs of nodes in the subgraph, if input doesn't belong to the subgraph
        and is not a placeholder, we consider it as the parent node of the subgraph.
        )	r®   r«   rº   r”   r»   r   ry  r”  rp   )rA   ry  Úparent_nodesrk   r?  s        rE   Úfind_parent_nodes_of_subgraphz+_SplitterBase.find_parent_nodes_of_subgraph×  s‚   € õ ‘u”uˆà”KÔ%Ô+ð 	.ð 	.ˆDØŒwÕ+Ð+Ð+°´¸C²°ØÔ/ð .ð .�CØ”vÕ!2Ð2Ð2°s´wÀ#²~°~Ø$×(Ò(¨Ñ-Ô-Ð-øøàÐrG   c                 ón  — |                       t          |                     dd¬¦  «        d         ¦  «        ¬¦  «        }|                      |¦  «         |                      |¦  «        }t          ¦   «         }|r¼d}|D ]}||         |k    r|| j        v r|} nŒ|€dS ||_        |                     |¦  «         | 	                    |¦  «         || j
        v r)| j
        |         D ]}||vr| 	                    |¦  «         Œ|j        D ])}|j        t          v r||vr| 	                    |¦  «         Œ*|°ºdS dS )z^
        Extend the acc subgraph with `tag` going the reversed topological direction.
        r�  r   )Úmaxsplitr/   )r�  N)r‘  r?   Úrsplitr—  rš  r®   r¯   ry  r¶   rp   rú   r”  r»   r   )	rA   ry  rý   r™  Úvisited_nodesrk   rÇ   Úfusion_noder?  s	            rE   Úextend_acc_subgraphz!_SplitterBase.extend_acc_subgraphè  sŒ  € ð ×%Ò%­S°·²¸CÈ!°Ñ1LÔ1LÈRÔ1PÑ-QÔ-QÐ%ÑRÔRˆØ×,Ò,¨TÑ2Ô2Ð2ð ×9Ò9¸#Ñ>Ô>ˆå!$¡¤ˆàð 	*ØˆDð "ð ð �Ø˜”7˜mÒ+Ð+°°T´^Ð0CÐ0CØ�DØ�Eøàˆ|Ø�ð ˆDŒHØ×Ò Ñ%Ô%Ð%Ø×Ò˜dÑ#Ô#Ð#ð �t”|Ð#Ð#Ø#'¤<°Ô#5ð 6ð 6�KØ"¨-Ð7Ð7Ø$×(Ò(¨Ñ5Ô5Ð5øð Ô+ð *ð *�Ø”6Õ.Ð.Ð.°3¸mÐ3KÐ3KØ ×$Ò$ SÑ)Ô)Ð)øð5 ð 	*ð 	*ð 	*ð 	*ð 	*rG   c                 ó¨  — t          ¦   «         }t          ¦   «         }| j        j        j        D ]¡}|j        dk    rLt          |j        ¦  «        dk    r4|| j        v r|                     |¦  «         n|                     |¦  «         |j        dvrŒc|j	        D ]6}|| j        v r|                     |¦  «         Œ!|                     |¦  «         Œ7Œ¢||fS )zK
        Finds nodes that consume module inputs or get_attr nodes.
        Úcall_functionr   >   Úget_attrrq  )
r®   r«   rº   r”   r»   rn   r”  r¯   rp   rµ   )rA   Ústarter_cpu_nodesÚstarter_acc_nodesrk   r·   s        rE   Ústarter_nodesz_SplitterBase.starter_nodes  sù   € õ &)¡U¤UÐÝ%(¡U¤UÐØ”KÔ%Ô+ð 	0ð 	0ˆDàŒw˜/Ò)Ð)­c°$Ô2FÑ.GÔ.GÈ1Ò.LÐ.LØ˜4œ>Ð)Ð)Ø%×)Ò)¨$Ñ/Ô/Ð/Ð/à%×)Ò)¨$Ñ/Ô/Ð/àŒwÐ9Ð9Ð9Øàœ
ð 0ð 0�Ø˜4œ>Ð)Ð)Ø%×)Ò)¨$Ñ/Ô/Ð/Ð/à%×)Ò)¨$Ñ/Ô/Ð/Ð/ð	0ð !Ð"3Ð3Ð3rG   c                 ó¢  ‡ ‡	— ‰                       ¦   «         \  }}t          ¦   «         Š	t          ˆ fd„|D ¦   «         ¦  «         }g }g }|s|�rK|r|n|}t          ˆ ˆ	fd„|D ¦   «         d ¦  «        }|€;|st	          d¦  «        ‚|                     t          ||¬¦  «        ¦  «         | }g }Œe|                     |¦  «         ‰	                     |¦  «         |                     |¦  «         |‰ j	        v rP|‰ j
        v r$|                     ‰ j	        |         ‰	z
  ¦  «         n#|                     ‰ j	        |         ‰	z
  ¦  «         |j        D ]E}|j        t          vrŒ|‰ j
        v r|                     |¦  «         Œ0|                     |¦  «         ŒF|�°H|�°K|r$|                     t          ||¬¦  «        ¦  «         |st	          d¦  «        ‚|S )Nc              3   óT   •K  — | ]"}t          ‰j        |         ¦  «        d k    V — Œ#dS )r   N)rn   rý   )r�   rÇ   rA   s     €rE   rI  z9_SplitterBase.put_nodes_into_subgraphs.<locals>.<genexpr>6  s6   øè è € Ð$WÐ$WÀ¥S¨¬°1¬Ñ%6Ô%6¸!Ò%;Ð$WÐ$WÐ$WÐ$WÐ$WÐ$WrG   c              3   ó>   •K  — | ]}‰j         |         ‰k    ¯|V — Œd S rV   )rý   )r�   rÇ   rA   rž  s     €€rE   rI  z9_SplitterBase.put_nodes_into_subgraphs.<locals>.<genexpr>@  s3   øè è € ÐKÐK�q¨T¬Y°q¬\¸]Ò-JÐ-J�Ð-JÐ-JÐ-JÐ-JÐKÐKrG   zSubgraph can't be empty)rÌ   r”   zCouldn't create subgraphs)r¦  r®   ÚanyrL  r   rm   r   r¶   rp   rú   r¯   r  rµ   r»   r   )
rA   Úcurrent_cpu_nodesÚcurrent_acc_nodesÚacc_subgraphÚcurrent_subgraph_nodesr  Úcurrent_nodesrk   r·   rž  s
   `        @rE   rw  z&_SplitterBase.put_nodes_into_subgraphs/  se  øø€ à/3×/AÒ/AÑ/CÔ/CÑ,ÐÐ,Ý!$¡¤ˆõ "%Ð$WÐ$WÐ$WÐ$WÐEVÐ$WÑ$WÔ$WÑ!WÔ!WÐWˆà+-Ðð %'ˆ	Øð (	0Ð#4ñ (	0à1=ÐTÐ-Ð-ÐCTˆMÝØKÐKÐKÐKÐK˜MÐKÑKÔKØñô ˆDð ˆ|Ø-ð PÝ4Ð5NÑOÔOÐOà× Ò Ý LÐ8NÐOÑOÔOñô ð ð $0Ð/�Ø)+Ð&Øà× Ò  Ñ&Ô&Ð&Ø×Ò˜dÑ#Ô#Ð#Ø"×)Ò)¨$Ñ/Ô/Ð/ð �t”|Ð#Ð#Ø˜4œ>Ð)Ð)Ø%×,Ò,¨T¬\¸$Ô-?À-Ñ-OÑPÔPÐPÐPà%×,Ò,¨T¬\¸$Ô-?À-Ñ-OÑPÔPÐPð œ
ð 0ð 0�Ø”7Õ"3Ð3Ð3Øð ˜4œ>Ð)Ð)Ø%×)Ò)¨$Ñ/Ô/Ð/Ð/à%×)Ò)¨$Ñ/Ô/Ð/Ð/ðQ  ñ (	0Ð#4ñ (	0ðV "ð 	Ø×ÒÝ Ð4JÐKÑKÔKñô ð ð ð 	JÝ,Ð-HÑIÔIÐIàÐrG   r  c                 ó  — g }|D �]}|j         r®t          |j        ¦  «        | j        j        k    r|                     |¦  «         ŒBt          dt          |j        ¦  «        › d| j        j        › �¦  «         |r&|d         j                             |j        ¦  «         Œ›d|_         |                     |¦  «         Œ¸|r3|d         j         s&|d         j                             |j        ¦  «         Œí|                     |¦  «         �Œ|S )z„
        This pass finds ACC submodules with less than specified size and merges
        them with adjacent CPU submodules.
        zBEliminating acc subgraph because it's smaller than the threshold: z < r/   F)rÌ   rn   r”   ró   r0   rm   ri   Úextend)rA   r  r�  r‚  s       rE   rx  z(_SplitterBase.remove_small_acc_subgraphsq  s,  € ð
 "$ˆØ!ð 	,ñ 	,ˆHØŒð ,Ý�x”~Ñ&Ô&¨$¬-Ô*KÒKÐKØ—M’M (Ñ+Ô+Ð+Ð+åðWÝ˜xœ~Ñ.Ô.ðWð WØ37´=Ô3TðWð Wñô ð ð ð 0Ø˜rœ
Ô(×/Ò/°´Ñ?Ô?Ð?Ð?à*/˜œØŸš hÑ/Ô/Ð/Ð/àð , &¨¤*Ô"3ð ,Ø˜2”JÔ$×+Ò+¨H¬NÑ;Ô;Ð;Ð;à—M’M (Ñ+Ô+Ð+Ñ+ØˆrG   c                 óN  — g | _         |D ]š}|j        rdt          | j         ¦  «        › �n| j        › t          | j         ¦  «        › �}| j                              |¦  «         |j        D ];}t          |d¦  «        rt          d|› d�¦  «        ‚||_        || j	        |j
        <   Œ<Œ›d S )Nrc  ry  zNode z was already tagged)r  rÌ   rn   rô   rm   r”   Úhasattrr   ry  rÿ   r[   )rA   r  r‚  ry  rk   s        rE   ry  z_SplitterBase.tagŒ  s×   € ØˆŒ	Ø!ð 	:ð 	:ˆHð ”?ðFÐ/�s 4¤9™~œ~Ð/Ð/Ð/àÔ3ÐEµS¸¼±^´^ÐEÐEð ð
 ŒI×Ò˜SÑ!Ô!Ð!Ø œð :ð :�Ý˜4 Ñ'Ô'ð XÝ4Ð5V¸TÐ5VÐ5VÐ5VÑWÔWÐWà�”Ø69�Ô(¨¬Ñ3Ð3ð:ð	:ð 	:rG   rd  c                 ó˜   — t          | j        | j        | j        ¬¦  «        }|r&| j        j        j        D ]}t          |d¦  «        r|`Œ|S )N)rõ   ry  )r   r«   r  r   rº   r”   r³  ry  )rA   rd  rÐ   rk   s       rE   r¤   z_SplitterBase.splitœ  sc   € Ý$ØŒK˜œ°Ô1Cð
ñ 
ô 
ˆð ð 	!ØœÔ)Ô/ð !ð !�Ý˜4 Ñ'Ô'ð !Ø˜øØÐrG   c                 ó^  — |                       ¦   «         }| j        j        rt          |¦  «         |                      |¦  «        }t	          d„ |D ¦   «         ¦  «        }t	          |¦  «        |z
  }t          d|› d|› d�¦  «         |                      |¦  «         |                      ¦   «         S )Nc                 ó    — g | ]}|j         ¯	|‘ŒS rO   r]  )r�   Úss     rE   rž   z*_SplitterBase.__call__.<locals>.<listcomp>«  s   € Ð"DÐ"DÐ"D¨¸1¼8Ð"D 1Ð"DÐ"DÐ"DrG   zGot ra  z non-acc subgraphs)rw  ró   r   rx  rn   ri   ry  r¤   )rA   r  Úacc_subgraphs_countÚnon_acc_subgraphs_counts       rE   rÈ   z_SplitterBase.__call__¦  s¼   € Ø×1Ò1Ñ3Ô3ˆ	ØŒ=Ô:ð 	9Ý-¨iÑ8Ô8Ð8Ø×3Ò3°IÑ>Ô>ˆ	Ý!Ð"DÐ"D¨iÐ"DÑ"DÔ"DÑEÔEÐÝ"% i¡.¤.Ð3FÑ"FÐÝØfÐ&ÐfÐfÐ;RÐfÐfÐfñ	
ô 	
ð 	
ð 	�Š�ÑÔÐØ�zŠz‰|Œ|ÐrG   c                 óH  —  | ¦   «         }g }|                      ¦   «         D ]\  }}|                     |¦  «         Œ| j        j        dk    r,t	          |¦  «        | j        j        k    rt          d¦  «        ‚t          || j        |¦  «        }t          ||| j	        ¦  «        S )Nr   ziCannot fulfill max_acc_splits limit. This may cause split fragmentation and result in performance issues.)
Únamed_childrenrm   ró   r3   rn   Ú
ValueErrorr!   rò   r    rô   )rA   rÐ   Úsubmodule_namesr[   Ú_modrÑ   s         rE   Úgenerate_split_resultsz$_SplitterBase.generate_split_results³  s»   € Ø�t‘v”vˆØ%'ˆØ&×5Ò5Ñ7Ô7ð 	)ð 	)‰JˆD�$Ø×"Ò" 4Ñ(Ô(Ð(Ð(àŒMÔ(¨1Ò,Ð,Ý�OÑ$Ô$ t¤}Ô'CÒCÐCåð0ñô ð õ :Ø˜$Ô+¨_ñ
ô 
Ðõ ˜<Ð)9¸4Ô;VÑWÔWÐWrG   )rñ   FNr§   ©FrV   )0rH   rI   rJ   r^   r|  r_   r`   rÉ   r   r   r   r.   rb   rN   r   rF   r©   r  ra   r   rü   rþ   rû   r   rå   ræ   r   r"  r   r<  rZ  rŒ  r?   r‘  r—  rš  r   rç   r¦  r    r   rw  rx  ry  r¤   rÈ   r    r¿  rO   rG   rE   rð   rð   é  sÔ  € € € € € ð(ð (ðV €Gð '5Ø"Ø37ð/"ð /"à”Ô$ð/"ð ˜s”mð/"ð .ð	/"ð
 'ð/"ð !$ð/"ð ð/"ð *¨DÑ0ð/"ð 
ð/"ð /"ð /"ð /"ðj(¨¨S°#¨X¬ð (ð (ð (ð (ð˜4 ¤¤¨wÐ 6Ô7ð ð ð ð ð$2ð 2ð 2ð 2ð?2ð ?2ð ?2ð ?2ðJØ”8Ô'ðØ18ðà	ŒŒðð ð ð ð_ ¤Ô!5ð _¸wð _È3ð _ð _ð _ð _ð0Ø”8Ô'ð0Ø:Bð0à	ð0ð 0ð 0ð 0ð4Að A¨tð AÀð Að Að Að AðFuð u¨ð u¸ð uð uð uð uðx $(ðð Ø˜D‘jðà	ˆeŒhŒm˜WÐ$Ô	%ðð ð ð ð,&Ø˜œœ¨Ð/Ô0ð&à	ð&ð &ð &ð &ð:°ð ¸ð ð ð ð ð"(* sð (*¨tð (*ð (*ð (*ð (*ð\4˜u W¨gÐ%5Ô6ð 4ð 4ð 4ð 4ð2@¨$¨x¬.ð @ð @ð @ð @ðD°D¸´Nð ÀtÈHÄ~ð ð ð ð ð6:˜T (œ^ð :°ð :ð :ð :ð :ð ð  ð °´Ô1Eð ð ð ð ð˜%œ(Ô.ð ð ð ð ðX¨ð Xð Xð Xð Xð Xð XrG   rð   rÀ  )Ir<   rÝ   r„   r¡   Úcollectionsr   Úcollections.abcr   r   r   Údataclassesr   Útypingr   r	   r
   r   r_   Útorch._loggingr   Útorch.fx._compatibilityr   Útorch.fx.noder   Ú"torch.fx.passes.graph_manipulationr   Úgraph_drawerr   r¬   r   r   Ú
shape_propr   Úsplit_utilsr   r   Útools_commonr   r   r   r   r   r   Ú__all__rK   rL   rM   ÚTRACKER_DUMP_PATHr—   rŸ   Ú$ENV_FX_NET_ACC_SPLITTER_TRACKER_MODEÚ)ENV_FX_NET_ACC_SPLITTER_TRACKER_DUMP_PATHr£   r¢   rw   r°   r,   rÎ   r.   r"   r#   r   rí   r   r   r    rå   ræ   rb   rN   r©   r!   rð   rO   rG   rE   ú<module>rÑ     sÌ  ðØ €€€€Ø €€€Ø €€€Ø 	€	€	€	Ø #Ð #Ð #Ð #Ð #Ð #Ø 8Ð 8Ð 8Ð 8Ð 8Ð 8Ð 8Ð 8Ð 8Ð 8Ø !Ð !Ð !Ð !Ð !Ð !Ø /Ð /Ð /Ð /Ð /Ð /Ð /Ð /Ð /Ð /Ð /Ð /à €€€Ø +Ð +Ð +Ð +Ð +Ð +Ø 1Ð 1Ð 1Ð 1Ð 1Ð 1Ø !Ð !Ð !Ð !Ð !Ð !Ø ?Ð ?Ð ?Ð ?Ð ?Ð ?à 'Ð 'Ð 'Ð 'Ð 'Ð 'Ø BÐ BÐ BÐ BÐ BÐ BÐ BÐ BØ !Ð !Ð !Ð !Ð !Ð !Ø IÐ IÐ IÐ IÐ IÐ IÐ IÐ Iðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ðð ð €ð  Ð ØÐ Ø Ð ð &Ð Ø€Ø€
à'IÐ $Ø,SÐ )à/ð .ð Œj�nŠnØ-Ð/@ñô €ðð -/¬J¯NªNØ(¨#ñ-ô -€ˆgÐ(Ô)ð ð ñ ð
H
ð H
ð H
ð H
ð H
ñ H
ô H
ð H
ðV € eÐ,Ñ,Ô,ðWð Wð Wð Wð Wñ Wô Wñ -Ô,ðWð. € eÐ,Ñ,Ô,ðv'ð v'ð v'ð v'ð v'ñ v'ô v'ñ -Ô,ðv'ðr € eÐ,Ñ,Ô,ðnð nð nð nð nñ nô nñ -Ô,ðnðb € eÐ,Ñ,Ô,ð	ð 	ð 	ð 	ð 	 ñ 	ô 	ñ -Ô,ð	ð € eÐ,Ñ,Ô,Ø
ð&ð &ð &ð &ð &ñ &ô &ñ „ñ -Ô,ð&ð € eÐ,Ñ,Ô,ð"ð "ð "ð "ð "�*ñ "ô "ñ -Ô,ð"ð  € eÐ,Ñ,Ô,ð
 ð	-ð -ØŒ8Œ?ð-à�SŒMð-ð   ”}ð-ð ð	-ð
 
ˆ#ˆsˆ(„^ð-ð -ð -ñ -Ô,ð-ð`\Xð \Xð \Xð \Xð \Xñ \Xô \Xð \Xð \Xð \XrG   