
    7hP'              	       ,   S SK r S SKJr  S SKJr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\\\R@                  RB                  RD                     \S\4   4   S\RF                  RH                  RJ                  S\&\'\R@                  RB                  RD                  4   S\(4S jr) " S S5      r*S\RV                  S\,4S jr-S\RF                  RJ                  S\\,   4S jr.S r/S\RF                  RJ                  S\\(\\   \&\'\4   4   4S jr0S\RF                  RJ                  S\(4S jr1S\RF                  RJ                  S\\,   4S jr2S\RF                  RJ                  S\(4S jr3g)    N)defaultdict)AnyCallable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/var/www/fran/franai/venv/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__O   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_nodeV   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   5      (       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N3= f! , (       d  f       GN== fs  sn
f )Nr   c                 *    [        [        X5      5      $ r.   )r   r   )newolds     r&   is_intlist_same=FakeTensorUpdater.incremental_update.<locals>.is_intlist_same_   s    ()9::r(   c                   > [        U 5      [        U5      :w  a  g[        U [        [        45      (       a7  [	        U 5      [	        U5      :w  a  g[        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T[7        U5         S:X  a  [7        U 5      T;  a  gg)NFc              3   8   >#    U  H  u  pT" X5      v   M     g 7fr.    ).0new_iold_iis_fake_tensor_sames      r&   	<genexpr>TFakeTensorUpdater.incremental_update.<locals>.is_fake_tensor_same.<locals>.<genexpr>h   s      JW,%'55-s   zUnknown type z in Tr   )r$   r   listtupler   allzipr   TensorSymIntSymBoolSymFloatr,   r   	shape_env_maybe_evaluate_staticsympyEqexprtrueshapelayoutstridedstrider   storage_offsetdeviceget_storage)r<   r=   existing_storagesrF   r>   r3   s     r&   rF   AFakeTensorUpdater.incremental_update.<locals>.is_fake_tensor_sameb   s   CyDI%#e}--s8s3x'  JMc-   {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 "+c"23q8$,==r(   c                     U R                   S:H  =(       aR    [        U R                  [        R                  R
                  5      =(       d    U R                  [        R                  :H  $ )Nr   )r!   r   r"   r   _ops
OpOverloadoperatorgetitemr   s    r&   should_process_nodeAFakeTensorUpdater.incremental_update.<locals>.should_process_node   sI     77o- 4;;

(=(=> 3;;("2"22r(   valunbacked_bindings)r   intr,   r0   get_node_storager   r2   r/   r7   get_fake_args_kwargsr   	fake_moder   r"   metar
   rQ   r	   updater%   r1   )r3   r   rf   
to_processis_validr   r8   new_fake_tensorrQ   symbol_to_pathuserr^   rF   r>   s   `          @@@r&   incremental_update$FakeTensorUpdater.incremental_updateZ   s   =H=MJJ$$D.t45:5 %	;+	 +	Z		  _&
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&:;C % 98$ @s*   (I3H2I&I
2
I<I
I	)r,   r/   )__name__
__module____qualname____firstlineno____doc__r   r   Graphr4   r    r2   ru   __static_attributes__rB   r(   r&   r*   r*   ;   s>    &<ehhnn < <Cehhmm Cb<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      $ Nrh   )rn   r   r   rM   _C_has_storager]   re   s    r&   rk   rk      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    rn   )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   r8   anypytreearg_tree_leaves)r   r   r8   s      r&   rl   rl      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"   rc   rd   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_inputs   s!    ww("Jdkk5J&JJr(   c              3   4   >#    U  H  nT" U5      v   M     g 7fr.   rB   )rC   rt   r   s     r&   rG   #is_node_realized.<locals>.<genexpr>   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 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)
r   r"   r#   r   rl   r   utilsflop_counterFlopCounterModeget_total_flops)r   successr   r8   flop_counter_modecounted_flopss         r&   count_flops_fxr     s    $++s##	d	3 4T :v))99 : "T,V,
 .==?M  
4	3  
4  	 
4	3 s#   =B8'B':B8'
B5	1B88
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&   countable_fxr     sg     dEHHMM****4""[[F6+,,&&""F]""r(   )4rc   collectionsr   typingr   r   r   rS   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   rJ   r$   nnr   Moduler   r   r    dictr#   r   r'   r*   rM   rj   r]   rk   r   rl   r   r   r   rB   r(   r&   <module>r      s    # * *    ; 8  * / ( 2 
4((//0(382DDE
((--

 #uxx''.../ 
	>A< A<H&5<< &C &)588== )Xc] )	EHHMM 	eD%*d3PS8n4T.U 	588== T @ 8C= "#uxx}} # #r(   