Ë
    f^(hÕƒ  ã                   ól  — d dl Z d dlZd dl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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mZ d	dlmZ d	dlmZ d	dlmZm Z m!Z!m"Z"m#Z#m$Z$ g d¢Z% ejL                  e'«      Z(d	Z)dZ*dZ+ G d„ d«      Z, ed¬«       G d„ d«      «       Z- ed¬«       G d„ de.«      «       Z/ ed¬«      e	 G d„ d«      «       «       Z0 ed¬«       G d„ de«      «       Z1 ed¬«      	 d$dejd                  jf                  dee   dee4   de5d e6e4ef   f
d!„«       Z7 G d"„ d#«      Z8y)%é    N)Údefaultdict)ÚIterableÚSequence)Ú	dataclass)ÚAnyÚ
NamedTupleÚOptional)Úcompatibility)Úmap_arg)Úget_size_of_nodeé   )ÚFxGraphDrawer)Úget_node_targetÚOperatorSupportBase)Ú	ShapeProp)Úsplit_by_tags)ÚCALLABLE_NODE_OPSÚFxNetAccFusionsFinderÚis_node_output_tensorÚNodeListÚNodeSetÚTensors)ÚFxNetAccNodesFinderÚFxNetSplitterInternalErrorÚSubgraphÚSplitResultÚgenerate_inputs_for_submodulesFc                   ó"   — e Zd Zeeedfdefd„Zy)Ú_SplitterSettingBaseéÿÿÿÿÚmax_acc_splitsc                 óÚ  — t        j                  «       }|j                  dddt        d¬«       |j                  dddt        d¬«       |j                  d	d
ddd¬«       |j                  ddddd¬«       |j	                  «       \  }}|j
                  r|j
                  n|| _        |j                  r|j                  n|| _        |j                  r|j                  n|| _        || _        y )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 constrain, setting this to false is recommended as it can reduce overhead.)ÚdefaultÚactionr%   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.)	ÚargparseÚArgumentParserÚadd_argumentÚintÚparse_known_argsÚmin_acc_module_sizeÚskip_fusionÚallow_non_tensorr!   )Úselfr.   r/   r0   r!   ÚparserÚargsÚ_unknowns           ú[/var/www/skyplay_api_hub/venv/lib/python3.12/site-packages/torch/fx/passes/splitter_base.pyÚ__init__z_SplitterSettingBase.__init__,   s  € ô ×(Ñ(Ó*ˆØ×ÑØ#Ø#ØÜØAð 	ô 	
ð 	×ÑØØØÜØ?ð 	ô 	
ð 	×ÑØØØØð#ð 	ô 		
ð 	×ÑØ Ø ØØðVð 	ô 	
ð  ×0Ñ0Ó2‰ˆˆhð ×'Ò'ð ×$Ò$à$ð 	Ô ð
 6:×5EÒ5E ×!1Ò!1È;ˆÔà%)×%:Ò%:ˆD×!Ò!Ð@Pð 	Ôð $2ˆÕó    N)Ú__name__Ú
__module__Ú__qualname__ÚDEFAULT_MIN_ACC_MODULE_SIZEÚDEFAULT_SKIP_FUSIONÚDEFAULT_ALLOW_NON_TENSORr,   r6   © r7   r5   r   r   +   s   „ ð 8Ø'Ø1Ø ñ72ð
 ô72r7   r   )Úis_backward_compatiblec                   óp   — e Zd ZdZdej
                  j                  dedefd„Z	de
fd„Zd„ Zd	„ Zd
efd„Zy)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_supportr0   c                 óL   — || _         || _        || _        t        «       | _        y ©N)rA   rB   r0   ÚsetÚ	acc_nodes)r1   rA   rB   r0   s       r5   r6   zFxNetAccNodesFinder.__init__u   s$   € ð ˆŒØ 0ˆÔØ 0ˆÔÜ"%£%ˆ�r7   Úcpu_worklistc                 óâ   — |rm|j                  d«      }|j                  D ]I  }|| j                  v sŒ| j                  j                  |«       t	        |«      rŒ9|j                  |«       ŒK |rŒlyy)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   N)ÚpopÚusersrF   Úremover   Úappend)r1   rG   ÚnodeÚusers       r5   Ú(reduce_acc_nodes_non_tensor_input_helperz<FxNetAccNodesFinder.reduce_acc_nodes_non_tensor_input_helper€   sc   € ñ Ø×#Ñ# AÓ&ˆDàŸ
™
ò 2�Ø˜4Ÿ>™>Ò)Ø—N‘N×)Ñ)¨$Ô/Ü0°Õ6Ø$×+Ñ+¨DÕ1ð	2ô r7   c                 óò   — g }| j                   j                  j                  D ]A  }|j                  t        vrŒ|| j
                  v rŒ%t        |«      rŒ1|j                  |«       ŒC | j                  |«       y)z„
        Excludes nodes from ACC supported set that have direct
        upstream CPU nodes that produce non-tensor outputs.
        N)	rA   ÚgraphÚnodesÚopr   rF   r   rL   rO   )r1   Únon_tensor_cpu_nodesrM   s      r5   Ú!reduce_acc_nodes_non_tensor_inputz5FxNetAccNodesFinder.reduce_acc_nodes_non_tensor_input‘   sr   € ð
 *,Ðà—K‘K×%Ñ%×+Ñ+ò 	.ˆDØ�w‰wÔ/Ñ/ØØ�t—~‘~Ñ%ØÜ$ TÔ*ØØ ×'Ñ'¨Õ-ð	.ð 	×5Ñ5Ð6JÕKr7   c                 ó  — 	 g }| j                   D ]@  }t        |«      rŒ|j                  D ]#  }|| j                   vsŒ|j                  |«        Œ@ ŒB |sy|D ]  }| j                   j	                  |«       Œ | j                  |«       Œˆ)z~
        Excludes nodes from ACC supported set that produce non-tensor
        outputs and have downstream CPU nodes.
        N)rF   r   rJ   rL   rK   rO   )r1   Únew_cpu_nodesÚacc_noderN   Únew_cpu_nodes        r5   Ú"reduce_acc_nodes_non_tensor_outputz6FxNetAccNodesFinder.reduce_acc_nodes_non_tensor_output£   s˜   € ð
 Ø&(ˆMà ŸN™Nò �Ü(¨Ô2ØØ$ŸN™Nò �DØ 4§>¡>Ò1Ø%×,Ñ,¨XÔ6Ùñðñ !Øà -ò 4�Ø—‘×%Ñ% lÕ3ð4ð ×9Ñ9¸-ÔHð# r7   Úreturnc                 ó„  — t        | j                  j                  «       «      }| j                  j                  j                  D �ch c]2  }|j
                  t        v r| j                  j                  ||«      r|’Œ4 c}| _	        | j                  s | j                  «        | j                  «        | j                  S c c}w rD   )ÚdictrA   Únamed_modulesrQ   rR   rS   r   rB   Úis_node_supportedrF   r0   rU   rZ   )r1   Ú
