
     TipE                        S r SSKJr  SSKrSSKrSSKrSSKJrJr  SSK	J
s  Jr  SSKJ
s  Jr  SSKJr        SS jr " S S\R"                  5      r " S	 S
\5      rg)z1Implementation of the pattern matching algorithm.    )annotationsN)IterableSequence)irc                    U  HW  nUR                    HD  nX1;   a  M
  UR                  5       (       a      gUR                  5        H  u  pEX@;  d  M        g   MF     MY     g)znCheck that values computed by the matched_nodes, except for output_values, are used only by the matched_nodes.FT)outputsis_graph_outputuses)matched_nodesoutput_valuesnvconsumer_s         [/var/www/html/ai-image-ml/venv/lib/python3.13/site-packages/onnxscript/rewriter/_matcher.py_valid_to_replacer      sW     A!  "" vvx0   (       c                  v    \ rS rSrS
S jr\R                  SSSS.             SS jj5       rSS jrS	r	g)PatternMatcher)   c                    Xl         g Npattern)selfr   s     r   __init__PatternMatcher.__init__*   s    r   r   TNverboseremove_nodestracerc                   g)z@Match the pattern against the subgraph ending at the given node.N )r   modelgraph_or_functionnoder   r    r!   s          r   matchPatternMatcher.match-   s    r   c                ,    [        U R                  5      $ r   )strr   )r   s    r   __str__PatternMatcher.__str__:   s    4<<  r   r   r   z_pattern_ir.GraphPatternreturnNoner$   ir.Modelr%   ir.Graph | ir.Functionr&   ir.Noder   intr    boolr!   z_basics.MatchingTracer | Noner.   _basics.MatchResult)r.   r*   )
__name__
__module____qualname____firstlineno__r   abcabstractmethodr'   r+   __static_attributes__r#   r   r   r   r   )   s~     	 !04
O
O 2
O 	
O 
O 
O .
O 

