
    8hZC                         S SK r S SKrS SKrS SKJr  S SKJrJr  S SKJ	r	J
r
  S SKrS SKJrJr  S SKJr  SS/rS	 r\" 5       r\" S
S9\ " S S5      5       5       r\" S
S9 " S S5      5       rg)    N)defaultdict)	dataclassfield)AnyUnion)GraphNode)compatibilitySubgraphMatcherInternalMatchc                     [         R                  " [        5      n [        R                  R                  SS5      R                  5       nU R                  U5        [         R                  " 5       n[         R                  " S5      nUR                  U5        UR                  U5        U R                  U5        SU l        U $ )NPYTORCH_MATCHER_LOGLEVELWARNINGz%(filename)s > %(message)sF)logging	getLogger__name__osenvirongetuppersetLevelStreamHandler	FormattersetFormatter
addHandler	propagate)loggerlevelconsole	formatters       ]/var/www/fran/franai/venv/lib/python3.13/site-packages/torch/fx/passes/utils/matcher_utils.py_init_loggerr"      s    x(FJJNN5yAGGIE
OOE##%G!!">?I#U
gFM    F)is_backward_compatiblec                       \ rS rSr% \\   \S'   \" \S9r	\\\4   \S'   \" \S9r
\\   \S'   \" \S9r\\   \S'   \" \S9r\\\4   \S'   S rS	rg
)r   $   anchors)default_factory	nodes_mapplaceholder_nodesreturning_nodesname_node_mapc                     [        U R                  U R                  R                  5       U R                  R                  5       U R
                  R                  5       S9$ )N)r'   r)   r*   r+   )r   r'   r)   copyr*   r+   )selfs    r!   __copy__InternalMatch.__copy__6   sJ    LLnn))+"4499; 00557	
 	
