ó
    Eñi&  ã            
       ó¦  • S r SSKrSSKrSSKr\R                  R
                  R                  \R                  R
                  R                  1rS\R                  R                  S\4S jrS\R                  R                  S\\\\\R                  R                  \\R                  R$                  4      4   SS4S jrS\S	\\\R                  R                  \\R                  R$                  4      S\4S
 jrS\R                  R                  S	\\\R                  R                  \\R                  R$                  4      S\\   S\4S jrg)aZ  
DCE pass for unused extra outputs in HOP subgraphs.

When enable_side_effects_with_extra_outputs is True, HOPs like invoke_subgraph and
checkpoint (tag_activation_checkpoint)
return all intermediate tensors/symints as extra outputs to support side effects.
However, many of these extra outputs may not actually be used in the parent graph.

This pass removes unused extra outputs by:
1. Collecting all callers for each subgraph
2. Checking if each output is used by all callers
3. Removing unused outputs from the subgraph's output node
4. Updating the HOP call and getitem indices in all call sites

é    NÚgmÚreturnc                 ó®  • [         R                  " [        5      n[        X5        U(       d  gSnUR	                  5        GH  nUS   u  pEn[        XE5      n[        U[        R                  R                  5      (       d  MB  [        S UR                  R                   5       5      nUR                  S   n	[        U	[        [        45      (       d  M”  [        U	5      n
[!        5       n[#        U
5       H&  n[%        XÃ5      (       d  M  UR'                  U5        M(     S[        U5      s=:  a  U
:  d  Mö  O  Mú  [)        XsU5      (       d  GM  SnGM     U$ )aÉ  
Remove unused extra outputs from HOP calls in all submodules.

For each subgraph output, check if any caller has a getitem for that index
with users. If no caller uses it, remove the output.
If the user in caller is an output node, to simply the algorithm, we do not recursively check
if the caller's output is used further up in the call chain.

Args:
    gm: The GraphModule to optimize

Returns:
    True if any modifications were made, False otherwise
Fr   c              3   óH   #   • U  H  oR                   S :X  d  M  Uv •  M     g7f©ÚoutputN©Úop©Ú.0Úns     Ú\/home/mande/repo/quber/.venv/lib/python3.13/site-packages/torch/_dynamo/dce_extra_outputs.pyÚ	<genexpr>Ú(dce_hop_extra_outputs.<locals>.<genexpr>@   s   é € ÐOÒ&: ¿d¹dÀhÑ>NŸ1™1Ò&:ùó   ‚"™	"T)ÚcollectionsÚdefaultdictÚlistÚ_collect_all_subgraph_usagesÚvaluesÚgetattrÚ
isinstanceÚtorchÚfxÚGraphModuleÚnextÚgraphÚnodesÚargsÚtupleÚlenÚsetÚrangeÚ_is_output_usedÚaddÚ_dce_subgraph)r   Úsubgraph_id_to_callersÚmodifiedÚcallersÚ	parent_gmÚsubgraph_nameÚ_ÚsubgraphÚoutput_nodeÚoutput_argsÚnum_outputsÚused_indicesÚidxs                r   Údce_hop_extra_outputsr3      s  € ô$ 	×Ò¤Ó%ð ô ! Ô<æ!Øà€Hà)×0Ñ0×2ˆØ&-¨a¡jÑ#ˆ	 !Ü˜9Ó4ˆä˜(¤E§H¡H×$8Ñ$8×9Ñ9ÙäÑO h§n¡n×&:Ò&:ÓOÓOˆØ!×&Ñ& qÑ)ˆÜ˜+¬¬t }×5Ñ5Ùä˜+Ó&ˆÜ!$£ˆô ˜Ö%ˆCÜ˜s×,Ó,Ø× Ñ  Ö%ñ &ð
 Œs�<Ó Õ. ;×.Ñ.Ü˜X°×=Ô=Ø“ñ/ 3ð2 €Oó    r'   c                 ó0  • U R                   R                   Hü  nUR                  S:X  d  M  UR                  [        ;   d  M+  UR
                  S   n[        U[        R                  R                  5      (       d  Me  UR                  S:X  d  Mw  UR                  n[        U[        5      (       d   e[        XS5      n[        U[        R                  R                  5      (       d  MÑ  [        U5      nX   R                  XU45        [        XQ5        Mþ     g)z9Recursively collect all HOP usages across the graph tree.Úcall_functionr   Úget_attrN)r   r   r
   ÚtargetÚ_HOPS_WITH_EXTRA_OUTPUTSr   r   r   r   ÚNodeÚstrr   r   ÚidÚappendr   )r   r'   ÚnodeÚsubgraph_attrr+   r-   Úsubgraph_ids          r   r   r   U   sË   € ð —‘—”ˆØ�7‰7�oÕ%¨$¯+©+Ô9QÕ*QØ ŸI™I a™LˆMä˜=¬%¯(©(¯-©-×8Ó8Ø!×$Ñ$¨
Õ2à -× 4Ñ 4�Ü! -´×5Ñ5Ð5Ð5Ü" 2°dÓ;�Ü˜h¬¯©×(<Ñ(<×=Ó=Ü"$ X£,�KØ*Ñ7×>Ñ>Ø¨DÐ1ôô 1°ÖRò r4   Ú
output_idxr)   c                 ó  • U H|  u  p#nUR                    Hf  nUR                  S:X  d  M  UR                  [        R                  :X  d  M5  UR
                  S   U :X  d  MJ  [        UR                   5      S:”  d  Me      g   M~     g)zECheck if output_idx is used by ANY caller (has a getitem with users).r6   é   r   TF)Úusersr
   r8   ÚoperatorÚgetitemr   r!   )rA   r)   Ú
_parent_gmÚ_subgraph_nameÚhop_nodeÚusers         r   r$   r$   n   se   € ó
 18Ñ,ˆ
 HØ—N”NˆDØ�w‰w˜/Õ)¨d¯k©k¼X×=MÑ=MÕ.MØ—9‘9˜Q‘< :Õ-´#°d·j±j³/ÀAÕ2EÚó #ñ 18ð
 r4   r-   r1   c           	      óÂ  ^^• [        S U R                  R                   5       5      n[        UR                  S   5      nSnU(       a1  [        U5      S:¼  a"  TR                  S5        TR                  S5        [        T5      [        U5      :¼  d  [        T5      S:X  a  g0 n/ nSn[        [        U5      5       H'  n	U	T;   d  M  X†U	'   UR                  XI   5        US-  nM)     U R                  R                  U5         U R                  R                  [        U5      5      n
SSS5        UR                  W
5        U R                  R                  U5        U GHã  u  p¼n[        UR                  5       GHL  nUR                  S:X  d  M  UR                   ["        R$                  :X  d  M6  UR                  S   n	['        U	[(        5      (       d   eX–;  aA  [        [        UR                  5      5      S:X  d   eUR                  R                  U5        M¢  Xi   nUR                  R                  U5         UR                  R+                  ["        R$                  UR                  S   U4S9nUR,                  R/                  5       Ul        SSS5        UR                  W5        UR                  R                  U5        GMO     S	UR,                  ;   d  GM€  UR,                  S	   m['        T[        [        45      (       d   e[        UU4S
 j[        [        U5      5       5       5      nUUR,                  S	'   GMæ     U R                  R1                  5         U R3                  5         U Vs1 s H  nUS   iM
     sn H-  nUR                  R1                  5         UR3                  5         M/     g! , (       d  f       GN—= f! , (       d  f       GN?= fs  snf )zŸ
DCE a subgraph by removing unused output indices.

Updates the subgraph's output node, all getitem nodes in callers,
and example_value metadata on HOP nodes.
c              3   óH   #   • U  H  oR                   S :X  d  M  Uv •  M     g7fr   r	   r   s     r   r   Ú _dce_subgraph.<locals>.<genexpr>†   s   é € ÐKÒ"6˜Q¿$¹$À(Ñ:J—q‘qÒ"6ùr   r   Fé   rC   Nr6   )r   Úexample_valuec              3   ó>   >#   • U  H  nUT;   d  M  TU   v •  M     g 7f)N© )r   Úold_idxÚold_exampler1   s     €€r   r   rM   É   s'   øé € ð  â6�GØ˜lÑ*ó %�˜GÖ$Ú6ùs   ƒ
‘T)r   r   r   r   r   r!   r%   r#   r=   Úinserting_beforer   r    Úreplace_all_uses_withÚ
erase_noderD   r
   r8   rE   rF   r   Úintr6   ÚmetaÚcopyÚlintÚ	recompile)r-   r)   r1   r.   Úold_outputsÚis_autograd_fwdÚ
old_to_newÚnew_outputsÚnew_idxrR   Únew_output_noder*   r,   rI   rJ   Únew_getitemÚnew_exampleÚcallerrS   s     `               @r   r&   r&   {   s#  ù€ ô ÑK (§.¡.×"6Ò"6ÓKÓK€KÜ�{×'Ñ'¨Ñ*Ó+€Kð €Oö œ3˜{Ó+¨qÓ0Ø×Ñ˜ÔØ×Ñ˜Ôô ˆ<ÓœC Ó,Ó,´°LÓ0AÀQÓ0FØð "$€JØ€KØ€Gäœ˜[Ó)Ö*ˆØ�lÕ"Ø")�wÑØ×Ñ˜{Ñ3Ô4Ø�q‰LŠGñ	 +ð 
�‰×	(Ñ	(¨Õ	5Ø"Ÿ.™.×/Ñ/´°kÓ0BÓCˆ÷ 
6à×%Ñ% oÔ6Ø‡N�N×Ñ˜kÔ*ä")Ñˆ	�hä˜Ÿ™×(ˆDØ�w‰w˜/Õ)¨d¯k©k¼X×=MÑ=MÕ.MØŸ)™) A™,�Ü! '¬3×/Ñ/Ð/Ð/àÓ,Üœt D§J¡JÓ/Ó0°AÓ5Ð5Ð5Ø—O‘O×.Ñ.¨tÔ4Ùà$Ñ-�à—_‘_×5Ñ5°dÕ;Ø"+§/¡/×"?Ñ"?Ü ×(Ñ(°·	±	¸!±¸gÐ/Fð #@ð #�Kð (,§y¡y§~¡~Ó'7�KÔ$÷ <ð ×*Ñ*¨;Ô7Ø—‘×*Ñ*¨4×0ñ' )ð, ˜hŸm™mÖ+Ø"Ÿ-™-¨Ñ8ˆKÜ˜k¬E´4¨=×9Ñ9Ð9Ð9Üõ  ä$¤S¨Ó%5Ô6ó ó ˆKð
 .9ˆH�M‰M˜/Ô*ñA #*ðF ‡N�N×ÑÔØ×ÑÔá.5Ó6ªg F�f˜Q”i©gÔ6ˆ	Ø�‰×ÑÔØ×ÑÖñ 7ð ÷_ 
6Ö	5ú÷& <Ö;üò0 7s   Ä%N8È;AO
Í4OÎ8
OÏ

O)Ú__doc__r   rE   r   ÚopsÚhigher_orderÚinvoke_subgraphÚtag_activation_checkpointr9   r   r   Úboolr3   ÚdictrW   r   r    r;   r:   r   r$   r"   r&   rQ   r4   r   Ú<module>rl      sa  ðñó  Û ã ð
 
‡I�I×Ñ×*Ñ*Ø	‡I�I×Ñ×4Ñ4ðÐ ð3˜eŸh™h×2Ñ2ð 3°tô 3ðlSØ�‰×ÑðSà ØˆT�%˜Ÿ™×,Ñ,¨c°5·8±8·=±=Ð@ÑAÑBÐBñðSð
 
ôSð2
Øð
à�%˜Ÿ™×,Ñ,¨c°5·8±8·=±=Ð@ÑAÑBð
ð 
ô
ð]Ø�h‰h×"Ñ"ð]à�%˜Ÿ™×,Ñ,¨c°5·8±8·=±=Ð@ÑAÑBð]ð �c‘(ð]ð 
õ	]r4   