O 
O!r   r   c                     ^  \ rS rSrSU 4S jjrSSS jjrSS jrSS jr      SS jr      SS jr	SS	 jr
SS
 jr          SS jr      SS jrSSSS.             SS jjrSrU =r$ )SimplePatternMatcher>   c                2   > [         TU ]  U5        S U l        g r   )superr   _current_node)r   r   	__class__s     r   r   SimplePatternMatcher.__init__?   s    !-1r   Nc                    U R                   (       a1  U R                  R                  5       nUS:  a  [        SU SU 35        U R                  R	                  X=(       d    U R
                  5        g)Nr   zMatch failed after z nodes: F)_verbose_matchnum_matched_nodesprintfailrC   )r   reasonr&   rI   s       r   rK   SimplePatternMatcher.failC   s\    == $ = = ? 1$+,=+>hvhOP!;););<r   c           	       ^^^ UR                   nUc,  U R                  SUR                   STR                   S35      $  UR	                  5       mTR                  m[        T[        5      (       a  [        T5      4nTR                  U:w  a/  U R                  SUR                   STR                   SU S35      $ [        UUU4S j[        [        T5      5       5       5      (       d  U R                  S	T S
T S35      $ gTR                  S:w  a"  U R                  SUR                   ST S35      $ [        R                  " TR!                  5       TTR"                  TR$                  S9(       d&  U R                  ST S
TR!                  5        S35      $ g! [
         a"    U R                  SUR                   S35      s $ f = f)a0  Match a Constant pattern against a value.

If the constant value is produced by a Constant node, we do not include
the constant node as part of the matched graph. Thus, it will not be deleted,
if subgraph replacement happens. But subsequent DCE will remove the constant
node if it is not used elsewhere.
Value z is not a constant, expecting .zConstant value of z not available.z has shape z, expecting c              3     >#    U  HB  n[         R                  " TR                  U5      TU   TR                  TR                  S 9v   MD     g7f)rel_tolabs_tolN)mathiscloseitem_rel_tol_abs_tol).0inumpy_valuepattern_constantpattern_constant_values     r   	<genexpr>7SimplePatternMatcher._match_constant.<locals>.<genexpr>f   sM       <A $$Q'*1-,55,55	 <s   A
AzValue mismatch: expected , got Tr   z is not a scalar, expecting rR   z"Constant value mismatch: expected )const_valuerK   namevaluenumpyFileNotFoundError_value
isinstancelistlenshapeallrangendimrU   rV   rW   rX   rY   )r   r]   rd   constant_valueexpected_shaper\   r^   s    `   @@r   _match_constant$SimplePatternMatcher._match_constantK   s    **!99$BCSCYCYBZZ[\ 	O(..0K "2!8!8,d33!"89;N  N2yyUZZLK4E4E3FlSaRbbcd    s#9:;   yy/0F/Gvk]Z[\   q 99$@AW@XXYZ  ||"$--$--	
 9945K4LFS^ScScSeRffgh  S ! 	O991%**_MNN	Os    F )GGc                >   X l         U R                  R                  U5      nUb  X2La  U R                  S5      $ gU R                  nUR	                  X$5      (       d  U R                  UR
                  5      $ U R                  (       a  [        SUR                   35        UR                  X5        [        UR                  5      [        UR                  5      :  ap  UR                  (       d>  U R                  S[        UR                  5       S[        UR                  5       S35      $ [        UR                  UR                  5      nO*[        R                  " UR                  UR                  SS9nU H8  u  pgUc  Uc  M  U R                  S	5      s  $ U R!                  Xv5      (       a  M8    g
   [#        UR$                  5       HO  u  pU[        UR$                  5      :  a    g
U R                  R'                  XR$                  U   5      (       a  MO    g
   g)z;Matches a pattern subgraph against subgraph rooted at node.Nz;Same pattern node is matched against different graph nodes.Tz	Matched: zNumber of inputs (z) is greater than expected ())	fillvaluez3(Optional) input is expected to be None but is not.F)rC   rH   lookup_noderK   matchesrL   rG   rJ   op_type	bind_noderj   inputsallow_other_inputszip	itertoolszip_longest_match_value	enumerater   
bind_value)
r   pattern_noder&   matched_noder'   checked_inputs	arg_valuearg_patternr[   output_value_patterns
             r   _match_node SimplePatternMatcher._match_node   s   ! {{..|<#'yy!^__##D0099U\\**==Idll^,-+ t{{c,"5"56622yy(T[[)9(::VWZ[g[n[nWoVppqr  !l.A.ABN '22\00DN '5"I"$99%Z[[$$[<< '5 (11E1E'F#A C%%;;))*>QPP (G r   c                B   Ub  UR                   U R                  Lat  [        U[        R                  [        R
                  [        R                  45      (       d6  U R                  SUR                   SU R                  R                   S35      $ [        U[        R                  5      (       a  gU R                  R                  X5      (       d  g[        U[        R                  5      (       a%  Uc  U R                  S5      $ U R                  X5      $ [        U[        R
                  5      (       a%  Uc  U R                  S5      $ U R                  X5      $ [        U[        R                  5      (       a  [        UR                   5       H  u  p4U R                  R#                  5         U R%                  XB5      (       a\  UR&                  b3  U R                  R)                  UR&                  UR*                  U   5        U R                  R-                  5           gU R                  R/                  5         M     U R                  S5      $ [        U[        R0                  5      (       a  Uc  U R                  S	5      $ UR3                  U5      nUc  U R                  S
5      $ Uu  p4U R%                  XB5      nU(       a3  UR&                  b&  U R                  R)                  UR&                  U5        U$ Uc&  UR4                  (       d  U R                  SU S35      $ g)z2Match an IR value against a ValuePattern instance.rO   z is not in the graph z>. Pattern matches crossing graph boundaries are not supported.TFz4Mismatch: Computed node pattern does not match None.z/Mismatch: Constant pattern does not match None.z!None of the alternatives matched.z.Mismatch: OrValue pattern does not match None.z/Mismatch: OrValue pattern does not match value.zMismatch: pattern variable z does not match None.)graph_graphrh   _pattern_irVarConstantAnyValuerK   rc   rH   r   NodeOutputPattern_match_node_outputrq   BacktrackingOrr   _valuesenter_new_matchr   tag_varbind_tag_valuesmerge_current_matchabandon_current_matchOpIdDispatchOrget_patterncan_match_none)r   pattern_valuerd   r[   pattern_choicealternativeresults          r   r   !SimplePatternMatcher._match_value   s    DKK!?1E1E{G[G[\ 
 yyUZZL(=dkk>N>N=O PS T  m[%9%9::{{%%m;;m[%B%BCC}yy!WXX**=@@m[%9%9::}yy!RSS''==m[%?%?@@%.}/D/D%E!++-$$^;;$,,8(()>)>@Y@YZ[@\]KK335113 &F 99@AAm[%?%?@@}yy!QRR'33E:K"yy!RSS +A&&~=F ((4KK$$]%:%:A>M=!=!=99-m_<QR  r   c                &   UR                  5       nUc  U R                  S5      $ UR                  5       UR                  :w  a0  U R                  SUR                   SUR                  5        S35      $ U R                  UR                  5       U5      $ )z7Match an IR value against a NodeOutputPattern instance.zCMismatch: Computed node pattern does not match uncomputed IR value.z%Node output index mismatch: expected ra   rP   )producerrK   indexoutput_index_output_indexr   )r   r   rd   r&   s       r   r   'SimplePatternMatcher._match_node_output   s     ~~<99U  ;;=M6669978S8S7TTZ[`[f[f[hZiijk   6 6 8$??r   c                R    Xl         [        R                  " 5       U l        SU l        g)z@Initialize the match state. Invoked before starting a new match.N)rG   _basicsMatchResultrH   rC   )r   r   s     r   _init_match SimplePatternMatcher._init_match  s    +2+>+>+@!r   c                \   / n/ n[        U R                  R                  5       H  u  p4UR                  bu  UR                  U R                  R
                  ;   a4  UR                  U R                  R
                  UR                     5        Mj  UR                  UR                  5        M  X@R                  R                  ;   a*  UR                  U R                  R                  U   5        M  UR                  SU 35        M     U(       a  U R                  R                  SU 35        gU$ )z8Get values bound to the output variables of the pattern.Noutput_z Error: Output values not found: )	r   r   r   rc   rH   bindingsappendvalue_bindingsrK   )r   r   unbound_valuesjvalue_patterns        r   _get_output_values'SimplePatternMatcher._get_output_values  s    (*$& )$,,*>*> ?A!!- %%)=)==!(()=)=m>P>P)QR"))-*<*<= KK$>$>>!(()C)CM)RS"))GA3-8 !@ KK??OPQr   c                   AAU R                   nU R                  nUR                  (       d  UR                  S5      $ U R	                  UR
                  U5      (       d  U$ U R                  5       nUc  U$ U(       a,  [        UR                  U5      (       d  UR                  S5      $ UR                  R                  U5        U$ )Nz`Internal Error: SimplePatternMatcher should not be used for patterns with multiple output nodes.5Matched nodes have other uses preventing replacement.)r   rH   has_single_output_noderK   r   output_noder   r   nodesr   extend)r   r$   r%   r&   check_removabler   r'   r   s           r   _match_single_output_node.SimplePatternMatcher._match_single_output_node   s     ,,--::r   3 3T::L//1 L#4U[[-#P#P::UVV]+r   c                j   U R                   n[        U R                  R                  U5       H  u  pEU R	                  XE5      (       a  M  Us  $    U R                  5       nUc  U$ U(       a,  [        UR                  U5      (       d  UR                  S5      $ UR                  R                  U5        U$ )a  Find a match for a pattern with multiple output nodes.

For a pattern with K output nodes, the input candidate should specify K nodes
in the graph that will be matched against the pattern output nodes.

Args:
    candidate: An iterable of nodes that will be matched against the pattern output nodes.
    check_removable: If True, check that the matched nodes can be removed (that is, that
        they are not used elsewhere in the graph).
r   )rH   r|   r   output_nodesr   r   r   r   rK   r   r   )r   	candidater   r'   r   r&   r   s          r   _multi_match!SimplePatternMatcher._multi_match@  s     "%dll&?&?"KL##L77 #L //1 L#4U[[-#P#P::UVV]+r   r   Tr   c                 ^^ X`l         [        U[        R                  5      (       a  X l        OUR
                  U l        U R                  R                  (       a!  U R                  U5        U R                  XX5S9$ U R                  R                  n0 mU H2  nTR                  UR                  5       / 5      R                  U5        M4     [        U5      mUU4S jn	[        U/5      /USS  V
s/ s H
  o" U
5      PM     sn
-   nSn[        R                   " U6  H.  nU R                  U5        U R#                  XS9nU(       d  M,  Us  $    Uc$  [$        R&                  " 5       R)                  S5      $ U$ s  sn
f )a  Match the pattern against the subgraph ending at the given node.

For patterns with multiple output nodes, the given node is matched
against the first output node in the pattern. For the remaining
output nodes in the pattern, we use a brute-force algorithm that
enumerates all possible combinations of nodes from the graph (with
a filter based on op-type).

TODO: Consider omitting parameters model and graph_or_function. With
the new IR, the graph can be obtained from the node, and the model is
not used. But this is a shared abstract method of the Matcher interface,
so other matcher implementation also needs to be updated. More importantly,
matching in the presence of subgraphs (control-flow) can introduce some
complications which require careful consideration.
)r   c                R   > U R                  5       nUc  T$ TR                  U/ 5      $ r   )op_identifierget)r   id	all_nodesop_to_nodess     r   	get_nodes-SimplePatternMatcher.match.<locals>.get_nodes  s-    !//1:$$"r2..r      NzNo match found.)_tracerrh   r   Graphr   r   r   r   r   r   r   
setdefaultr   r   iterr}   productr   r   r   rK   )r   r$   r%   r&   r   r    r!   pattern_output_nodesr   r   pn
candidatesr'   combinationr   r   s                 @@r   r'   SimplePatternMatcher.match[  s^   2 '22$5K+11DK<<..W%11$ 2   $(<<#<#< EGK&&&q'8"=DDQG './I/ v,CWXYXZC[*\C[R9R=C[*\\JE(00*=  )))+)T5 L	  >
 }**,112CDDL +]s   1E7)rC   r   rH   r   rG   r-   r   )rL   r*   r&   zir.Node | Noner.   r5   )r]   z_pattern_ir.Constantrd   ir.Valuer.   r5   )r   z_pattern_ir.NodePatternr&   r3   r.   r5   )r   z_pattern_ir.ValuePatternrd   zir.Value | Noner.   r5   )r   z_pattern_ir.NodeOutputPatternrd   r   r.   r5   )r   r4   r.   r/   )r.   zlist[ir.Value] | None)
r$   r1   r%   r2   r&   r3   r   r5   r.   r6   )r   zIterable[ir.Node]r   r5   r.   r6   r0   )r7   r8   r9   r:   r   rK   rq   r   r   r   r   r   r   r   r'   r=   __classcell__)rD   s   @r   r?   r?   >   s   29v6p757>M7	7r@:@CK@	@"( 2 	
  
@*=A	B !04BB 2B 	B B B .B 
B Br   r?   )r   zSequence[ir.Node]r   zSequence[ir.Value]r.   r5   )__doc__
__future__r   r;   r}   rU   typingr   r   onnxscript.rewriter._basicsrewriterr   onnxscript.rewriter._pattern_irr   
onnxscriptr   r   ABCr   r?   r#   r   r   <module>r      sg    8 " 
  
 . - 5 5 $5G	*!SWW !*_> _r   