r#    N)r   
__module____qualname____firstlineno__listr	   __annotations__r   dictr)   r*   r+   r,   strr0   __static_attributes__r2   r#   r!   r   r   $   so     $Z"'"=ItD$J= %*$$?tDz? #("=OT$Z= &+4%@M4T	?@
r#   c                       \ rS rSr    SS\S\S\S\S\SS4S	 jjrS
\S\S\4S jrS
\S\S\4S jr	S\
\\4   S\4S jrS\\   S\\   4S jrS
\S\S\S\4S jrS
\S\S\S\4S jrS\S\\   4S jrSrg)r   ?   patternmatch_outputmatch_placeholderremove_overlapping_matchesignore_literalsreturnNc                    Xl         X l        X0l        X@l        XPl        [        UR                  5      S:X  a  [        S5      eUR                   H5  nUR                  S:w  d  M  [        UR                  5      S:  a  M0   S5       e   UR                   Vs/ s H  owR                  S:X  d  M  UPM     snU l
        [        [        [        UR                  5      5      5      nUR                  U l        / U l        U(       a	  U/U l        gUR                   Vs/ s H   n[        UR                  5      S:X  d  M  UPM"     snU l        gs  snf s  snf )a  
Args:
    pattern: the targeted matching pattern, represented in fx.Graph.
    match_output: If True, output node in the pattern graph will be treated as a part of the targeted pattern.
        If False, output node is ignored during match.
    match_placeholder: If True, placeholder node in the pattern graph will be treated as a part of
        the targeted pattern. If False, placeholder nodes will be used a wildcard.
    remove_overlapping_matches: If True, in the case of overlapping matches, only the first match
        will be returned.
    ignore_literals: If True, will not check if literals are equal and
        will instead treat them as wildcards.
r   z;SubgraphMatcher cannot be initialized with an empty patternoutputzDSubgraphMatcher cannot be initialized with an pattern with dead codeplaceholder   N)r=   r>   r?   r@   rA   lennodes
ValueErroropuserspattern_placeholder_nodesnextiterreversedall_input_nodespattern_returning_nodespattern_anchors)	r/   r=   r>   r?   r@   rA   nodenoutput_nodes	            r!   __init__SubgraphMatcher.__init__A   s$   * (!2*D'.w}}"M  MMDww("4::* Z* " }}*
$!(=A}*
& 4 7893>3N3N$+-$/=D 
 '66$6a#agg,!:K6$D *
$s   E-EE9Epngnc                    [        UR                  [        5      (       d   SUR                   S35       e[        UR                  [        5      (       d   SUR                   S35       e[        R                  R
                  R                  UR                  R                  UR                  5      n[        R                  R
                  R                  UR                  R                  UR                  5      n[        U5      [        U5      :w  a  g[        U[        R                  5      (       a  [        U[        R                  5      $ [        SU S35      e)Nz
pn.target z must be a string.z
gn.target FzUnsupported type z when matching attributes)
isinstancetargetr9   torchfxgraph_module	_get_attrgraphowning_moduletypeTensorRuntimeError)r/   rX   rY   pn_valuegn_values        r!   _match_attributes!SubgraphMatcher._match_attributesz   s    "))S))UZ		{BT+UU)"))S))UZ		{BT+UU)88((222883I3I299U88((222883I3I299U>T(^+ h--h55!28*<UVWWr#   c                 2   U R                   (       d  UR                  S:X  a  gUR                  UR                  :X  a[  UR                  S:X  d  UR                  S:X  a  gUR                  S:X  a  U R                  X5      $ UR                  UR                  :H  $ g)NrE   TrD   get_attrF)r?   rJ   rh   r\   )r/   rX   rY   s      r!   _nodes_are_equal SubgraphMatcher._nodes_are_equal   su    %%"%%=*@55BEE>uu%():*$--b5599		))r#   r)   c                    UR                  5        VVs0 s H  u  p#UR                  S:w  d  M  X2_M     nnnUR                  5        H1  u  p2X R                  ;   a  M  UR                   H  nXT;  d  M
      g   M3     gs  snnf )NrE   FT)itemsrJ   rQ   rK   )r/   r)   rX   rY   lookupusers         r!   _is_containedSubgraphMatcher._is_contained   s     "+!2$
!2vrbee}6LFBF!2 	 $
 llnFB111 % 	 ! % $
s
   A=A=matchesc                 p   / n[        5       nU H  nSnUR                  R                  5        H   u  pgUR                  S;  d  M  Xs;   d  M  Sn  O   U(       a  ML  UR	                  U5        UR                  R                  5        H(  u  pgUR                  S;  d  M  UR                  U5        M*     M     U$ )NF>   rD   rE   T)setr)   ro   rJ   appendadd)r/   rt   non_overlapping_matchesnodes_matchedmatchfound_overlaprX   rY   s           r!   _remove_overlapping_matches+SubgraphMatcher._remove_overlapping_matches   s     8:#&5E!M////155 99b>Q$(M 2
 !='..u5#oo335FBuu$==%))"- 6  '&r#   r{   c                    [        U[        5      (       a  [        U[        5      (       a   S5       e[        U[        5      (       aV  [        U[        5      (       dA  UR                  S:X  a0  XR                  ;   a  UR                  U   U:H  $ X#R                  U'   gg[        U[        5      (       d  [        U[        5      (       a  g[	        U5      [	        U5      :H  =(       a    X!:H  $ )Nzpn and gn cannot both be NoderE   TF)r[   r	   rJ   r)   rc   )r/   rX   rY   r{   s       r!   _match_literalsSubgraphMatcher._match_literals   s    r4((ZD-A-A 	
+	
B b$
2t(<(<uu% ( ??2."44&(#B%%*R*>*>8tBx'4BH4r#   c                   ^ ^^	^
 [         R                  SX5        [        U[        5      (       a  [        U[        5      (       d   [	        SU SU 35      5       eUTR
                  ;   a  TR
                  U   U:H  $ UTR
                  R                  5       ;   a  gT R                  X5      (       d  g[        R                  " T5      nUTR
                  U'   UR                  S:X  a  gSnS[        [        [        4   S[        [        [        4   S	[        4U	UU 4S
 jjm	Su  pg[        UR                  5      [        UR                  5      :w  dH  [        UR                   R#                  5       5      [        UR                   R#                  5       5      :w  a  UR                  S:X  a  [        UR$                  [&        R(                  R*                  5      (       ab  UR$                  R,                  R.                  m
U
4S jnU" UR                  UR                   5      nU" UR                  UR                   5      nGO[        UR                  5      [        UR                  5      :X  a  [        UR                   R#                  5       5      [        UR                   R#                  5       5      :X  a  [        UR                  5      n[        UR                  5      nUR1                  [        UR                   R                  5       5      5        UR1                  [        UR                   R                  5       5      5        OSnU=(       a    US L=(       a    US L=(       a    T	" Xg5      nU(       d  [        R                  " U5      mgg)Nz  matching %s to %szpn and gn must be Node, pn: z, gn: FrE   Targs1args2rB   c                   > [        U 5      [        U5      :w  a  g[        X5       H  u  p#[        U[        5      (       a(  [        U[        5      (       a  TR	                  X#T5      nOd[        U[
        [        45      (       a$  [        U[
        [        45      (       a	  T" X#5      nO%TR                  X#T5      =(       d    TR                  nU(       a  M    g   g)NFT)	rG   zipr[   r	   _match_nodesr6   tupler   rA   )r   r   a1a2matched_match_argsr{   r/   s        r!   r   1SubgraphMatcher._match_nodes.<locals>._match_args   s    5zSZ'e+b$''Jr4,@,@"//>GT5M22z"tUm7T7T)"1G ,,RU;St?S?S  w  , r#   )NNcall_functionc                 2  > / n[        T5       H  u  p4UR                  U;   a  UR                  XR                     5        M4  UR                  (       d$  U[	        U 5      :  a  UR                  X   5        Mi  UR                  UR
                  5        M     U$ )N)	enumeratenamerw   
kwarg_onlyrG   default_value)	orig_argsorig_kwargsall_argsischemaargs_schemas        r!   get_all_arguments7SubgraphMatcher._match_nodes.<locals>.get_all_arguments  ss    !*;!7IA{{k1 KK(@A#..1s9~3E 	5 (<(<= "8  r#   )r   infor[   r	   r9   r)   valuesrl   r.   rJ   r   r6   r   boolrG   argskwargskeysr\   r]   _ops
OpOverload_schema	argumentsextend)r/   rX   rY   r{   saved_matchmatch_foundpn_argsgn_argsr   r   r   s   `  `     @@r!   r   SubgraphMatcher._match_nodes   s   )22"d##
2t(<(< 	
c*2$fRD9?
 	
<  ??2&",, ''))$$R,, ii&  55M! 	uT5[1 	%e:L 	QU 	 	( & BGGBGG,		()T"))..2B-CC(299ejj&;&;<<))++55K	  (;G';G\S\)d299>>3C.DIINNI
 /
 277mG277mGNN4		 0 0 234NN4		 0 0 234K  .t#.t#. G-	 	 IIk*Er#   ra   c                   ^ ^^^ SSK Jn  [        [        5      nT R                   HA  nUR
                   H.  nT R                  XE5      (       d  M  X4   R                  U5        M0     MC     [        UR                  5       5      m[        R                  ST5        / mUUUU 4S jm[        T R                  S9nT(       a	  T" SU5        [        T5      nT Vs/ s H'  nT R                  UR                  5      (       d  M%  UPM)     snm[        T5      nXx:w  a  [        R                  SXx-
  5        / n	T Hc  nUR                  R                  5        V
Vs/ s H  u  pU
R                  S;  d  M  UPM     nn
nU" U5      (       d  MR  U	R                  U5        Me     [        U	5      [        T5      :w  a+  [        R                  S[        T5      [        U	5      -
  5        T R                   (       aD  [        U	5      nT R#                  U	5      m[        T5      nXx:w  a  [        R                  S	Xx-
  5        [        R                  S
T5        T$ s  snf s  snn
f )a  
Returns:
    The matched subgraphs.
    Thre returned subgraph would be fully self-contained, meaning the nodes (except placeholder
    and nodes returned by output) can only be consumed by nodes within the matched subgraph.

Subgraph pattern matcher is implemented with the backtracking style in the following steps:

1. We first identify all the anchor nodes in the pattern graph. The anchor nodes
are the "sinks" (nodes with no user other than the output node) of the pattern graph.
One pattern graph could have multiple anchors if it has multiple return values.

2. In the target graph, we identify the potential candidate nodes that can be matched
with each anchor. These anchor-candidate pairs are the starting points for
pairwise per-node matching.

3. For each anchor-candidate pair, we simultaneously traverse backwards (DFS) in both
pattern and target graphs. For every pattern nodes along traversal path, we compare it
against the target nodes. In case any comparison failed, the match for this anchor-candidate
pair fails. A match is found when DFS completes traversing the graph. See `self._match_nodes`
for more details.

4. In the case of multiple anchors, every anchor will need to find a match using step 3.
In addition, the matches found between anchors need to have a common intersection node
in order for the match to be valid. This is implemented with backtracking. See `backtracking`
for more details.

Notice: graph traversal must be done in the reverser order because a tensor can have multiple
consumers, but can only have a single producer. Only with reverser order, we can we jointly
traverse the pattern and target graph in a deterministic path.

Warning: In theory, this backtracking algorithm have an **exponential** time complexity. However,
in practice, it's unlikely to blow up.

r   )validate_partitionz"Initial match_candidates_list: %s
c                 \  > U [        T	5      :X  a  TR                   Vs/ s H  o!R                  U   PM     snUl        TR                   Vs/ s H  o!R                  U   PM     snUl        T
R                  U5        [        R                  SU5        g T	U    u  p4[        R                  " U5      nU Hk  n[        R                  SX65        TR                  X6U5      nU(       a  T" U S-   U5        O[        R                  SX65        [        R                  " U5      nMm     g s  snf s  snf )NzFound a match: %s
zTrying to match anchor %s to %srF   z Failed to match anchor %s to %s
)rG   rL   r)   r*   rQ   r+   rw   r   r   r.   r   )anchor_indexr{   rX   pattern_anchorcandidate_nodesr   rS   r   backtrackingmatch_candidates_listrt   r/   s           r!   r   +SubgraphMatcher.match.<locals>.backtrackingn  s
   s#899262P2P+2PBOOB'2P+' 372N2N)2NBOOB'2N)% u%159.CL.Q+N))E*K'=~T"//eL !159KK;^
 		+. (+)s   D$D))r'   z<Filtered out %s matches because they are not fully contained>   rD   rE   zfFiltered out %s matches because                           matched subgraph would form a cycle if fusedzAFiltered out %s matches because matched subgraphs are overlappingzMatches returned: %s)!torch.fx.passes.utils.fuser_utilsr   r   r6   rR   rH   rl   rw   ro   r   r   r   rG   rr   r)   rJ   r@   r}   )r/   ra   r   match_candidatesr   rS   r{   beforeaftervalid_matchesrX   rY   matched_compute_nodesr   r   rt   s   `            @@@r!   r{   SubgraphMatcher.match<  s   H 	I 4?t3D"22N((>>$4;;DA $ 3 !%%5%;%;%= >9;PQ')	/ 	/> d&:&:; E" W&-UgU1C1CEOO1T5gUG?KKN E $oo335%5FB55 99 5 " %
 ""788$$U+  }W-KKHGs=11 **'F66}EGLEWN
 	*G4K V%s   $I?II.I)rA   r>   r?   r=   rR   rL   rQ   r@   )FFTF)r   r3   r4   r5   r   r   rV   r	   rh   rl   r8   rr   r6   r   r}   r   r   r   r{   r:   r2   r#   r!   r   r   ?   s"   
 #"'+/ %77 7  	7
 %)7 7 
7rD d t $4 T d tD$J'7 D *'M*'	m	'(5# 53 5} 5 5*ct c cm c cJ|5 |T-%8 |r#   )r.   r   r   collectionsr   dataclassesr   r   typingr   r   r]   torch.fxr   r	   torch.fx._compatibilityr
   __all__r"   r   r   r   r2   r#   r!   <module>r      s      	 # (     1 o
. 
 e,

 
  -
2 e,x x -xr#   