
    ȅi3              	       <   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  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\ \!\
RD                  RF                  RH                     \S\4   4   S\
RJ                  RL                  RN                  S\(\)\
RD                  RF                  RH                  4   S\*4S jr+ " S S5      r,S\
RZ                  S\.4S jr/S\
RJ                  RN                  S\\.   4S jr0S r1S\
RJ                  RN                  S\ \*\ \   \(\)\4   4   4S jr2S\
RJ                  RN                  S\*4S jr3S\
RJ                  RN                  S\\.   4S jr4S\
RJ                  RN                  S\*4S jr5g)    N)defaultdict)Callable)AnyOptional)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/james-whalen/.local/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)r3   r   s     r&   r2   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   r8   stackrY   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   rM   SymIntSymBoolSymFloatr,   r   rY   _maybe_evaluate_staticsympyEqexprtrueshapelayoutstridedstrider   storage_offsetdevicer\   )r<   r=   r   ra   existing_storagesrG   r>   r3   s     ` r&   rG   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   rN   rO   operatorgetitemrQ   rR   rS   rT   rB   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(   NrK   rB   unbacked_bindings)r   intr,   r0   get_node_storager   r2   r/   r7   rU   r   rV   r   r"   rL   r
   rY   r	   updater%   r1   )r3   r   rz   
to_processr^   r   r8   r`   rY   symbol_to_pathr]   ru   rG   r>   s   `          @@@r&   incremental_update$FakeTensorUpdater.incremental_update\   s   =H=M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   Graphr4   r    r2   r   __static_attributes__rC   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      $ NrK   )rL   r   r   rM   _C_has_storager\   rB   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    rL   )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    )rD   as     r&   rH   'get_fake_args_kwargs.<locals>.<genexpr>  s&      .U
1ehhmm$$.Us   13FT)r   r   r   r8   anypytreearg_tree_leaves)r   r   r8   s      r&   rU   rU     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"   rx   ry   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.   rC   )rD   r]   r   s     r&   rH   #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   rU   r   utilsflop_counterFlopCounterModeget_total_flops)r   successr   r8   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(   )6rW   rx   collectionsr   collections.abcr   typingr   r   rk   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   rd   r$   nnr   Moduler   r   r    dictr#   r   r'   r*   rM   r}   r\   r~   r   rU   r   r   r   rC   r(   r&   <module>r      s     # $      ; 8  * / ( 2 
4((//0(382DDE
((--

 #uxx''.../ 
	>|< |<~&5<< &C &)588== )Xc] )	EHHMM 	eD%*d3PS8n4T.U 	588== T @ 8C= "#uxx}} # #r(   