
    3j3              	       8   S SK r S SKrS SKJr  S SKJr  S SKJr  S SKrS SK	r	S SK
r	S SKJr  S SKJr  S SKJrJrJrJr  S SKJr  S S	KJr  S S
KJr  S SKJr  SSKJr  S\\ \	RB                  RD                  RF                     \S\4   4   S\	RH                  RJ                  RL                  S\'\(\	RB                  RD                  RF                  4   S\)4S jr* " S S5      r+S\	RX                  S\-4S jr.S\	RH                  RL                  S\-S-  4S jr/S r0S\	RH                  RL                  S\\)\\   \'\(\4   4   4S jr1S\	RH                  RL                  S\)4S jr2S\	RH                  RL                  S\-S-  4S jr3S\	RH                  RL                  S\)4S jr4g)    N)defaultdict)Callable)Any)enable_python_dispatcher)FakeTensorMode)compute_unbacked_bindingsrebind_unbackedstatically_known_truesym_eq)_pytree)
OrderedSet)tree_map)flop_registry   )Vpattern.nodemodulesreturnc                    [        UR                  5      S:X  a  g[        UR                  S   [        R                  R
                  5      (       a)  [        U[        R                  R
                  5      (       d  gUR                  S   R                  S:w  a  g[        UR                  S   R                  [        5      (       d  gUR                  S   R                  U;  a  g[        X!R                  S   R                     5      U S   La  gUR                  S:w  a  UR                  S:w  a  gUR                  U S   :w  a  g[        UR                  S   R                  5      S:  a  gg)Nr   Fcall_modulecall_functioncall_methodr   T)lenargs
isinstancetorchfxNodeoptargetstrtypeusers)r   r   r   s      R/home/wildlama/miniconda3/lib/python3.13/site-packages/torch/_inductor/fx_utils.pymatches_module_function_patternr&      s   
 499~diilEHHMM22*ehhmm; ; yy|-'diil))3//yy|')GIIaL''();ww/!dgg&>{{gaj 
499Q<"    c                       \ rS rSrSrS\R                  R                  SS4S jrS\R                  R                  4S jr
S	 rS
rg)FakeTensorUpdater=   a  
The main idea here is that it's difficult to maintain accurate fake
tensors (our primary form of metadata) for each node in our graph as we
transform it.

The most reliable way to obtain this information is by rerunning
faketensor propagation. However, in general, faketensor propagation is
fairly expensive. So, instead we'd like to only rerun faketensor
propagation on nodes that have changed.

In order to detect which nodes have changed, we first hash its node,
target, and argument lists (which are immutable in FX).

Then, whenever we call incremental_update, we check which FX nodes have a
new hash, and recompute the faketensor metadata for that node. Then, we
continue to recursively compute the faketensors for all users until the
fake tensors stop changing.
graphr   Nc                     [         [           " 5       U l        Xl        U R                  R                   H-  nU R                  R                  U R                  U5      5        M/     g N)r   r   processed_hashesr+   nodesadd	hash_node)selfr+   r   s      r%   __init__FakeTensorUpdater.__init__Q   sG     *3 1
JJ$$D!!%%dnnT&:; %r'   r   c                 l    XR                   [        UR                  5      [        UR                  5      4$ r-   )r!   idr   kwargs)r2   r   s     r%   r1   FakeTensorUpdater.hash_nodeX   s#    kk2dii="T[[/BBr'   c           	        ^ ^^^ [        [        5      mT R                  R                   H  nT[	        U5      ==   S-  ss'   M     S mUUUU 4S jmS n[
        [           " 5       nT R                  R                   GH  nT R                  U5      T R                  ;   a  [        U5      U;  a  M4  U" U5      (       d  MC  [        U5      u  pEnU(       d  MZ  [        R                     [        5          UR                  " U0 UD6nSSS5        SSS5        SUR                  ;   a  T" WUR                  S   US9(       a  M  [        [        R                  R                   UW5        XqR                  S'   [        R                  R                   =n(       a   [#        X5      =n	(       a  XR                  S'   T[	        U5      ==   S-  ss'   UR%                  UR&                   V
s/ s H  n
[        U
5      PM     sn
5        T R                  R)                  T R                  U5      5        GM     g! , (       d  f       GN2= f! , (       d  f       GN<= fs  sn
f )	zOUpdate FakeTensors on self.graph. We will try to do the minimum amount of work.r   c                 *    [        [        X5      5      $ r-   )r
   r   )newolds     r%   is_intlist_same=FakeTensorUpdater.incremental_update.<locals>.is_intlist_sameb   s    ()9::r'   c                  >^ [        U 5      [        U5      La  g[        U [        [        45      (       a8  [	        U 5      [	        U5      :w  a  g[        UU4S j[        X5       5       5      $ U c  US L $ [        U [        R                  5      (       d  [        U [        R                  [        R                  [        R                  45      (       d    S[        U 5       STR                   35       eU R                  R                  R                  [         R"                  " U R                  R$                  UR                  R$                  5      5      [         R&                  :H  $ T" U R(                  UR(                  5      (       a  U R*                  UR*                  :w  a  gU R*                  [        R,                  :X  aZ  T" U R/                  5       UR/                  5       5      (       a/  [1        U R3                  5       UR3                  5       :H  5      (       d  gU R4                  UR4                  :w  a  g[7        U 5      [7        U5      :X  a  gS nT[7        U5         S:X  a  [7        U 5      T;  a  U" T5      (       d  gg)NFc              3   6   >#    U  H  u  pT" XTS 9v   M     g7f)r   N ).0new_iold_iis_fake_tensor_samer   s      r%   	<genexpr>TFakeTensorUpdater.incremental_update.<locals>.is_fake_tensor_same.<locals>.<genexpr>k   s!      (5 (4@(5s   zUnknown type z in Tc           	      Z   [        U R                  S   [        R                  5      (       d  gU R                   GH  n[        UR
                  [        R                  R                  [        R                  R                  45      (       d=  UR
                  [        R                  R                  R                  R                  L d    g[        UR
                  [        R                  R                  5      (       a  M  [        U5      u  p#nU(       d    g[        R                     [!        5          ["        R$                  " 5        n[        R                  R&                  nUb  UR)                  UR+                  5       5        UR
                  " U0 UD6nS S S 5        S S S 5        S S S 5        [        W[        R                  5      (       d    g[-        U5      [-        U R                  S   5      :X  d  GM    g   g! , (       d  f       Nl= f! , (       d  f       Nu= f! , (       d  f       N~= f)NvalTF)r   metar   Tensorr$   r!   _ops
OpOverloadHigherOrderOperator	_inductor	fx_passes	reinplace_generalized_scatterget_fake_args_kwargsr   	fake_moder   
contextlib	ExitStack	shape_enventer_contextignore_fresh_unbacked_symbolsget_storage)r   useris_validr   r7   stackrX   new_fake_tensors           r%   any_user_may_alias]FakeTensorUpdater.incremental_update.<locals>.is_fake_tensor_same.<locals>.any_user_may_alias   s   !$))E"2ELLAA JJD" KK"ZZ22EJJ4R4RS   ;; ??44>>SST  $!$++uzz/M/MNN !
 .B$-G*HF##02",,.% %&KK$9$9	$0!// ) G G I +/++t*Fv*F / 3 $ &ou||DD#"?3{499UCS7TT#M 'N  /. 32 $s=   $H/HAG:	HH:
HH
HH
H*	r   )r#   r   listtupler   allzipr   rL   SymIntSymBoolSymFloatr+   r   rX   _maybe_evaluate_staticsympyEqexprtrueshapelayoutstridedstrider
   storage_offsetdevicer[   )r;   r<   r   r`   existing_storagesrF   r=   r2   s     ` r%   rF   AFakeTensorUpdater.incremental_update.<locals>.is_fake_tensor_samee   s   CyS	)#e}--s8s3x'  (+C   {d{"c5<<00!#emmU^^'TUU #DI;d4::,?U HH&&==> zz" #399cii88CJJ#**<TzzU]]*#CJJL#**,??,&&(C,>,>,@@  zzSZZ'3;s#33+b "+c"23q8$,==*400r'   c                 R   U R                   S:H  =(       a    [        U R                  [        R                  R
                  5      =(       d]    U R                  [        R                  L =(       d:    U R                  [        R                  R                  R                  R                  L $ )Nr   )r    r   r!   r   rM   rN   operatorgetitemrP   rQ   rR   rS   rA   s    r%   should_process_nodeAFakeTensorUpdater.incremental_update.<locals>.should_process_node   sv     77o- 4;;

(=(=> L;;("2"22L;;??,,66KKLr'   NrJ   rA   unbacked_bindings)r   intr+   r/   get_node_storager   r1   r.   r6   rT   r   rU   r   r!   rK   r	   rX   r   updater$   r0   )r2   r   ry   
to_processr]   r   r7   r_   rX   symbol_to_pathr\   rt   rF   r=   s   `          @@@r%   incremental_update$FakeTensorUpdater.incremental_update\   s   :Ec:JJJ$$D.t45:5 %	;]	 ]	~	  _&
JJ$$D t$(=(==tHJ.&t,,%9$%?"HF68"&++t">v"> 9 		!&95!1' AKK114I.IIe[[222	2";I"WWW 2@		-..t45:5DJJ?JDr$xJ?@!!%%dnnT&:;O %" 98( @s*   (I3H1I%I
1
I ;I
I	)r+   r.   )__name__
__module____qualname____firstlineno____doc__r   r   Graphr3   r   r1   r   __static_attributes__rB   r'   r%   r)   r)   =   s>    &<ehhnn < <Cehhmm C]<r'   r)   tc                 6    U R                  5       R                  $ r-   )untyped_storage_cdata)r   s    r%   r[   r[      s    %%%r'   c                    SU R                   ;  a  g [        U R                   S   [        R                  5      (       d  g [        R                  R                  U R                   S   5      (       d  g [        U R                   S   5      $ NrJ   )rK   r   r   rL   _C_has_storager[   rA   s    r%   r}   r}      sc    DIIdii&5588  5!122tyy'((r'   c                     [        U [        R                  R                  5      (       a!  SU R                  ;  a  U $ U R                  S   $ U $ r   )r   r   r   r   rK   )xs    r%   get_faker   
  s;    !UXX]]##Hvve}Hr'   r   c                     [        [        U R                  U R                  45      u  p[	        S [
        R                  " U0 UD6 5       5      (       a  SX4$ SX4$ )zR
First value returns a boolean if any of the input nodes don't have a faketensor.
c              3   j   #    U  H)  n[        U[        R                  R                  5      v   M+     g 7fr-   )r   r   r   r   )rC   as     r%   rG   'get_fake_args_kwargs.<locals>.<genexpr>  s&      .U
1ehhmm$$.Us   13FT)r   r   r   r7   anypytreearg_tree_leaves)r   r   r7   s      r%   rT   rT     sa     Hqvvqxx&89LD
 .4.D.Dd.Uf.U   d""r'   c                 $  ^^^^ SSK JmJm  S[        R                  R
                  S[        4UU4S jjmT" U 5      (       a  gS[        R                  R
                  S[        4U4S jjm[        U4S jU R                   5       5      (       a  gg	)
zReturns true if a node is always realized when lowered to inductor IR.

NOTE: This may return some false negatives. e.g. it doesn't
handle buffers realized heuristically during lowering, or
buffers realized indirectly through view ops.
r   )	fallbacksneeds_realized_inputsr   r   c                    > U R                   S:X  a2  U R                  [        R                  L a  T" U R                  S   5      $ U R                   S;   =(       d    U R                  T;   $ )Nr   r   )placeholderoutput)r    r!   rw   rx   r   )r   r   	is_buffers    r%   r   #is_node_realized.<locals>.is_buffer'  sS    77o%$++9I9I*I TYYq\**ww33Ot{{i7OOr'   Tc                 N   > U R                   S:H  =(       d    U R                  T;   $ )Nr   )r    r!   )r   r   s    r%   realizes_inputs)is_node_realized.<locals>.realizes_inputs4  s!    ww("Jdkk5J&JJr'   c              3   4   >#    U  H  nT" U5      v   M     g 7fr-   rB   )rC   r\   r   s     r%   rG   #is_node_realized.<locals>.<genexpr>7  s     
8ZT?4  Zs   F)	torch._inductor.loweringr   r   r   r   r   boolr   r$   )r   r   r   r   r   s    @@@@r%   is_node_realizedr     sx     JP P$ P P Kehhmm K K 
8TZZ
888 r'   c                    [        U 5      (       a  [        U R                  [        5      (       a  g [	        SS9   [        U 5      u  pnU(       a]  [        R                  R                  R                  SS9 nU R                  " U0 UD6  S S S 5        WR                  5       nUsS S S 5        $  S S S 5        g ! , (       d  f       N3= f! , (       d  f       g = f)NT)allow_non_fake_inputsF)display)countable_fxr   r!   r"   r   rT   r   utilsflop_counterFlopCounterModeget_total_flops)r   successr   r7   flop_counter_modecounted_flopss         r%   count_flops_fxr   >  s    DKK!=!=	d	3 4T :v))99 : "T,V,
 .==?M  
4	3  
4  	 
4	3 s#   =C7B7
C7
C	C
Cc                     [        U [        R                  R                  5      (       d   e[	        U S5      (       d  gU R
                  n[	        US5      (       d	  U[        ;   $ UR                  nU[        ;   $ )z6
Whether or not we can count the flops of an FX node.
r!   Foverloadpacket)r   r   r   r   hasattrr!   r   r   )r   r!   packets      r%   r   r   O  sg     dEHHMM****4""[[F6+,,&&""F]""r'   )5rV   rw   collectionsr   collections.abcr   typingr   rj   r   torch.fxtorch._dispatch.pythonr   torch._subclasses.fake_tensorr   %torch.fx.experimental.symbolic_shapesr   r	   r
   r   torch.utilsr   r   torch.utils._ordered_setr   torch.utils._pytreer   torch.utils.flop_counterr   virtualizedr   rc   r#   nnr   Moduler   r   r   dictr"   r   r&   r)   rL   r|   r[   r}   r   rT   r   r   r   rB   r'   r%   <module>r      s     # $     ; 8  * / ( 2 
4((//0(382DDE
((--

 #uxx''.../ 
	>|< |<~&5<< &C &)588== )S4Z )	EHHMM 	eD%*d3PS8n4T.U 	588== T @ 3: "#uxx}} # #r'   