ó
    Eñiè3  ã            	       ó<  • 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      ÚU/home/mande/repo/quber/.venv/lib/python3.13/site-packages/torch/_inductor/fx_utils.pyÚmatches_module_function_patternr'      s  € ô
 ˆ4�9‰9ƒ~˜ÓØÜ�d—i‘i ‘l¤E§H¡H§M¡M×2Ñ2¼*ØŒe�h‰h�m‰m÷;ñ ;ð à‡y�y��|‡�˜-Ó'ØÜ�d—i‘i ‘l×)Ñ)¬3×/Ñ/ØØ‡y�y��|×Ñ 'Ó)ØÜˆG—I‘I˜a‘L×'Ñ'Ñ(Ó)°¸±Ò;Øà‡w�w�/Ó! d§g¡g°Ó&>ØØ‡{�{�g˜a‘jÓ Øä
ˆ4�9‰9�Q‰<×ÑÓ Ó"ØØó    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ˆÔØŒ
à—J‘J×$Ô$ˆDØ×!Ñ!×%Ñ% d§n¡n°TÓ&:Ö;ò %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#   € à—k‘k¤2 d§i¡i£=´"°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   [#        X‡5      =n	(       a  X‘R                  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Ö@Ú(5ùs   ƒ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Ñ"2´E·L±L×AÑAàØ ŸJ�J�Dä"Ø ŸK™KÜ"ŸZ™Z×2Ñ2´E·J±J×4RÑ4RÐS÷ñ ð  Ÿ;™;Ü Ÿ?™?×4Ñ4×>Ñ>×SÑSòTñ  $Ü! $§+¡+¬u¯z©z×/MÑ/M×NÑNñ !ô
 .BÀ$Ó-GÑ*�H FÞ#Ù#äŸ›Ü0Õ2Ü"×,Ò,Ô.°%ô %&§K¡K×$9Ñ$9˜	Ø$Ñ0Ø!×/Ñ/Ø )× GÑ GÓ Iôð +/¯+ª+°tÐ*F¸vÑ*F˜÷ /÷ 3÷ $ô & o´u·|±|×DÑDá#Ü" ?Ó3´{À4Ç9Á9ÈUÑCSÓ7TÖ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é  ù€ Ü�C‹y¤ S£	Ò)ØÜ˜#¤¤e˜}×-Ñ-Ü�s“8œs 3›xÓ'Ø Üõ ä(+¨C¬óó ð ð ‰{Ø˜d�{Ð"Ü˜c¤5§<¡<×0Ñ0Ü! #¬¯©´e·m±mÄUÇ^Á^Ð'T×UÑUð Ø#¤D¨£I ;¨d°4·:±:°,Ð?óÐUð —H‘H×&Ñ&×=Ñ=ÜŸš §¡§¡°·±·±Ó>óô —z‘zñ"ðñ # 3§9¡9¨c¯i©i×8Ñ8¸C¿J¹JÈ#Ï*É*Ó<TØØ�z‰zœUŸ]™]Ó*Ù# C§J¡J£L°#·*±*³,×?Ñ?Ü,Ø×&Ñ&Ó(¨C×,>Ñ,>Ó,@Ñ@÷ñ ð à�z‰z˜SŸZ™ZÓ'Øä˜3Ó¤;¨sÓ#3Ó3Øò+ðb "¤+¨cÓ"2Ñ3°qÓ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_nodeÚAFakeTensorUpdater.incremental_update.<locals>.should_process_nodeÄ   sv   € ð —7‘7˜oÑ-÷ Ü˜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ÐØ—J‘J×$Ô$ˆDØÔ.¨tÓ4Ó5¸Ñ:Õ5ñ %ò	;÷]	ð ]	ò~	ô  ¤’_Ó&ˆ
Ø—J‘J×$Õ$ˆDð —‘˜tÓ$¨×(=Ñ(=Ó=Ü�t“H JÓ.áá& t×,Ñ,Ùä%9¸$Ó%?Ñ"ˆH˜FÞÙÜ—“Ô6Õ8Ø"&§+¢+¨tÐ">°vÑ">�÷ 9—ð ˜Ÿ	™	Ó!Ñ&9Ø §¡¨5Ñ!1¸÷'ñ äœAŸK™K×1Ñ1°4¸ÔIà.�I‰I�eÑÜŸ[™[×2Ñ2Ð2�	Õ2Ü";¸IÓ"WÐW�ÕWð 2@—	‘	Ð-Ñ.àÔ.¨tÓ4Ó5¸Ñ:Ó5à×Ñ°D·J²JÓ?²J¨Dœr $žx±JÑ?Ô@à×!Ñ!×%Ñ% d§n¡n°TÓ&:×;ò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>   † ñð&<˜eŸh™hŸn™nð <°ô <ðC˜eŸh™hŸm™mô 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   € Ø�D—I‘IÓØÜ�d—i‘i Ñ&¬¯©×5Ñ5ØÜ�8‰8× Ñ  §¡¨5Ñ!1×2Ñ2ØÜ�t—y‘y Ñ'Ó(Ð(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;   € Ü�!”U—X‘X—]‘]×#Ñ#Ø˜Ÿ™ÓØˆHØ�v‰v�e‰}ÐØ€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¨Œ
�1”e—h‘h—m‘m×$Ð$Ò.Uùs   ‚13FT)r   r•   r   r8   ÚanyÚpytreeÚarg_tree_leaves)r”   r   r8   s      r&   rU   rU     sa   € ô œH q§v¡v¨q¯x©xÐ&8Ó9�L€DÜ
ñ Ü.4×.DÒ.DÀdÐ.UÈfÒ.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	)
zìReturns 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   ø€ Ø�7‰7�oÓ%¨$¯+©+¼×9IÑ9IÒ*Iñ ˜TŸY™Y q™\Ó*Ð*Ø�w‰wÐ3Ñ3×O°t·{±{ÀiÑ7OÐ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!   ø€ Ø�w‰w˜(Ñ"×J d§k¡kÐ5JÑ&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   øé € Ð
8ªZ T‰?˜4× Ð ªZùs   ƒ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œeŸh™hŸm™mð K´÷ Kô Ô
8¨T¯ZªZÓ
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¶   € Ü˜×Ñ¤¨D¯K©K¼×!=Ñ!=ØÜ	¨dÓ	3Ü 4°TÓ :Ñˆ�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   € ô �dœEŸH™HŸM™M×*Ñ*Ð*Ð*Ü�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À¸8Ñ2DÐDÑEðà
�(‰(�-‰-×
Ñ
ðð �#�u—x‘x×'Ñ'×.Ñ.Ð.Ñ/ðð 
ô	÷>|<ñ |<ð~&�5—<‘<ð & Cô &ð)˜5Ÿ8™8Ÿ=™=ð )¨X°c©]ô )òð	˜EŸH™HŸM™Mð 	¨e°D¸%À¹*ÀdÈ3ÐPSÈ8ÁnÐ4TÑ.Uô 	ð˜5Ÿ8™8Ÿ=™=ð ¨Tô ð@˜Ÿ™Ÿ™ð ¨8°C©=ô ð"#�u—x‘x—}‘}ð #¨õ #r(   