submodulesÚns      r5   Ú__call__zFxNetAccNodesFinder.__call__»   sš   € Ü˜$Ÿ+™+×3Ñ3Ó5Ó6ˆ
ð —[‘[×&Ñ&×,Ñ,ö
àØ�t‰tÔ(Ñ(Ø×%Ñ%×7Ñ7¸
ÀAÔFò ò
ˆŒð ×$Ò$Ø×2Ñ2Ô4Ø×3Ñ3Ô5à�~‰~Ðùò
s   Á7B=N)r8   r9   r:   Ú__doc__ÚtorchÚfxÚGraphModuler   Úboolr6   r   rO   rU   rZ   r   rb   r>   r7   r5   r   r   f   sV   „ ñð	(à—‘×$Ñ$ð	(ð .ð	(ð ó		(ð2ÀXó 2ò"Lò$Ið0˜'ô r7   r   c                   ó   — e Zd Zy)r   N)r8   r9   r:   r>   r7   r5   r   r   Ë   s   „ àr7   r   c                   ó6   — e Zd ZU eed<   eed<   dZee   ed<   y)r   Úis_accrR   NÚdevice_ordinal)	r8   r9   r:   rg   Ú__annotations__r   rk   r	   r,   r>   r7   r5   r   r   Ð   s   … ð ƒLØƒOØ$(€N�H˜S‘MÔ(r7   r   c                   ób   — e Zd ZU dZej
                  j                  ed<   ee	e
f   ed<   e	ed<   y)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 alwasy "_run_on_acc_".
    Úsplit_moduleÚsubmodule_inputsÚnon_acc_submodule_prefixN)r8   r9   r:   rc   rd   re   rf   rl   r]   Ústrr   r>   r7   r5   r   r   Ø   s-   … ñð —(‘(×&Ñ&Ó&Ø˜3 ˜8‘nÓ$Ø!Ô!r7   r   ÚmodelÚinputsÚtarget_submodulesÚdeepcopyr[   c                 óœ  ‡‡	‡
‡— g Š	i Š
| j                  «       D ��ci c]  \  }}||“Œ
 c}}Šˆˆ
ˆfd„}| j                  «       D ]*  \  }}||v sŒ‰	j                  |j                  |«      «       Œ, ˆ	fd„}	 t        j                  «       5   | |Ž  ddd«        |«        ‰
S c c}}w # 1 sw Y   ŒxY w# t
        $ r} |«        |‚d}~ww xY w)a~  
    Generate inputs for targeting submdoules 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                 óD   •— ‰rt        j                  |«      n|‰‰|    <   y rD   )Úcopyru   )rA   Úmodule_inputsru   ÚresultsÚsubmodule_to_namess     €€€r5   Úpre_forwardz3generate_inputs_for_submodules.<locals>.pre_forward  s#   ø€ á,4ŒD�M‰M˜-Ô(¸-ð 	Ð" 6Ñ*Ò+r7   c                  ó4   •— ‰D ]  } | j                  «        Œ y rD   )rK   )ÚhÚhandless    €r5   Úclean_up_handlesz8generate_inputs_for_submodules.<locals>.clean_up_handles
  s   ø€ Øò 	ˆAØ�H‰H�Jñ	r7   N)r^   rL   Úregister_forward_pre_hookrd   Úno_gradÚ	Exception)rr   rs   rt   ru   ÚnameÚmodr|   r€   Úer   rz   r{   s      `     @@@r5   r   r   é   sÒ   û€ ð( €GØ€GØ5:×5HÑ5HÓ5J×K©	¨¨c˜#˜t™)ÓKÐö
ð
 ×(Ñ(Ó*ò G‰	ˆˆcØÐ$Ò$Ø�N‰N˜3×8Ñ8¸ÓEÕFðGôðÜ�]‰]‹_ñ 	Ù�6‰N÷	ñ ÔØ€Nùó/ L÷ 	ð 	ûäò ÙÔØˆûðús5   œB"Á7B4 ÂB(ÂB4 Â(B1Â-B4 Â4	CÂ=	CÃCc                   ó8  — 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e   fd„Zdeeef   fd„Zdeej                  j&                  ef   fd„Zd„ Zdej                  j                  dedej0                  j2                  fd„Zdej                  j                  dedefd„Zdej                  j                  defd„Zd*defd„Zd*defd„Z	 d+dee    deej                  j&                  ef   fd„Z!deej                  j&                  ef   fd„Z"dedefd„Z#de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(   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/y),Ú_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 NrA   Úsample_inputrB   ÚsettingsÚnon_acc_submodule_nameÚreturn_tupleÚnodes_finderc                 óP  — t        |t        j                  j                  «      sJ ‚|| _         t        | j                  «      j                  |Ž  || _        || _        || _	        |€5t        | j                  | j                  | j                  j                  «      } |«       | _        | j                  j                  ri | _        n  t        || j                  «      «       | _        | j!                  «       | _        | j%                  «        || _        i | _        || _        g | _        y)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.
        N)Ú
isinstancerd   re   rf   rA   r   Ú	propagaterŠ   rB   r‰   r   r0   rF   r/   Úfusionsr   Ú	find_depsÚdepsÚupdate_deps_for_fusionsr‹   Ú_node_submodule_mapÚ_return_tupleÚtags)r1   rA   r‰   rB   rŠ   r‹   rŒ   r�   s           r5   r6   z_SplitterBase.__init__G  sò   € ô$ ˜&¤%§(¡(×"6Ñ"6Ô7Ð7Ð7àˆŒØ(Œ	�$—+‘+Ó×(Ñ(¨,Ñ7à ˆŒØ 0ˆÔØ(ˆÔØÐÜ.Ø—‘˜T×2Ñ2°D·M±M×4RÑ4RóˆLñ &›ˆŒà�=‰=×$Ò$ØˆD�LàHÔ0°¸¿¹ÓHÓJˆDŒLð —N‘NÓ$ˆŒ	Ø×$Ñ$Ô&à&<ˆÔ#Ø35ˆÔ Ø)ˆÔà!ˆ�	r7   r[   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•   )r1   s    r5   Úget_node_submodule_mapz$_SplitterBase.get_node_submodule_mapz  s   € ð ×'Ñ'Ð'r7   c                 óþ   — t        t        «      }| j                  j                  j                  D ]J  }|j
                  t        vrŒ|j                  D ]&  }|j
                  dk7  sŒ||   j                  |«       Œ( ŒL |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   rE   rA   rQ   rR   rS   r   rJ   Úadd)r1   r“   rM   rN   s       r5   r’   z_SplitterBase.find_depsƒ  ss   € ô .9¼Ó-=ˆØ—K‘K×%Ñ%×+Ñ+ò 	)ˆDØ�w‰wÔ/Ñ/ØàŸ
™
ò )�Ø—7‘7˜hÓ&Ø˜‘J—N‘N 4Õ(ñ)ð		)ð ˆr7   c                 ó  — | j                   D ]z  }| j                   |   }|D ]d  }| j                  |   j                  | j                  |   |z
  «       |j                  D ]%  }||vsŒ| j                  |   j	                  |«       Œ' Œf Œ| y)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“   ÚupdaterJ   rœ   )r1   rM   ÚfusionÚfused_neighborrN   s        r5   r”   z%_SplitterBase.update_deps_for_fusions•  s‹   € ð —L‘Lò 	2ˆDØ—\‘\ $Ñ'ˆFØ"(ò 2�Ø—	‘	˜$‘×&Ñ& t§y¡y°Ñ'@À6Ñ'IÔJà*×0Ñ0ò 2�DØ 6Ò)ØŸ	™	 $™×+Ñ+¨DÕ1ñ2ñ2ñ	2r7   r…   rs   c                 ó   — |S )z/
        Lower the model to a backend.
        r>   ©r1   r…   rs   s      r5   Ú_lower_model_to_backendz%_SplitterBase._lower_model_to_backend¨  s	   € ð ˆ
r7   c                  ó   — y)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.r>   r¢   s      r5   Ú_find_culpritz_SplitterBase._find_culprit±  s   € ð _r7   Úsupported_nodesc                 ó�   ‡‡— ddddœŠ G ˆˆfd„dt         «      } ||dd¬	«      }|j                  «       }|j                  d
«       y )NÚ	AliceBlueÚchartreuse1Úcrimson)r'   Ú	supportedÚunsupportedc                   ó$   •‡ — e Zd Zˆ ˆˆfd„Zˆ xZS )úE_SplitterBase._draw_graph_based_on_node_support.<locals>.CustomDrawerc                 óŠ   •— t         ‰| �  |«      }|‰v r
‰d   |d<   |S |j                  t        v r
‰d   |d<   |S ‰d   |d<   |S )Nr«   Ú	fillcolorr¬   r'   )ÚsuperÚ_get_node_stylerS   r   )r1   rM   ÚtemplateÚ	__class__Ú	color_mapr¦   s      €€€r5   r²   zU_SplitterBase._draw_graph_based_on_node_support.<locals>.CustomDrawer._get_node_styleÃ  sk   ø€ Ü ™7Ñ2°4Ó8�Ø˜?Ñ*Ø,5°kÑ,B�H˜[Ñ)ð  �ð —W‘WÔ 1Ñ1Ø,5°mÑ,D�H˜[Ñ)ð  �ð -6°iÑ,@�H˜[Ñ)à�r7   )r8   r9   r:   r²   Ú__classcell__)r´   rµ   r¦   s   @€€r5   ÚCustomDrawerr®   Â  s   ù„ ÷	 ò 	 r7   r·   Únode_supportT©Úignore_getattrznode_support.dot)r   Úget_main_dot_graphÚ	write_raw)r1   r…   r¦   r·   ÚdrawerÚ	dot_graphrµ   s     `   @r5   Ú!_draw_graph_based_on_node_supportz/_SplitterBase._draw_graph_based_on_node_support¹  sN   ù€ ð #Ø&Ø$ñ
ˆ	÷
	 œ=ô 
	 ñ ˜c >À$ÔGˆØ×-Ñ-Ó/ˆ	à×ÑÐ.Õ/r7   Ú
dump_graphc           
      ó–  ‡— t        | j                  j                  «       «      }g }t        t        «      }t        t        «      }d„ Š| j                  j
                  j                  D �]6  }|j                  t        vrŒt        ||«      }|j                  D �cg c]0  }t        |t        j                  j                  «      r ‰|«      nd ‘Œ2 }	}t        |	«      t!        d„ t#        t%        |	«      «      D «       t        |	«      «      z
  }
