
    9j3              	       *   d dl Z d dlZd dlmZ d dlmZ d dlmZ d dlZd dl	Z	d dl
Z	d dlmZ d dlmZ d dlmZmZmZmZ d dlmZ d d	lmZ d d
lmZ d dlmZ ddlmZ dee e	jB                  jD                  jF                     edef   f   de	jH                  jJ                  jL                  de'e(e	jB                  jD                  jF                  f   de)fdZ* G d d      Z+de	jX                  de-fdZ.de	jH                  jL                  de-dz  fdZ/d Z0de	jH                  jL                  dee)ee   e'e(ef   f   fdZ1de	jH                  jL                  de)fdZ2de	jH                  jL                  de-dz  fdZ3de	jH                  jL                  de)fdZ4y)    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                    t        |j                        dk(  ryt        |j                  d   t        j                  j
                        r$t        |t        j                  j
                        sy|j                  d   j                  dk7  ryt        |j                  d   j                  t              sy|j                  d   j                  |vryt        ||j                  d   j                           | d   ury|j                  dk7  r|j                  dk7  ry|j                  | d   k7  ryt        |j                  d   j                        dkD  ryy)Nr   Fcall_modulecall_functioncall_methodr   T)lenargs
isinstancetorchfxNodeoptargetstrtypeusers)r   r   r   s      X/media/conek/DATA/Code/OCR/venv/lib/python3.12/site-packages/torch/_inductor/fx_utils.pymatches_module_function_patternr&      s
   
 499~diilEHHMM2*ehhmm; yy|-'diil))3/yy|')GDIIaL''();ww/!dgg&>{{gaj 
499Q<"    c                       e Zd ZdZdej
                  j                  ddfdZdej
                  j                  fdZ	d Z
y)	FakeTensorUpdatera:  
    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                     t        t                  | _        || _        | j                  j                  D ],  }| j                  j                  | j                  |             . y N)r   r   processed_hashesr*   nodesadd	hash_node)selfr*   r   s      r%   __init__zFakeTensorUpdater.__init__Q   sN     *3 1
JJ$$ 	<D!!%%dnnT&:;	<r'   r   c                 n    ||j                   t        |j                        t        |j                        fS r,   )r!   idr   kwargs)r1   r   s     r%   r0   zFakeTensorUpdater.hash_nodeX   s%    dkk2dii="T[[/BBr'   c           	      V    t        t               j                  j                  D ]  }t	        |      xx   dz  cc<    d  fdd }t        t                  } j                  j                  D ]  } j                  |       j                  v rt        |      |vr/ ||      s8t        |      \  }}}|sJt        j                  5  t               5   |j                  |i |}ddd       ddd       d|j                  v r |j                  d   |      rt        t        j                  j                   |       ||j                  d<   t        j                  j                   x}rt#        ||      x}	r|	|j                  d<   t	        |      xx   dz  cc<   |j%                  |j&                  D 
cg c]  }
t        |
       c}
        j                  j)                   j                  |              y# 1 sw Y   xY w# 1 sw Y   !xY wc c}
