
    Vh%                        d dl Z d dlmZ d dl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mZ d d	lmZ  e	d
      dedefd       Z e	d
      dedefd       Z e	d
      	 d d
ddedededeeedf      dedeeeedf   eedf   f   fd       Z e	d
      dededeedf   deedf   fd       Z e	d
      dedefd       Z e	d
      	 	 d!dedeeedf      dededef
d       Z y)"    N)SimpleQueue)Optional)compatibility)Graph)GraphModule)Node)legalize_graphNodeListNodeSet)lift_subgraph_as_moduleF)is_backward_compatiblenodesreturnc                    t         j                  | d      }t               }| D ]?  }|j                  D ]  }||v s||xx   dz  cc<    ||   dk(  s/|j	                  |       A g }|j                         so|j                         }|j                  |       |j                  D ].  }||v s||xx   dz  cc<   ||   dk(  s|j	                  |       0 |j                         sot        |       t        |      k(  sJ d       |S )Nr      z@topological sorted nodes doesn't have same length as input nodes)
dictfromkeysr   all_input_nodesputemptygetappenduserslen)r   indegree_map
candidatesnodensorted_nodess         Q/home/dcms/DCMS/lib/python3.12/site-packages/torch/fx/passes/utils/fuser_utils.py	topo_sortr!      s"    ==*L)mJ !%% 	(AL T"a'"	( "NN4 !  L ~~D! 	&AL Q1$?a'NN1%		&	   u:  JIJ      	partitionc                     t        |       g }D ])  }|j                  D ]  }|vs|j                  |        + dt        dt        ffd} ||      ryy)N
root_nodesr   c                     t               }| }|rP|j                         }|j                  |       |v ry|j                  D ]  }||v r|j	                  |        |rPy)NTF)setpopaddr   r   )r%   visitedqueuecurrent	user_nodepartition_sets        r    bfs_find_cyclez*validate_partition.<locals>.bfs_find_cycle?   sn     5
 %iikGKK -' $]] (	'Y'(  r"   FT)r'   r   r   r
   bool)r#   outputsr   r-   r/   r.   s        @r    validate_partitionr2   .   sl    
 	NMG * 	*I-y)	**8  4 gr"   always_return_tuplegmmodule_namepartition_lookup_tabler4   .c                h   |D ]|  }|j                   j                  | u sJ | d| j                                 |j                  r
J | d       || j                   j                  v rdJ | d| j                                  t        |      sJ d       t        j                  |      t               i i fd}|D ]  }j                  ||      }||<    i }|D ]   }|j                  D ]  }	|	vs|   ||<    " t        |j                               }
|rj                  |
       n$j                  t        |
      dk(  r|
d   n|
       j                          t!        | d|	      \  }}t        j#                               }t        |j#                               }|||fS )
a  
    Fuse nodes in graph_module into a GraphModule.

    Args:
        gm (GraphModule): target graph_module

        nodes (List[Node]): list of nodes in `gm` to fuse, where the node must be topologically sorted

        module_name: class name for the fused GraphModule

        partition_lookup_table (Optional[Dict[Node, None]]): optional dict of nodes to speed up lookup

        always_return_tuple (bool): whether to always return a tuple, even if there is only one output

    Returns:
        fused_gm (GraphModule): fused graph module, where its node is a copy of `nodes` in `gm`

        original_inputs (Tuple[Node, ...]): input nodes to `nodes` in original `gm`

        original_outputs (Tuple[Node, ...]): consumer nodes of `nodes` in original `gm`

    z* doesn't belong to passed in graph module z# has been removed from owning graphz is not found in graph module z*Invalid partition, found dependency cyclesc                     | j                   dk(  r	 | v r|    S | vrPj                  | j                  | j                        }t	        j                  | j
                        |_        || <   |    S )Nget_attr)	type_expr)opplaceholdernametypecopymeta)xplaceholder_nodenode_mapnode_to_placeholderr7   subgraphs     r    remap_inputsz)fuse_as_graphmodule.<locals>.remap_inputs   s|    44: && A;'''33AFFaff3M$(IIaff$5!%5""1%%r"   r   r    )	comp_name
class_name)graphowning_module	_get_name_erased_find_nodes_lookup_tabler2   r   r   r   	node_copyr   tuplevaluesoutputr   lintr   keys)r5   r   r6   r7   r4   r   rG   new_nodeoutput_mappingr-   outsfused_gm_original_inputsoriginal_outputsrD   rE   rF   s      `           @@@r    fuse_as_graphmoduler]   _   s   D  CJJ$$*	OV=blln=MN	O*<<MD6)L!MMBHH555	CV1",,.1AB	C5C e$R&RR$ %!%u!5wH 	  "$H&*  "%%dL9!"
 (*N 6 	6I 66'/~t$	66 &&()D 	3t9>Qt< MMO)
H{KHa
 )..A.F.F.H(IO */~/B/B/D)E_&666r"   sub_gmorig_inputsorig_outputsc                 .   |j                   j                  }| j                  ||       | j                  j	                  ||d       }|j                  j                         }t        |      dk(  r5t        |j                  d   t              s|d   j                  |d       | S t        |      D ]D  \  }}t        j                  j                  |      |   j                  }	|j                  |	d       F t        d |D              |j                   d<   | S )N)argskwargsr   r   T)propagate_metac              3   T   K   | ]   }|j                   j                  d d       " yw)valN)rA   r   ).0orig_outputs     r    	<genexpr>zinsert_subgm.<locals>.<genexpr>   s(      (
2=K  -(
s   &(rf   )	__class____name__add_submodulerK   call_moduleoutput_noder   
isinstancerb   rQ   replace_all_uses_with	enumeratetorchfxProxyr   rA   )
r5   r^   r_   r`   submodule_namemodule_nodern   irh   	proxy_outs
             r    insert_subgmry      s    %%..N^V, ((&&~KPT&UK,,**,K
<Aj1A1A!1De&LQ--k$-O I (5 	NNA{{3A6;;I--i-M	N
 #( (
AM(
 #
 Ir"   c                 Z    t        |      D ]  }| j                  j                  |        y N)reversedrK   
erase_node)r5   r   r   s      r    erase_nodesr~      s)      "
D!"r"   
partitionsprefixc                     t        |      D ]U  \  }}t        t        |            }|t        |      z   }t	        | ||||      \  }}	}
t        | ||	|
       t        | |       W t        |        | S )Nr3   )rq   r!   liststrr]   ry   r~   r	   )r5   r   r   r4   partition_idr#   r   ru   r^   r_   r`   s              r    fuse_by_partitionsr      s     $-Z#8 &i i1#l"33,? 3-
)\ 	Rl;B%&" 2Ir"   r{   )fused_F)!r@   r+   r   typingr   	_Optionaltorch.fxrr   torch.fx._compatibilityr   torch.fx.graphr   torch.fx.graph_moduler   torch.fx.noder   torch.fx.passes.tools_commonr	   r
   r   torch.fx.passes.utilsr   r!   r0   r2   r   r   rQ   r]   ry   r~   r   r    r"   r    <module>r      s     (  1   -  J J 9 e,X (  -< e,-( -t - --` e,
 ;?	r7 !&r7r7r7 r7 &d4:&67	r7 r7 ;dCi(%c	*::;r7 -r7j e, tSy! c	"	 -: e,"K " " -" e,  %	T$*%&  	
  -r"   