t'        |	d |
 «      }t'        ˆfd„|j(                  j+                  «       D «       «      }| j,                  j/                  ||«      r)|j1                  |«       ||   j3                  ||f«       �Œ!||   j3                  ||f«       �Œ9 |r| j5                  | j                  |«       d}|j+                  «       D ]&  \  }}|D ]  \  }}||› d|› dt        |«      › d�z  }Œ Œ( |dz  }|j+                  «       D ]&  \  }}|D ]  \  }}||› d|› dt        |«      › d�z  }Œ Œ( t7        |«       |S c c}w )	Nc                 óR   — | j                   j                  d«      }t        |dd «      S )NÚtensor_metaÚdtype)ÚmetaÚgetÚgetattr)ÚargrÃ   s     r5   Ú	get_dtypez5_SplitterBase.node_support_preview.<locals>.get_dtypeÚ  s#   € ØŸ(™(Ÿ,™, }Ó5ˆKÜ˜;¨°Ó6Ð6r7   c              3   ó*   K  — | ]  \  }}|�|–— Œ y ­wrD   r>   )Ú.0ÚirÄ   s      r5   ú	<genexpr>z5_SplitterBase.node_support_preview.<locals>.<genexpr>ì  s"   è ø€ ò á ˜˜5ØÐ(ô ñùs   ‚c              3   ó€   •K  — | ]5  \  }}t        |t        j                  j                  «      r| ‰|«      f–— Œ7 y ­wrD   )r�   rd   re   ÚNode)rË   ÚkrÈ   rÉ   s      €r5   rÍ   z5_SplitterBase.node_support_preview.<locals>.<genexpr>ö  s8   øè ø€ ò 'á�A�sÜ˜c¤5§8¡8§=¡=Ô1ð ‘I˜c“NÔ#ñ'ùs   ƒ;>z$