w )	zOUpdate FakeTensors on self.graph. We will try to do the minimum amount of work.r   c                 ,    t        t        | |            S r,   )r
   r   )newolds     r%   is_intlist_samez=FakeTensorUpdater.incremental_update.<locals>.is_intlist_sameb   s    (S)9::r'   c                   t        |       t        |      uryt        | t        t        f      r7t	        |       t	        |      k7  ryt        fdt        | |      D              S | |d u S t        | t        j                        st        | t        j                  t        j                  t        j                  f      s J dt        |        dj                          | j                  j                  j                  t!        j"                  | j                  j$                  |j                  j$                              t         j&                  k(  S  | j(                  |j(                        r| j*                  |j*                  k7  ry| j*                  t        j,                  k(  rP | j/                         |j/                               r*t1        | j3                         |j3                         k(        sy| j4                  |j4                  k7  ryt7        |       t7        |      k(  ryd }t7        |         dk(  rt7        |       vr	 |      syy)NFc              3   :   K   | ]  \  }} ||         yw)r   N ).0new_iold_iis_fake_tensor_samer   s      r%   	<genexpr>zTFakeTensorUpdater.incremental_update.<locals>.is_fake_tensor_same.<locals>.<genexpr>k   s)      $u (u4@@s   zUnknown type z in Tc           	         t        | j                  d   t        j                        sy| j                  D ]  }t        |j
                  t        j                  j                  t        j                  j                  f      s<|j
                  t        j                  j                  j                  j                  u s yt        |j
                  t        j                  j                        rt        |      \  }}}|s yt        j                  5  t!               5  t#        j$                         5 }t        j                  j&                  }||j)                  |j+                                 |j
                  |i |}d d d        d d d        d d d        t        t        j                        s yt-        |      t-        | j                  d         k(  s y y# 1 sw Y   _xY w# 1 sw Y   cxY w# 1 sw Y   gxY w)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   r5   stackrS   new_fake_tensors           r%   any_user_may_aliasz]FakeTensorUpdater.incremental_update.<locals>.is_fake_tensor_same.<locals>.any_user_may_alias   s   !$))E"2ELLA JJ &$D" KK"ZZ22EJJ4R4RS  ;; ??44>>SST  $!$++uzz/M/MN !
 .B$-G*HdF##G02G #,,.G 38 %&KK$9$9	$0!// ) G G I +6$++t*Fv*FG G G &ou||D#"?3{499UCS7TT#M&$N %G G G G G Gs=   G3G'/AG	=G'G3G$ G''G0,G33G<	r   )r#   r   listtupler   allzipr   rG   SymIntSymBoolSymFloatr*   r   rS   _maybe_evaluate_staticsympyEqexprtrueshapelayoutstridedstrider
   storage_offsetdevicerV   )r8   r9   r   r[   existing_storagesrB   r:   r1   s     ` r%   rB   zAFakeTensorUpdater.incremental_update.<locals>.is_fake_tensor_samee   s   CyS	)#e}-s8s3x'  (+C   {d{"c5<<0!#emmU^^'TU #DI;d4::,?U HH&&==> zz" #399cii8CJJ#**<TzzU]]*#CJJL#**,?,&&(C,>,>,@@ zzSZZ'3;s#33+b "+c"23q8$,==*40r'   c                 4   | j                   dk(  xr t        | j                  t        j                  j
                        xsX | j                  t        j                  u xs: | j                  t        j                  j                  j                  j                  u S )Nr   )r    r   r!   r   rH   rI   operatorgetitemrK   rL   rM   rN   r=   s    r%   should_process_nodezAFakeTensorUpdater.incremental_update.<locals>.should_process_node   sv     77o- 4;;

(=(=> L;;("2"22L;;??,,66KKLr'   NrE   r=   unbacked_bindings)r   intr*   r.   get_node_storager   r0   r-   r4   rO   r   rP   r   r!   rF   r	   rS   r   updater$   r/   )r1   r   rr   
to_processrX   r   r5   rZ   rS   symbol_to_pathrW   rn   rB   r:   s   `          @@@r%   incremental_updatez$FakeTensorUpdater.incremental_update\   s   :Ec:JJJ$$ 	;D.t45:5	;	;]	~	  _&
JJ$$ '	<D t$(=(==tHJ.&t,%9$%?"HdF ?68 ?"-$++t">v">? ? 		!&95!1' AKK114I.DIIe[[222	2";I"WWW 2@		-..t45:5DJJ?Dr$x?@!!%%dnnT&:;O'	<"? ? ? ?( @s*   HH2HH&
HHH#	)__name__
__module____qualname____doc__r   r   Graphr2   r   r0   ry   r>   r'   r%   r)   r)   =   s>    &<ehhnn < <Cehhmm C]<r'   r)   tc                 6    | j                         j                  S r,   )untyped_storage_cdata)r   s    r%   rV   rV      s    %%%r'   c                     d| j                   vry t        | j                   d   t        j                        sy t        j                  j                  | j                   d         sy t        | j                   d         S NrE   )rF   r   r   rG   _C_has_storagerV   r=   s    r%   ru   ru      s]    DIIdii&588  5!12tyy'((r'   c                     t        | t        j                  j                        rd| j                  vr| S | j                  d   S | S r   )r   r   r   r   rF   )xs    r%   get_faker   
  s8    !UXX]]#Hvve}Hr'   r   c                     t        t        | j                  | j                  f      \  }}t	        d t        j                  |i |D              rd||fS d||fS )zZ
    First value returns a boolean if any of the input nodes don't have a faketensor.
    c              3   d   K   | ](  }t        |t        j                  j                         * y wr,   )r   r   r   r   )r?   as     r%   rC   z'get_fake_args_kwargs.<locals>.<genexpr>  s$      )*
1ehhmm$s   .0FT)r   r   r   r5   anypytreearg_tree_leaves)r   r   r5   s      r%   rO   rO     sb     Hqvvqxx&89LD&
 .4.D.Dd.Uf.U  dF""vr'   c                    ddl mm dt        j                  j
                  dt        ffd |       rydt        j                  j
                  dt        ffdt        fd| j                  D              ryy	)
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                     | j                   dk(  r1| j                  t        j                  u r | j                  d         S | j                   dv xs | j                  v S )Nr   r   )placeholderoutput)r    r!   rp   rq   r   )r   r   	is_buffers    r%   r   z#is_node_realized.<locals>.is_buffer'  sS    77o%$++9I9I*I TYYq\**ww33Ot{{i7OOr'   Tc                 B    | j                   dk(  xs | j                  v S )Nr   )r    r!   )r   r   s    r%   realizes_inputsz)is_node_realized.<locals>.realizes_inputs4  s!    ww("Jdkk5J&JJr'   c              3   .   K   | ]  } |        y wr,   r>   )r?   rW   r   s     r%   rC   z#is_node_realized.<locals>.<genexpr>7  s     
8T?4 
8s   F)	torch._inductor.loweringr   r   r   r   r   boolr   r$   )r   r   r   r   r   s    @@@@r%   is_node_realizedr     sm     JP P$ P Kehhmm K K 
8TZZ
88 r'   c                    t        |       rt        | j                  t              ry t	        d      5  t        |       \  }}}|r`t        j                  j                  j                  d      5 } | j                  |i | d d d        j                         }|cd d d        S 	 d d d        y # 1 sw Y   .xY w# 1 sw Y   y xY w)NT)allow_non_fake_inputsF)display)countable_fxr   r!   r"   r   rO   r   utilsflop_counterFlopCounterModeget_total_flops)r   successr   r5   flop_counter_modecounted_flopss         r%   count_flops_fxr   >  s    DKK!=	d	3 
! 4T :v))99 :  -"T,V,-
 .==?M 
! 
! 
! - -	
! s#   <B;/B/B;/B8	4B;;Cc                     t        | t        j                  j                        sJ t	        | d      sy| j
                  }t	        |d      s|t        v S |j                  }|t        v S )z>
    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  s^     dEHHMM***4"[[F6+,&&""F]""r'   )5rQ   rp   collectionsr   collections.abcr   typingr   rd   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   r]   r#   nnr   Moduler   r   r   dictr"   r   r&   r)   rG   rt   rV   ru   r   rO   r   r   r   r>   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'   