
    pi3              	       &   d dl Z d dlZd dlmZ d dlmZmZ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e-   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e-   fdZ3de	jH                  jL                  de)fdZ4y)    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                    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      Z/opt/services/ai/voice_agent/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__P   sN     *3 1
JJ$$ 	<D!!%%dnnT&:;	<r(   r   c                 n    ||j                   t        |j                        t        |j                        fS r-   )r"   idr   kwargs)r2   r   s     r&   r1   zFakeTensorUpdater.hash_nodeW   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_samea   s    (S)9::r(   c                   t        |       t        |      k7  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>j   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                  k(  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   r6   stackrT   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=   G4G(0AG	>G(G4G%!G((G1-G44G=	r   )r$   r   listtupler   allzipr   rH   SymIntSymBoolSymFloatr+   r   rT   _maybe_evaluate_staticsympyEqexprtrueshapelayoutstridedstrider   storage_offsetdevicerW   )r9   r:   r   r\   existing_storagesrC   r;   r2   s     ` r&   rC   zAFakeTensorUpdater.incremental_update.<locals>.is_fake_tensor_samed   s   CyDI%#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                 8   | j                   dk(  xr t        | j                  t        j                  j
                        xsZ | j                  t        j                  k(  xs; | j                  t        j                  j                  j                  j                  k(  S )Nr   )r!   r   r"   r   rI   rJ   operatorgetitemrL   rM   rN   rO   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(   NrF   r>   unbacked_bindings)r   intr+   r/   get_node_storager   r1   r.   r5   rP   r   rQ   r   r"   rG   r
   rT   r	   updater%   r0   )r2   r   rs   
to_processrY   r   r6   r[   rT   symbol_to_pathrX   ro   rC   r;   s   `          @@@r&   incremental_updatez$FakeTensorUpdater.incremental_update[   s   =H=M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&:;M&	<"? ? ? ?& @s*   HH2HH&
HHH#	)__name__
__module____qualname____doc__r   r   Graphr3   r    r1   rz   r?   r(   r&   r*   r*   <   s>    &<ehhnn < <Cehhmm C\<r(   r*   tc                 6    | j                         j                  S r-   )untyped_storage_cdata)r   s    r&   rW   rW      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 NrF   )rG   r   r   rH   _C_has_storagerW   r>   s    r&   rv   rv      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    rG   )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&   rD   z'get_fake_args_kwargs.<locals>.<genexpr>  s$      )*
1ehhmm$s   .0FT)r   r   r   r6   anypytreearg_tree_leaves)r   r   r6   s      r&   rP   rP     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"   rq   rr   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_inputs2  s!    ww("Jdkk5J&JJr(   c              3   .   K   | ]  } |        y wr-   r?   )r@   rX   r   s     r&   rD   z#is_node_realized.<locals>.<genexpr>5  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   rP   r   utilsflop_counterFlopCounterModeget_total_flops)r   successr   r6   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   M  s^     dEHHMM***4"[[F6+,&&""F]""r(   )5rR   rq   collectionsr   typingr   r   r   re   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*   rH   ru   rW   rv   r   rP   r   r   r   r?   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(   