Supported node types in the model:
z: (z, z)
z&
Unsupported node types in the model:
)r]   rA   r^   r   rE   rQ   rR   rS   r   r   r3   r�   rd   re   rÏ   ÚlenÚnextÚ	enumerateÚreversedÚtupleÚkwargsÚitemsrB   r_   rL   rœ   r¿   Úprint)r1   rÀ   r`   r¦   Úsupported_node_typesÚunsupported_node_typesrM   ÚtargetrÈ   Ú
arg_dtypesÚ
last_indexÚarg_dtypes_tupleÚkwarg_dtypes_tupleÚreportsÚtÚdtypesrÉ   s                   @r5   Únode_support_previewz"_SplitterBase.node_support_previewÓ  s}  ø€ Ü˜$Ÿ+™+×3Ñ3Ó5Ó6ˆ
à$&ˆÜ*¬3Ó/ÐÜ!,¬SÓ!1Ðò	7ð —K‘K×%Ñ%×+Ñ+ó $	ˆDØ�w‰wÔ/Ñ/Øä$ Z°Ó6ˆFð
  Ÿ9™9öàô #-¨S´%·(±(·-±-Ô"@‘	˜#”ÀdÑJðˆJð ô ˜Z›¬4ñä$-¬h°zÓ.BÓ$Côô
 �J“ó,ñ ˆJô  % Z°°Ð%<Ó=ÐÜ!&ó 'à"Ÿk™k×/Ñ/Ó1ô'ó "Ðð ×$Ñ$×6Ñ6°zÀ4ÔHØ×&Ñ& tÔ,Ø$ VÑ,×0Ñ0Ð2BÐDVÐ1WÖXà& vÑ.×2Ñ2Ø%Ð'9Ð:öðE$	ñL Ø×2Ñ2°4·;±;ÀÔPà:ˆØ-×3Ñ3Ó5ò 	V‰IˆAˆvØ8>ò VÑ4Ð Ð"4Ø˜a˜S Ð$4Ð#5°R¼Ð=OÓ8PÐ7QÐQTÐUÑU‘ñVð	Vð 	Ð=Ñ=ˆØ/×5Ñ5Ó7ò 	V‰IˆAˆvØ8>ò VÑ4Ð Ð"4Ø˜a˜S Ð$4Ð#5°R¼Ð=OÓ8PÐ7QÐQTÐUÑU‘ñVð	Vô 	ˆgŒð ˆùò_s   Â5Ic                 óž  ‡‡‡— dŠ| j                  «       }t        |D �cg c]  }|j                  sŒ|‘Œ c}«      }t        |«      |z
  }‰dt        |«      › d�z  Š‰d|› d|› d�z  Š| j                  |«      }t        |D �cg c]  }|j                  sŒ|‘Œ c}«      }t        |«      |z
  }‰dt        |«      › d�z  Š‰d|› d|› d�z  Št	        |«      D ]F  \  }}‰|j                  rd|› d	�n| j
                  › |› d	�z  Š‰t        |j                  «      › d
�z  ŠŒH | j                  |«       | j                  d¬«      }|j                  «        |rJt        |dd¬«      }	|	j                  «       }
|
j                  «       D ]  \  }}|j                  |› d�«       Œ | j                  }d}|j                  j                  D �]Œ  }|j                   dk(  sŒd|j"                  v sŒ#‰d|j"                  › d�z  Št%        ||j"                  «      Šd„ } ||‰| j&                  «      } t)        ‰«      j*                  |Ž  d}dŠ‰dz  Š‰j                  j                  D ]T  }|j                   dk(  r1t-        |«      s‰d|j.                  › d�z  Šn|t1        ‰|«      d   z  }|j                   dk(  sŒS|}ŒV ‰dz  Šdt2        j4                  j6                  fˆˆˆfd„}t9        j:                  |«       | j                  t=        |‰«      z  }‰d|› d‰› d �z  Š‰d!|› d"�z  Š||k  r|}|j"                  }	 | j?                  ‰|«      }	  ||Ž  ‰d$z  Š�Œ� ‰d&|› d �z  Š‰d'|› d(�z  ŠtE        ‰«       ‰S c c}w c c}w # t@        $ r ‰d#z  Š‰| jC                  ‰|«      z  ŠY �Œßw xY w# t@        $ r ‰d%z  Š‰| jC                  ‰|«      z  ŠY �Œ	w xY w))NÚ z+Before removing small acc subgraphs, total z subgraphs are created:ú ú acc subgraphs and z cpu subgraphs.
z*After removing small acc subgraphs, total Ú_run_on_acc_z: z	 node(s)
T)Ú
remove_tagÚpreviewr¹   z.dotÚcall_moduleÚaccz
Processing acc submodule ú
c                 ób   ‡— d Šˆfd„}|j                  |«      } | |Ž  |j                  «        ‰S )Nc                 ó
   •— |Šy rD   r>   )r1   rs   Ú
sub_inputss     €r5   Ú
get_inputszJ_SplitterBase.split_preview.<locals>.get_submod_inputs.<locals>.get_inputsC  s   ø€ à%+™
r7   )r�   rK   )Úmain_modÚsubmodÚexample_inputsrñ   Úhandlerð   s        @r5   Úget_submod_inputsz6_SplitterBase.split_preview.<locals>.get_submod_inputs@  s6   ø€ Ø!%�Jô,ð $×=Ñ=¸jÓI�FÙ˜nÑ-Ø—M‘M”OØ%Ð%r7   r   zChecking inputs...
ÚplaceholderzInput ú= is not a tensor, this might cause problems during lowering!
r›   zChecking outputs...
rM   c                 óh   •— t        | «      s‰d| j                  › d�z  Šy ‰t        ‰| «      d   z  Šy )NzOutput rø   r   )r   r„   r   )rM   rà   ró   Útotal_output_bytess    €€€r5   Ú	get_bytesz._SplitterBase.split_preview.<locals>.get_bytes^  s=   ø€ ô 1°Ô6Ø W¨T¯Y©Y¨KÐ7uÐ#vÑv™à*Ô.>¸vÀtÓ.LÈQÑ.OÑOÑ*r7   zTotal input size in bytes is z , total output size in bytes is ú,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_subgraphsrÑ   rj   Úremove_small_acc_subgraphsrÓ   r‹   rR   ÚtagÚsplitÚevalr   Úget_all_dot_graphsr×   r¼   ÚPCIe_BWrQ   rS   rÛ   rÇ   r‰   r   r�   r   r„   r   rd   re   rÏ   r   r3   Úmaxr£   ÚRuntimeErrorr¥   rØ   )r1   rÀ   Ú	subgraphsÚgÚacc_subgraphs_numÚcpu_subgraphs_numrÌ   ÚsubgraphÚ	split_modr½   Ú
dot_graphsr„   r¾   Úmax_qpsÚbottleneck_modulerM   rö   Úsubmod_inputsÚtotal_input_bytesra   Úoutput_noderû   ÚqpsÚlowered_submodrà   ró   rú   s                           @@@r5   Úsplit_previewz_SplitterBase.split_preview  s†  ú€ ØˆØ×1Ñ1Ó3ˆ	Ü¨IÖ B q¸¿»¢Ò BÓCÐÜ 	›NÐ->Ñ>ÐØÐ@ÄÀYÃÐ@PÐPgÐhÑhˆØ�QÐ(Ð)Ð)<Ð=NÐ<OÐO`ÐaÑaˆà×3Ñ3°IÓ>ˆ	Ü¨IÖ B q¸¿»¢Ò BÓCÐÜ 	›NÐ->Ñ>ÐØÐ?ÄÀIÃÐ?OÐOfÐgÑgˆØ�QÐ(Ð)Ð)<Ð=NÐ<OÐO`ÐaÑaˆä$ YÓ/ò 	:‰KˆAˆxØà—?’?ð ˜q˜c Ñ$à×3Ñ3Ð4°Q°C°rÐ:ñˆGð
 œ#˜hŸn™nÓ-Ð.¨jÐ9Ñ9‰Gð	:ð 	�‰�ÔØ—J‘J¨$�JÓ/ˆ	Ø�‰ÔáÜ" 9¨iÈÔMˆFØ×2Ñ2Ó4ˆJØ#-×#3Ñ#3Ó#5ò 3‘��ià×#Ñ# t f¨D MÕ2ð3ð Ÿ™ˆØÐà—O‘O×)Ñ)ó B	AˆDØ�w‰w˜-Ó'¨E°T·[±[Ò,@ØÐ8¸¿¹¸ÀRÐHÑH�ä  ¨D¯K©KÓ8�ò
&ñ !2°)¸VÀT×EVÑEVÓ W�Ø+”	˜&Ó!×+Ñ+¨]Ñ;à$%Ð!Ø%&Ð"àÐ1Ñ1�ØŸ™×+Ñ+ò (�AØ—t‘t˜}Ò,Ü4°QÔ7Ø#¨°·±¨xÐ7uÐ'vÑv™Gà-Ô1AÀ&È!Ó1LÈQÑ1OÑOÐ-Ø—t‘t˜xÓ'Ø&'™ð(ð Ð2Ñ2�ðP¤E§H¡H§M¡M÷ Pô ˜×(Ñ(¨)Ô4Ø—l‘l¤SÐ):Ð<NÓ%OÑO�ØÐ:Ð;LÐ:MÐMmð  oAð  nBð  BCð  Dñ  D�ØÐcÐdgÐchÐhkÐlÑl�à˜’=Ø!�GØ(,¯©Ð%ðØ%)×%AÑ%AÀ&È-Ó%X�NðAÙ" MÑ2ð
 Ð@Ñ@’GðEB	AðH 	ÐXÐY`ÐXaÐabÐcÑcˆØÐ.Ð/@Ð.AÀÐCÑCˆÜˆgŒð ˆùòU !Cùò !Cøôd $ò ØÐEÑE�GØ˜t×1Ñ1°&¸-ÓHÑH�GÚðûô $ò IØÐFÑF�GØ˜t×1Ñ1°&¸-ÓHÑH“GðIús:   ŸM1±M1ÂM6ÂM6Ì2M;ÍN%Í;#N"Î!N"Î%#OÏOÚtag_idc                 ó^  — t        t        «      }| j                  j                  j                  D ]z  }|j
                  t        vrŒ|j                  D ]V  }|j
                  t        vrŒ|�+t        |j                  j                  d«      d   «      |k  sŒC||   j                  |«       ŒX Œ| |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.
        Ú_r    )r   rE   rA   rQ   rR   rS   r   rJ   r,   r   r  rœ   )r1   r  ÚresultrM   rN   s        r5   Úfind_reverse_depsz_SplitterBase.find_reverse_deps‰  sœ   € ô 0;¼3Ó/?ˆà—K‘K×%Ñ%×+Ñ+ò 		+ˆDØ�w‰wÔ/Ñ/ØàŸ
