
    sgY"                        d dl 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mZmZ d dl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e
de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   dede
fd       Zy)    N)SimpleQueue)ListDictTuple)GraphModule)Graph)Node)NodeListNodeSetlegalize_graph)lift_subgraph_as_module)compatibilityF)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         T/var/www/html/venv/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:\**n,nn*    	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/   r1   r0   s        @r"   validate_partitionr4   +   sl    
 	NMG * 	*I-y)	**8  4 gr$   gmmodule_name.c                    D ]|  }|j                   j                  | u sJ | d| j                                 |j                  r
J | d       || j                   j                  v rdJ | d| j                                  t              sJ d       t               i i fd}D ]  }j                  ||      }||<    i }D ]   }|j                  D ]  }|vs|   ||<    " t        |j                               }j                  t        |      dk(  r|d   n|       j                          t        | d|	      \  }	}
t        j                               }t        |j                               }|	||fS )
a1  
    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

    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_placeholderr   subgraphs     r"   remap_inputsz)fuse_as_graphmodule.<locals>.remap_inputs   sz    44: : A;'''33AFFaff3M$(IIaff$5!%5""1%%r$   r   r    )	comp_name
class_name)graphowning_module	_get_name_erasedr   r4   r   	node_copyr   tuplevaluesoutputr   lintr   keys)r5   r   r6   r   rF   new_nodeoutput_mappingr/   outsfused_gm_original_inputsoriginal_outputsrC   rD   rE   s    `           @@@r"   fuse_as_graphmoduler[   \   s   4  _zz''2-r$7abdbnbnbpaq/rr-<<MD6)L!MMrxx~~%^$/MbllnM]'^^%_ e$R&RR$wH,.!#H&*  "%%dL9!"
 (*N 6 	6I%'/~t$	66 &&()D OOs4yA~DG48 MMO)"h"Q\]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       }t        |      dk(  r|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)r@   r   ).0orig_outputs     r"   	<genexpr>zinsert_subgm.<locals>.<genexpr>   s#     'jk(8(8(<(<UD(I'js   &(rd   )	__class____name__add_submodulerJ   call_moduler   replace_all_uses_with	enumeratetorchfxProxyr   rO   r@   )	r5   r\   r]   r^   submodule_namemodule_nodeirf   	proxy_outs	            r"   insert_subgmru      s     %%..N^V, ((&& ' K
 <AQ--k$-O I (5 	NNA{{3A6;;I--i-M	N
 #('j]i'j"jIr$   c                 Z    t        |      D ]  }| j                  j                  |        y N)reversedrJ   
erase_node)r5   r   r   s      r"   erase_nodesrz      s)      "
D!"r$   
partitionsprefixc                     t        |      D ]I  \  }}t        |      }|t        |      z   }t        | ||      \  }}}	t	        | |||	       t        | |       K t        |        | S rw   )rm   r#   strr[   ru   rz   r   )
r5   r{   r|   partition_idr   r!   rq   r\   r]   r^   s
             r"   fuse_by_partitionsr      sq    (4 &e '#l"33,?LR`,a)\Rl;B%& 2Ir$   )fused_)r?   r-   r   typingr   r   r   torch.fxrn   torch.fx.graph_moduler   torch.fx.graphr   torch.fx.noder	   torch.fx.passes.tools_commonr
   r   r   torch.fx.passes.utilsr   torch.fx._compatibilityr   r#   r2   r4   r~   r[   ru   rz   r    r$   r"   <module>r      s     $ $  -    J J 9 1e,X (  -8 e,-( -t - --` e,]7K ]7']7%(]7-2;dCi@PRWX\^aXaRb3b-c]7 -]7@ e,[ + E$PS)DT dijnpsjsdt  -. e,"K " " -" e,; DN C _j  -r$   