™
ò +�Ø—7‘7Ô"3Ñ3Øà�>¤c¨$¯(©(¯.©.¸Ó*=¸bÑ*AÓ&BÀVÓ&KØ˜4‘L×$Ñ$ TÕ*ñ+ð			+ð ˆr7   r“   c                 ó`  — t        «       }| j                  j                  «       D ]‡  \  }}||v rŒt        «       }|D ]  }|j                  ||   «       Œ |j	                  |«       |D ]B  }|||<   |j
                  D ]  }||vsŒ||   j                  |«       Œ |j                  |«       ŒD Œ‰ y rD   )rE   r‘   r×   rž   Údifference_updateÚall_input_nodesrœ   )r1   r“   Úprocessed_noderM   rŸ   Únew_depra   rÈ   s           r5   Úupdate_reverse_deps_for_fusionsz-_SplitterBase.update_reverse_deps_for_fusionsŸ  sÅ   € Ü›ˆà ŸL™L×.Ñ.Ó0ò 	&‰LˆD�&Ø�~Ñ%Øä“eˆGð ò (�Ø—‘˜t A™wÕ'ð(ð ×%Ñ% fÔ-ð ò &�Ø!��Q‘à×,Ñ,ò 1�CØ &Ò(Ø˜S™	×(Ñ(¨Õ0ð1ð ×"Ñ" 1Õ%ñ&ñ	&r7   r   c                 ó4  — t        «       }| j                  j                  j                  D ]j  }|j                  t
        v sŒ|j                  |k(  sŒ&|j                  D ]6  }|j                  t
        v sŒ|j                  |k7  sŒ&|j                  |«       Œ8 Œl |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.
        )	rE   rA   rQ   rR   rS   r   r   r  rœ   )r1   r   Úparent_nodesrM   rÈ   s        r5   Úfind_parent_nodes_of_subgraphz+_SplitterBase.find_parent_nodes_of_subgraphº  sƒ   € ô “uˆà—K‘K×%Ñ%×+Ñ+ò 	.ˆDØ�w‰wÔ+Ò+°·±¸C³Ø×/Ñ/ò .�CØ—v‘vÔ!2Ò2°s·w±wÀ#³~Ø$×(Ñ(¨Õ-ñ.ð	.ð Ðr7   c                 óF  — | j                  t        |j                  d«      d   «      ¬«      }| j                  |«       | j	                  |«      }t        «       }|rÆd}|D ]  }||   |k  sŒ|| j                  v sŒ|} n |€y||_        |j                  |«       |j                  |«       || j                  v r*| j                  |   D ]  }||vsŒ|j                  |«       Œ |j                  D ]+  }|j                  t        v sŒ||vsŒ|j                  |«       Œ- |rŒÅyy)z^
        Extend the acc subgraph with `tag` going the reversed topological direction.
        r  r    )r  N)r  r,   r  r   r#  rE   rF   r   rK   rœ   r‘   r  rS   r   )	r1   r   r“   r"  Úvisited_nodesrM   ra   Úfusion_noderÈ   s	            r5   Úextend_acc_subgraphz!_SplitterBase.extend_acc_subgraphË  s1  € ð ×%Ñ%¬S°·±¸3³ÀÑ1CÓ-DÐ%ÓEˆØ×,Ñ,¨TÔ2ð ×9Ñ9¸#Ó>ˆä!$£ˆáØˆDð "ò �Ø˜‘7˜mÓ+°°T·^±^Ò0CØ�DÙðð
 ˆ|Øð ˆDŒHØ×Ñ Ô%Ø×Ñ˜dÔ#ð �t—|‘|Ñ#Ø#'§<¡<°Ñ#5ò 6�KØ"¨-Ò7Ø$×(Ñ(¨Õ5ð6ð
 ×+Ñ+ò *�Ø—6‘6Ô.Ò.°3¸mÒ3KØ ×$Ñ$ SÕ)ð*ô1 r7   c                 ó  — t        «       }t        «       }| j                  j                  j                  D ]S  }|j                  dvrŒ|j
                  D ]3  }|| j                  v r|j                  |«       Œ#|j                  |«       Œ5 ŒU ||fS )zK
        Finds nodes that consume module inputs or get_attr nodes.
        >   Úget_attrr÷   )rE   rA   rQ   rR   rS   rJ   rF   rœ   )r1   Ústarter_cpu_nodesÚstarter_acc_nodesrM   rN   s        r5   Ústarter_nodesz_SplitterBase.starter_nodesù  sŒ   € ô &)£UÐÜ%(£UÐØ—K‘K×%Ñ%×+Ñ+ò 	0ˆDØ�w‰wÐ9Ñ9ØØŸ
™
ò 0�Ø˜4Ÿ>™>Ñ)Ø%×)Ñ)¨$Õ/à%×)Ñ)¨$Õ/ñ	0ð	0ð !Ð"3Ð3Ð3r7   c                 óN  ‡ ‡	— ‰ j                  «       \  }}t        «       Š	t        ˆ fd„|D «       «       }g }g }|s|�r<|r|n|}t        ˆ ˆ	fd„|D «       d «      }|€/|st	        d«      ‚|j                  t        ||¬«      «       | }g }ŒR|j                  |«       ‰	j                  |«       |j                  |«       |‰ j                  v rQ|‰ j                  v r"|j                  ‰ j                  |   ‰	z
  «       n!|j                  ‰ j                  |   ‰	z
  «       |j                  D ]F  }|j                  t        vrŒ|‰ j                  v r|j                  |«       Œ6|j                  |«       ŒH |r�Œ8|r�Œ<|r|j                  t        ||¬«      «       |st	        d«      ‚|S )Nc              3   óT   •K  — | ]  }t        ‰j                  |   «      d k(  –— Œ! y­w)r   N)rÑ   r“   )rË   ra   r1   s     €r5   rÍ   z9_SplitterBase.put_nodes_into_subgraphs.<locals>.<genexpr>  s#   øè ø€ Ò$WÀ¤S¨¯©°1©Ó%6¸!Õ%;Ñ$Wùs   ƒ%(c              3   óH   •K  — | ]  }‰j                   |   ‰k  sŒ|–— Œ y ­wrD   )r“   )rË   ra   r1   r%  s     €€r5   rÍ   z9_SplitterBase.put_nodes_into_subgraphs.<locals>.<genexpr>  s    øè ø€ ÒK�q¨T¯Y©Y°q©\¸]Ó-J”ÑKùs   ƒ"›"zSubgraph can't be empty)rj   rR   zCouldn't create subgraphs)r,  rE   ÚanyrÒ   r   rL   r   rK   rœ   r‘   rF   rž   rJ   rS   r   )
r1   Úcurrent_cpu_nodesÚcurrent_acc_nodesÚacc_subgraphÚcurrent_subgraph_nodesr  Úcurrent_nodesrM   rN   r%  s
   `        @r5   rþ   z&_SplitterBase.put_nodes_into_subgraphs	  s´  ù€ à/3×/AÑ/AÓ/CÑ,ÐÐ,Ü!$£ˆô "%Ó$WÐEVÔ$WÓ!WÐWˆà+-Ðð %'ˆ	ÙÒ#4á1=Ñ-ÐCTˆMÜÜK˜MÔKØóˆDð ˆ|Ù-Ü4Ð5NÓOÐOà× Ñ Ü LÐ8NÔOôð $0Ð/�Ø)+Ð&Øà× Ñ  Ô&Ø×Ñ˜dÔ#Ø"×)Ñ)¨$Ô/ð �t—|‘|Ñ#Ø˜4Ÿ>™>Ñ)Ø%×,Ñ,¨T¯\©\¸$Ñ-?À-Ñ-OÕPà%×,Ñ,¨T¯\©\¸$Ñ-?À-Ñ-OÔPð Ÿ
™
ò 0�Ø—7‘7Ô"3Ñ3Øð ˜4Ÿ>™>Ñ)Ø%×)Ñ)¨$Õ/à%×)Ñ)¨$Õ/ð0óA  Ó#4ñV "Ø×ÑÜ Ð4JÔKôñ Ü,Ð-HÓIÐIàÐr7   r  c                 ó@  — g }|D �]  }|j                   rºt        |j                  «      | j                  j                  k\  r|j                  |«       ŒNt        dt        |j                  «      › d| j                  j                  › �«       |r)|d   j                  j                  |j                  «       Œ±d|_         |j                  |«       ŒÊ|r9|d   j                   s*|d   j                  j                  |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)rj   rÑ   rR   rŠ   r.   rL   rØ   Úextend)r1   r  r  r  s       r5   rÿ   z(_SplitterBase.remove_small_acc_subgraphsK  sé   € ð
 "$ˆØ!ó 	,ˆHØ�ŠÜ�x—~‘~Ó&¨$¯-©-×*KÑ*KÒKØ—M‘M (Õ+äØ\Ü˜xŸ~™~Ó.Ð/¨s°4·=±=×3TÑ3TÐ2UðWôñ Ø˜r™
×(Ñ(×/Ñ/°·±Õ?à*/˜œØŸ™ hÕ/á &¨¡*×"3Ò"3Ø˜2‘J×$Ñ$×+Ñ+¨H¯N©NÖ;à—M‘M (Ö+ð%	,ð& ˆr7   c                 ó|  — g | _         |D ]°  }|j                  rdt        | j                   «      › �n"| j                  › t        | j                   «      › �}| j                   j	                  |«       |j
                  D ]=  }t        |d«      rt        d|› d�«      ‚||_        || j                  |j                  <   Œ? Œ² y )Nrè   r   zNode z was already tagged)r—   rj   rÑ   r‹   rL   rR   Úhasattrr   r   r•   r„   )r1   r  r  r   rM   s        r5   r   z_SplitterBase.tagf  s¸   € ØˆŒ	Ø!ò 	:ˆHð —?’?ð œs 4§9¡9›~Ð.Ñ/à×3Ñ3Ð4´S¸¿¹³^Ð4DÐEð ð
 �I‰I×Ñ˜SÔ!Ø Ÿ™ò :�Ü˜4 Ô'Ü4°u¸T¸FÐBUÐ5VÓWÐWà�”Ø69�×(Ñ(¨¯©Ò3ñ:ñ	:r7   ré   c                 óÊ   — t        | j                  | j                  | j                  ¬«      }|r4| j                  j                  j
                  D ]  }t        |d«      sŒ|`Œ |S )N)rŒ   r   )r   rA   r—   r–   rQ   rR   r9  r   )r1   ré   rn   rM   s       r5   r  z_SplitterBase.splitv  s\   € Ü$Ø�K‰K˜Ÿ™°×1CÑ1Cô
ˆñ ØŸ™×)Ñ)×/Ñ/ò !�Ü˜4 Õ'Ø™ð!ð Ðr7   c                 ó  — | j                  «       }| j                  |«      }t        |D �cg c]  }|j                  sŒ|‘Œ c}«      }t        |«      |z
  }t	        d|› d|› d�«       | j                  |«       | j                  «       S c c}w )NzGot rç   z non-acc subgraphs)rþ   rÿ   rÑ   rj   rØ   r   r  )r1   r  ÚsÚacc_subgraphs_countÚnon_acc_subgraphs_counts        r5   rb   z_SplitterBase.__call__€  sŒ   € Ø×1Ñ1Ó3ˆ	Ø×3Ñ3°IÓ>ˆ	Ü!¨iÖ"D¨¸1¿8»8¢1Ò"DÓEÐÜ"% i£.Ð3FÑ"FÐÜØÐ&Ð'Ð':Ð;RÐ:SÐSeÐfô	
ð 	�‰�ÔØ�z‰z‹|Ðùò #Es
   «B	½B	c                 óN  —  | «       }g }|j                  «       D ]  \  }}|j                  |«       Œ | j                  j                  dkD  r-t	        |«      | j                  j                  kD  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_childrenrL   rŠ   r!   rÑ   Ú
ValueErrorr   r‰   r   r‹   )r1   rn   Úsubmodule_namesr„   Ú_modro   s         r5   Úgenerate_split_resultsz$_SplitterBase.generate_split_results‹  s§   € Ù“vˆØˆØ&×5Ñ5Ó7ò 	)‰JˆD�$Ø×"Ñ" 4Õ(ð	)ð �M‰M×(Ñ(¨1Ò,Ü�OÓ$ t§}¡}×'CÑ'CÒCäð0óð ô :Ø˜$×+Ñ+¨_ó
Ðô ˜<Ð)9¸4×;VÑ;VÓWÐWr7   )Ú_run_on_cpu_FN©FrD   )0r8   r9   r:   rc   r  rd   re   rf   r   r   r   r   rq   rg   r	   r   r6   r]   r™   rÏ   r   r’   r”   r   ÚnnÚModuler£   r¥   r   r¿   rã   r  r,   r  r   r#  r'  rÕ   r,  Úlistr   rþ   rÿ   r   r  rb   r   rD  r>   r7   r5   rˆ   rˆ     sF  „ ñ(ðV €Gð '5Ø"Ø6:ñ-"à—‘×$Ñ$ð-"ð ˜s‘mð-"ð .ð	-"ð
 'ð-"ð !$ð-"ð ð-"ð Ð2Ñ3ó-"ðf(¨¨S°#¨X©ó (ð˜4 §¡§¡¨wÐ 6Ñ7ó ò$2ð&Ø—8‘8×'Ñ'ðØ18ðà	�‰�‰óð_ §¡×!5Ñ!5ð _¸wð _È3ó _ð0Ø—8‘8×'Ñ'ð0Ø:Bó0ñ4A¨tó AñFm¨ó mðh '+ñØ˜s‘mðà	ˆe�h‰h�m‰m˜WÐ$Ñ	%óð,&°D¸¿¹¿¹ÈÐ9OÑ4Pó &ð6°ð ¸ó ð"(* só (*ð\4˜u W¨gÐ%5Ñ6ó 4ð @¨$¨x©.ó @ðD°D¸±Nð ÀtÈHÁ~ó ð6:˜T (™^ó :ñ  ð °·±×1EÑ1Eó ð	˜%Ÿ(™(×.Ñ.ó 	ðX¨ô Xr7   rˆ   rF  )9r)   rx   ÚloggingÚcollectionsr   Úcollections.abcr   r   Údataclassesr   Útypingr   r   r	   rd   Útorch.fx._compatibilityr
   Útorch.fx.noder   Ú"torch.fx.passes.graph_manipulationr   Úgraph_drawerr   rB   r   r   Ú
shape_propr   Úsplit_utilsr   Útools_commonr   r   r   r   r   r   Ú__all__Ú	getLoggerr8   Ú_LOGGERr;   r<   r=   r   r   rƒ   r   r   r   rG  rH  rq   rg   r]   r   rˆ   r>   r7   r5   ú<module>rY     sr  ðã Û Û Ý #ß .Ý !ß ,Ñ ,ã Ý 1Ý !Ý ?å 'ß BÝ !Ý &÷÷ ò€ð ˆ'×
Ñ
˜HÓ
%€àÐ ØÐ Ø Ð ÷82ñ 82ñv  eÔ,÷að aó -ðañH  eÔ,ô	 ó 	ó -ð	ñ  eÔ,Ø
÷)ð )ó ó -ð)ñ  eÔ,ô"�*ó "ó -ð"ñ   eÔ,ð
 ñ	,Ø�8‰8�?‰?ð,à�S‰Mð,ð   ‘}ð,ð ð	,ð
 
ˆ#ˆsˆ(�^ò,ó -ð,÷^D
Xò D
Xr7   