ó
    EñinI ã                  óÌ  • % S SK Jr  S SKrS SKrS SKrS SKrS SKrS SKrS SKrS SK	r	S SK
r
S SKrS SKrS SKrS SKrS SKrS SKJrJr  S SKJrJr  S SKJrJrJrJrJrJrJr  S SKJr  S SKJr  SS	K J!r!  \(       a  S S
K"J#r#J$r$J%r%  S SK&J'r'  S SK(r(S SK)r)S SK*r)S SK+J,s  J-r.  S SK/J0r0J1r1  S SK2J3r3  S SK4J5r5J6r6  S SK7J8r8  S SK9J:r:J;r;  S SK<J=r=  S SK>J?r?J@r@JArA  S SKBJCrC  SSKDJErEJFrFJGrGJHrHJ r JIrI  SSKJJKrK  SSKLJMrMJNrNJOrO  SSKPJQrQJRrR  SSKHJSrSJTrTJUrUJVrV  SSKWJXrXJYrY  SSKZJ[r[  SSK J\r\J]r]J^r^J_r_J`r`Jara  SSKbJcrc  SSKdJereJfrf  SSKgJhrh  SSKiJjrjJkrk  SS KlJmrm  SS!K,JnrnJoroJprpJqrqJrrrJsrsJtrtJuruJvrvJwrwJxrxJyryJzrzJ{r{J|r|J}r}J~r~Jr  SS"K€J�r�  \GR                  " \ƒ5      r„\)GR
                  GR                  \ƒS#5      r‡\)GR
                  GR                  \ƒS$5      rˆ\)GR
                  GR                  \ƒS%5      r‰\)GR
                  GR                  \ƒS&5      rŠ\‹S'   rŒS(\�S)'   \" S*5      rŽ\" S+5      r�\GR                    " S, S-5      5       r‘\GR                    " S. S/5      5       r’ " S0 S15      r“\GR                    " S2 S35      5       r”\GR                    " S4 S5\”5      5       r• " S6 S'5      r–\GR.                  ScS7 j5       r˜SdS8 jr™SeS9 jršSfS: jr›\GR                   " S;S<9 " S= S>5      5       rœSgS? jr� " S@ SA5      rž        ShSB jrŸ " SC SD\–5      r  " SE SF\–5      r¡ " SG SH\–5      r¢    SiSI jr£        SjSK jr¤ " SL SM\–5      r¥ " SN SO\¥5      r¦ " SP SQ\¥5      r§ " SR SS\–5      r¨ Sk       SlST jjr©      SmSU jrªSnSV jr«\GR                    " SW SX5      5       r¬\GRZ                  " 5       r®SoSY jr¯SpSZ jr°    SqS[ jr±SrS\ jr²SrS] jr³SrS^ jr´SrS_ jrµ " S` SJ5      r¶ " Sa Sb5      r·g)sé    )ÚannotationsN)ÚCounterÚdefaultdict)Úas_completedÚFuture)ÚAnyÚGenericÚOptionalÚTYPE_CHECKINGÚ	TypeAliasÚTypeVarÚUnion)Ú	ParamSpec©Ú
OrderedSeté   )ÚComputedBuffer)ÚCallableÚIteratorÚSequence)Ú
ModuleType)ÚcountersÚdynamo_timed)Úuse_pipelined_autotuning)ÚLambdaFutureÚPyCodeCache)ÚTritonTemplateCallerBase)Úget_metric_tableÚis_metric_table_enabled)Úfree_symbols)Úfree_symbol_is_typeÚsymbol_is_typeÚSymT)Ú
has_triton)ÚcommsÚconfigÚconfig_commsÚdependenciesÚirÚmetrics)Úcan_codegen_without_upcasts)ÚBackendFeatureÚget_scheduling_for_deviceÚKernel)Ú estimate_nccl_collective_runtimeÚ/estimate_nccl_collective_runtime_nccl_estimator)ÚDepÚ	MemoryDepÚStarDepÚWeakDep)ÚGPUTooOldForTritonÚTritonMissing)Úcount_flops_fx)Úassign_origin_nodeÚget_device_typeÚGraphPartitionSignatureÚMultiOutputÚMultiOutputLayoutÚ
NoneLayout)ÚLoopBody)ÚMemoryPlanningInfoForBufferÚMemoryPlanningInfoForNode)ÚReductionHint)Ú
green_textÚred_text)ÚSimplifyIndexing)Ú&_unstable_customized_partition_wrapperÚcache_on_selfÚcmpÚdevice_need_guardÚget_current_backendÚget_device_tflopsÚget_dtype_sizeÚget_gpu_dram_gbpsÚget_op_namesÚGraphPartitionMapÚIndentedBufferÚis_collectiveÚis_cudagraph_unsafe_opÚis_gpuÚis_multi_outputs_templateÚ#is_output_of_multi_outputs_templateÚis_waitÚsympy_product)ÚVÚfusionÚloop_orderingÚcompute_dependenciesÚ
cudagraphsÚBaseSchedulerNoder   ÚPartitionTypeÚ_TÚ_Pc                  óz   • \ rS rSr% SrS\S'   SrS\S'   SrS\S'   S	 r\	SS
 j5       r
\	 S   SS jj5       rSrg)ÚFusionResultéh   NzOptional[bool]Úshould_fusezOptional[Callable[[], bool]]Úcallable_fnúOptional[LambdaFuture]Úfuturec                óV   • U R                   S LU R                  S L-  (       d   S5       eg )NzLFusion result should contain either fusion decision or callable_fn, not both)rc   rd   ©Úselfs    ÚV/home/mande/repo/quber/.venv/lib/python3.13/site-packages/torch/_inductor/scheduler.pyÚ__post_init__ÚFusionResult.__post_init__n   s0   € Ø× Ñ ¨Ð,°×1AÑ1AÈÐ1M×Nð 	
ØZó	
ÑNó    c                ó   • [        US9$ )N)rc   ©ra   )Úclsrc   s     rj   ÚfuseÚFusionResult.fuses   s   € ä¨Ñ4Ð4rm   c                ó   • [        XS9$ )N©rd   rf   ro   )rp   rd   rf   s      rj   Úfrom_callableÚFusionResult.from_callablew   s   € ô ¨ÑCÐCrm   © )rc   Úbool©N)rd   úCallable[[], bool]rf   re   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__rc   Ú__annotations__rd   rf   rk   Úclassmethodrq   ru   Ú__static_attributes__rw   rm   rj   ra   ra   h   sf   ‡ à"&€K�Ó&Ø04€KÐ-Ó4Ø%)€FÐ"Ó)ò
ð
 ó5ó ð5ð àOSðDØ,ðDØ6LôDó óDrm   ra   c                  óL   • \ rS rSr% S\S'   S\S'   S\S'   SrS\S	'   SS
 jrSrg)ÚPendingFusioné~   rz   rd   r\   Únode1Únode2Nre   rf   c                ó2   • U R                   U R                  4$ ry   ©r…   r†   rh   s    rj   Úget_fusion_nodesÚPendingFusion.get_fusion_nodes…   s   € Ø—
‘
˜DŸJ™JÐ'Ð'rm   rw   )Úreturnú+tuple[BaseSchedulerNode, BaseSchedulerNode])r{   r|   r}   r~   r   rf   r‰   r�   rw   rm   rj   rƒ   rƒ   ~   s$   ‡ à#Ó#ØÓØÓØ%)€FÐ"Ó)÷(rm   rƒ   c                  óD  • \ rS rSrSr\SS j5       r\SS j5       r\      SS j5       r	\SS j5       r
\      SS j5       r\      SS j5       r\SS	 j5       r\      SS
 j5       r\SS j5       r\      SS j5       r\SS j5       r\SS j5       rSrg)ÚMixOrderReductioné‰   z�
This class contains utility functions to decide if we should fuse reductions
reducing across different dimensions of the same input tensor.
c                óp   • U R                  5       =(       a     [        S U R                  5        5       5      $ )Nc              3  óð   #   • U  Hl  n[        U[        5      (       d  M  UR                  5       (       d  M1  [        UR                  [        5      (       d  MR  UR                  R
                  S Lv •  Mn     g 7fry   )Ú
isinstanceÚSchedulerNodeÚis_reductionÚnoder   Ú_split_size©Ú.0Úsubnodes     rj   Ú	<genexpr>Ú7MixOrderReduction.is_split_reduction.<locals>.<genexpr>‘   sZ   é € ð +
â+�Ü˜'¤=×1ó 1ð ×$Ñ$×&ó 1ô ˜7Ÿ<™<¬×8ó	 1ˆG�L‰L×$Ñ$¨DÕ0Ú+ùs   ‚A6ŸA6¶A6ÁA6)r”   ÚallÚ	get_nodes©r•   s    rj   Úis_split_reductionÚ$MixOrderReduction.is_split_reduction�   s3   € à× Ñ Ó"÷ 
¤sñ +
àŸ>™>Ô+ó+
ó (
ð 	
rm   c                ó¦  • U R                  U5      (       Ga¬  S nS nUR                  5        GH‹  n[        U[        5      (       a4  UR	                  5       (       a  [        UR
                  [        5      (       d  MO  UR
                  R                  c   e[        R                  R                  R                  [        UR
                  R                  5      5      nUR
                  R                  c   e[        R                  R                  R                  [        UR
                  R                  5      5      nUc  UnUnGM  [        R                  R                  R                  X%5      (       d   U SU 35       e[        R                  R                  R                  X65      (       a  GM‚   U SU 35       e   Uc   eX#4$ UR                  S   $ )Nú v.s. r   )rŸ   r�   r’   r“   r”   r•   r   Ú_original_rangesrW   ÚgraphÚsizevarsÚsimplifyrV   Ú_original_reduction_rangesÚstatically_known_equalsÚgroup)rp   r•   ÚxnumelÚrnumelr™   Ú	curxnumelÚ	currnumels          rj   Úget_numel_rnumelÚ"MixOrderReduction.get_numel_rnumel™   s–  € à×!Ñ! $×'Ò'ØˆFØˆFØŸ>™>×+�ä˜w¬×6Ñ6Ø×,Ñ,×.Ñ.Ü" 7§<¡<´×@Ñ@áà—|‘|×4Ñ4Ñ@Ð@Ð@ÜŸG™G×,Ñ,×5Ñ5Ü! '§,¡,×"?Ñ"?Ó@ó�	ð —|‘|×>Ñ>ÑJÐJÐJÜŸG™G×,Ñ,×5Ñ5Ü! '§,¡,×"IÑ"IÓJó�	ð ‘>Ø&�FØ&“FäŸ7™7×+Ñ+×CÑCØ÷ñ ð 4à ˜ ¨	 {Ð3ó4ð ô Ÿ7™7×+Ñ+×CÑCØ÷ô ð 4à ˜ ¨	 {Ð3ó4ð ñ1 ,ð8 Ñ%Ð%Ð%ØÐ#Ð#à—:‘:˜a‘=Ð rm   c                óÎ   • U R                  U5      nU R                  U5      n[        U5      S:w  d  [        U5      S:w  d  X4:X  a  g[        U5      [        [        U5      5      :H  $ )Né   F)r®   ÚlenÚtupleÚreversed)rp   r…   r†   Úg1Úg2s        rj   Úhas_mix_reduction_ordersÚ*MixOrderReduction.has_mix_reduction_orders¿   sX   € ð ×!Ñ! %Ó(ˆØ×!Ñ! %Ó(ˆäˆr‹7�a‹<œ3˜r›7 a›<¨2«8Øä�R‹yœE¤(¨2£,Ó/Ñ/Ð/rm   c                ó   • SnUR                   R                   H.  n[        U[        5      (       d  M  UR                  U:X  d  M,  Un  O   U(       d  gUR
                  nUR                   R                  nU(       dI  [        U[        5      (       d   [        U5       5       eUR                  S   R                   R                  nU(       d   e[        U5      [        UR                  5      -
  (       d  g[        R                  R                  R                  [!        UR"                  5      [!        UR%                  5       5      5      (       a  gg)z0
The access to 'buf' is not a broadcast access.
NFr   T)Úread_writesÚreadsr’   r2   ÚnameÚindexÚ
var_rangesÚFusedSchedulerNodeÚtypeÚsnodesr   r    rW   r¤   r¥   r¨   rV   ÚsizeÚvalues)rp   Úbufr•   Ú	found_depÚdepr½   r¾   s          rj   Ú_is_full_accessÚ!MixOrderReduction._is_full_accessË   s  € ð
 ˆ	Ø×#Ñ#×)Ô)ˆCÜ˜#œy×)Ó)¨c¯h©h¸#­oØ�	Ùñ *ö
 Øà—‘ˆØ×%Ñ%×0Ñ0ˆ
æÜ˜dÔ$6×7Ñ7ÐH¼DÀ»J¸<ÓHÐ7ØŸ™ Q™×3Ñ3×>Ñ>ˆJæÐˆzÜ˜:Ó&¬°E×4FÑ4FÓ)G×GØô
 �7‰7×Ñ×3Ñ3Ü˜)Ÿ.™.Ó)¬=¸×9JÑ9JÓ9LÓ+M÷
ñ 
ð Ørm   c                óà   • / nUR                  5       UR                  5       -  nU HD  nU R                  XQ5      (       d  M  U R                  XR5      (       d  M3  UR                  U5        MF     U$ ry   )Úused_buffer_namesrÇ   Úappend)rp   r…   r†   ÚoutÚcommon_readsrÄ   s         rj   Úget_common_readÚ!MixOrderReduction.get_common_readí   sb   € ð ˆØ×.Ñ.Ó0°5×3JÑ3JÓ3LÑLˆÛˆCØ×"Ñ" 3×.Ó.°3×3FÑ3FÀs×3RÓ3RØ—
‘
˜3–ñ  ð ˆ
rm   c                ó<   • [        U R                  X5      5      S:„  $ ©Nr   )r²   rÎ   ©rp   r…   r†   s      rj   Úhas_common_readÚ!MixOrderReduction.has_common_readù   s   € ô �3×&Ñ& uÓ4Ó5¸Ñ9Ð9rm   c                ó†   • U R                  U5      n[        R                  R                  R	                  US   US   -  SS9$ )Nr   r   ©Úfallback)r®   rW   r¤   r¥   Úoptimization_hint)rp   r•   rµ   s      rj   Ú	get_numelÚMixOrderReduction.get_numelÿ   s>   € à×!Ñ! $Ó'ˆÜ�w‰w×Ñ×1Ñ1°"°Q±%¸"¸Q¹%±-È!Ð1ÐLÐLrm   c                ó$   • U R                  U5      $ ry   )rÙ   rÒ   s      rj   Úget_fusion_scoreÚ"MixOrderReduction.get_fusion_score  s   € ð
 �}‰}˜UÓ#Ð#rm   c                óò  • [         R                  R                  (       d  g[        R                  R
                  (       a  gUR                  5       (       a  UR                  5       (       d  gUR                  5       R                  nUS;  d  [        U5      S:w  a  gUR                  5       (       a  UR                  5       (       d  gUR                  UR                  5       -  (       d"  UR                  UR                  5       -  (       a  gU R                  X5      (       d  g[        R                  X5      n[!        U5      S:X  a  gU R#                  U5      (       a  XpeOU R#                  U5      (       a  X!peOgU R%                  U5      nUu  p‰[         R                  R&                  (       dÒ  Sn
[        R                  R(                  R+                  [,        R.                  " X‰-  U
5      5      (       d  g[        R                  R(                  R+                  [,        R.                  " X‰S-  5      5      (       d  g[        R                  R(                  R+                  [,        R.                  " US5      5      (       d  g[1        S UR3                  5        5       5      (       a  g[        R                  R(                  R5                  U	S	5      (       d  g[7        S
 UR3                  5        5       5      nU$ )z@
Check whether we can fuse two reductions with mix loop orders.
F)ÚcudaÚxpuÚtritonr   i  P r±   i   c              3  óÒ   #   • U  H]  nUR                  5       (       d  M  UR                  R                  R                  [        R
                  [        R                  4;  v •  M_     g 7fry   )r”   r•   ÚdataÚreduction_hintrA   ÚINNERÚDEFAULTr—   s     rj   rš   Ú-MixOrderReduction.can_fuse.<locals>.<genexpr>V  sU   é € ð 
ò 7�Ø×#Ñ#×%óˆG�L‰L×Ñ×,Ñ,ä×#Ñ#Ü×%Ñ%ðöò
 7ùs   ‚A'ŸAA'i @  c              3  óŠ   #   • U  H9  nUR                  5       (       d  M  UR                  R                  5       S ;   v •  M;     g7f)>   ÚsumÚprodN)r”   r•   Úget_reduction_typer—   s     rj   rš   rç   i  s@   é € ð 
ò 2�Ø×#Ñ#×%óˆG�L‰L×+Ñ+Ó-ðöò
 2ùs
   ‚AŸ$A)r&   rá   Úmix_order_reductionrW   r¤   Úcpp_wrapperrR   Ú
get_devicerÀ   rI   r”   Ú	ancestorsÚget_operation_namesr·   rŽ   rÎ   r²   Úis_contiguous_noder®   Ú#mix_order_reduction_non_strict_moder¥   Úguard_or_trueÚsympyÚGeÚanyr�   Ústatically_known_leqrœ   )rp   r…   r†   Údevice_typerÍ   Úcontiguous_nodeÚ
other_noderµ   ÚnrowÚncolÚ
size_thresrÌ   s               rj   Úcan_fuseÚMixOrderReduction.can_fuse  sK  € ô
 �}‰}×0×0Øô �7‰7××Øà�|‰|�~‰~ U§\¡\§^¡^ØØ×&Ñ&Ó(×-Ñ-ˆà˜Ó.Ü" ;Ó/°8Ó;àØ×!Ñ!×#Ñ#¨5×+=Ñ+=×+?Ñ+?Øà�O‰O˜e×7Ñ7Ó9×9Ø�O‰O˜e×7Ñ7Ó9×9ð ð ×+Ñ+¨E×9Ñ9Øô )×8Ñ8¸ÓFˆÜˆ|Ó Ó!Øà×!Ñ! %×(Ñ(Ø*/™ZØ×#Ñ# E×*Ñ*Ø*/™Zàà×!Ñ! /Ó2ˆØ‰
ˆô �}‰}×@×@ð #ˆJô
 —7‘7×#Ñ#×1Ñ1´%·(²(¸4¹;È
Ó2S×TÑTØô
 —7‘7×#Ñ#×1Ñ1´%·(²(¸4ÈÁÓ2J×KÑKØô
 —7‘7×#Ñ#×1Ñ1´%·(²(¸4ÀÓ2F×GÑGØô ñ 
ð +×4Ñ4Ô6ó
÷ 
ñ 
ð ô
 �w‰w×Ñ×4Ñ4°T¸9×EÑEØô ñ 
ð &×/Ñ/Ô1ó
ó 
ˆð ˆ
rm   c                ó$   • U R                  X5      $ ry   )rþ   rÒ   s      rj   Úare_mix_order_reductionsÚ*MixOrderReduction.are_mix_order_reductionst  s   € ð �|‰|˜EÓ)Ð)rm   c                óh   ^ ^• [        U U4S jTR                  R                   5       5      (       d  gg)Nc              3  ó\   >#   • U  H!  nTR                  UR                  T5      v •  M#     g 7fry   )Úis_contiguous_loadr¼   )r˜   rÆ   rp   r•   s     €€rj   rš   Ú7MixOrderReduction.is_contiguous_node.<locals>.<genexpr>|  s)   øé € ð 
Ú>T°sˆC×"Ñ" 3§8¡8¨T×2Ð2Ò>Tùs   ƒ),FT)rœ   rº   r»   )rp   r•   s   ``rj   rñ   Ú$MixOrderReduction.is_contiguous_nodez  s1   ù€ äõ 
Ø>B×>NÑ>N×>TÒ>Tó
÷ 
ñ 
ð Ørm   c                ó:  • SSK Jn  UR                  5        Hü  n[        U[        5      (       d   eUR
                  nUR                  UR                     nU Vs/ s H   owR                  U:X  d  M  UR                  PM"     nn[        U5      S:X  a  M}  U Hy  n	UR                  U	   n
UR                  n[        UR                  5       5      n[        R                   R"                  R%                  U
UU5      nUS   S:X  a  Mm  US   S:X  a  Mx      g   Mþ     gs  snf )Nr   )ÚMemoryUsageTypeéÿÿÿÿr   FT)Útorch._inductor.loop_bodyr	  r�   r’   r“   Ú_bodyÚmemory_usageÚLOADÚbuffer_nameÚ
index_namer²   Úindexing_exprsr¾   ÚlistÚkeysrW   r¤   r¥   Ústride_vars)rp   rÄ   Úparent_noder	  r•   Ú	loop_bodyÚentriesÚeÚindex_namesr  Ú
index_exprr¾   Úvar_symbolsr  s                 rj   r  Ú$MixOrderReduction.is_contiguous_load‚  s  € å=à×)Ñ)Ö+ˆDÜ˜d¤M×2Ñ2Ð2Ð2ØŸ
™
ˆIØ×,Ñ,¨_×-AÑ-AÑBˆGÙ18ÓQ²¨A¿M¹MÈSÑ<P›<˜1Ÿ<œ<±ˆKÐQä�;Ó 1Ó$Ùó *�
Ø&×5Ñ5°jÑA�
Ø&×1Ñ1�
ô # :§?¡?Ó#4Ó5�ÜŸg™g×.Ñ.×:Ñ:ØØØó�ð $ B™¨1Õ,°¸B±À1Õ0DÚ ó *ñ ,ð2 ùò+ Rs   ÁDÁ1Drw   N©r•   r\   r‹   rx   )r•   r\   r‹   ztuple[sympy.Expr, sympy.Expr]©r…   r\   r†   r\   r‹   rx   )rÄ   Ústrr•   r\   r‹   rx   )r…   r\   r†   r\   r‹   ú	list[str])r•   r\   r‹   Úint©r…   r\   r†   r\   r‹   r!  )rÄ   r  r  r\   r‹   rx   )r{   r|   r}   r~   Ú__doc__ÚstaticmethodrŸ   r€   r®   r·   rÇ   rÎ   rÓ   rÙ   rÜ   rþ   r  rñ   r  r�   rw   rm   rj   rŽ   rŽ   ‰   sv  † ñð
 ó
ó ð
ð ó#!ó ð#!ðJ ð	0Ø%ð	0Ø.?ð	0à	ó	0ó ð	0ð óó ððB ð	Ø%ð	Ø.?ð	à	ó	ó ð	ð ð:Ø%ð:Ø.?ð:à	ó:ó ð:ð
 óMó ðMð ð$Ø%ð$Ø.?ð$à	ó$ó ð$ð óeó ðeðN ð*Ø%ð*Ø.?ð*à	ó*ó ð*ð
 óó ðð óó órm   rŽ   c                  óì   • \ rS rSr% S\S'   S\S'   S\S'   \R                  " \S9rS	\S
'   \R                  " \	S9r
S\S'   SS jrSS jrSS jrSS jrSS jrSS jrSS jrSS jrSS jrSS jrSrg) ÚSchedulerBufferi¢  Ú	SchedulerÚ	schedulerz	ir.Bufferr•   úOptional[BaseSchedulerNode]Údefining_op)Údefault_factoryúlist[NodeUser]Úusersr?   Ú
mpi_bufferc                óD   • U R                   nUc   eUR                  5       $ ry   )r*  Úget_name)ri   Úops     rj   Údefining_op_nameÚ SchedulerBuffer.defining_op_name¬  s#   € Ø×ÑˆØ‰~Ðˆ~Ø�{‰{‹}Ðrm   c                ó@   • [        U R                  R                  5      $ ry   )Úhashr•   r¼   rh   s    rj   Ú__hash__ÚSchedulerBuffer.__hash__±  s   € Ü�D—I‘I—N‘NÓ#Ð#rm   c                ó˜  • [        5       nU R                  5       nUR                  U S[        U R                  5      R
                   35        UR                  U SU R                  R                   35        U R                  5       (       a-  UR                  U S[        U R                  5       5       35        U R                  5       (       a-  UR                  U S[        U R                  5       5       35        [        U R                  5      S::  a0  UR                  U SU R                   35        UR                  5       $ UR                  U S35        UR                  S5         U R                   H  nUR                  U S35        M     S S S 5        UR                  S	5        UR                  5       $ ! , (       d  f       N/= f)
Nú: z
.layout = z.aliases = z.mutations = r   z	.users = z
.users = [Ú,Ú])rO   r0  Ú	writelinerÀ   r•   r{   ÚlayoutÚget_aliasesÚpformatÚget_mutationsr²   r-  ÚindentÚgetrawvalue)ri   Úresultr¼   Úusers       rj   Ú	debug_strÚSchedulerBuffer.debug_str´  s  € ÜÓ!ˆØ�}‰}‹ˆØ×Ñ˜D˜6 ¤D¨¯©£O×$<Ñ$<Ð#=Ð>Ô?Ø×Ñ˜D˜6 ¨D¯I©I×,<Ñ,<Ð+=Ð>Ô?Ø×Ñ×ÑØ×Ñ ˜v [´¸×9IÑ9IÓ9KÓ1LÐ0MÐNÔOØ×Ñ×ÑØ×Ñ ˜v ]´7¸4×;MÑ;MÓ;OÓ3PÐ2QÐRÔSäˆt�z‰z‹?˜aÓØ×Ñ ˜v Y¨t¯z©z¨lÐ;Ô<ð ×!Ñ!Ó#Ð#ð ×Ñ ˜v ZÐ0Ô1Ø—‘˜qÕ!Ø ŸJœJ�DØ×$Ñ$¨ v¨Q ZÖ0ñ '÷ "ð ×Ñ˜SÔ!Ø×!Ñ!Ó#Ð#÷	 "Õ!ús   Å*(F;Æ;
G	c                ó6   • U R                   R                  5       $ ry   ©r•   r0  rh   s    rj   r0  ÚSchedulerBuffer.get_nameÈ  ó   € Ø�y‰y×!Ñ!Ó#Ð#rm   c                ó0  • U R                   c   eU R                   R                  5       (       d  g U R                   R                  5       (       dV  U R                   R                  5       (       d7  [	        U R                   R                  5       [        R                  5      (       a4  [        R                  R                  R                  U R                   5        g [        [        R                  S5      (       aì  U R                  5       [        R                  R                  ;   aÀ  [        R                  R                  U R                  5          nXR                   R"                  ;   a$  U R                   R"                  U   R                   nO#U R                   R$                  U   R                   n[        R                  R                  R'                  UU R                   5        g [        R                  R                  R                  U R                   5        g )NÚargs)r•   Úshould_allocateÚget_inputs_that_alias_outputÚget_mutation_namesr’   Úget_output_specr)   ÚCommBufferLayoutrW   r¤   Úwrapper_codeÚcodegen_allocationÚhasattrÚkernelr0  Úinplace_update_buffersr(  Úname_to_donated_bufferÚname_to_bufÚcodegen_inplace_reuse)ri   Úinput_buffer_nameÚinput_buffers      rj   ÚallocateÚSchedulerBuffer.allocateË  sc  € Ø�y‰yÑ$Ð$Ð$Ø�y‰y×(Ñ(×*Ñ*Øð �I‰I×2Ñ2×4Ñ4Ø�y‰y×+Ñ+×-Ñ-Ü˜$Ÿ)™)×3Ñ3Ó5´r×7JÑ7J×KÑKä�G‰G× Ñ ×3Ñ3°D·I±IÔ>Øô ”A—H‘H˜f×%Ñ%Ø—‘“¤1§8¡8×#BÑ#BÓBô !"§¡× ?Ñ ?ÀÇÁÃÑ PÐØ §N¡N×$IÑ$IÓIØ#Ÿ~™~×DÑDØ%ñ ç‘$ñ ð  $Ÿ~™~×9Ñ9Ð:KÑL×QÑQ�Ü�G‰G× Ñ ×6Ñ6ØØ—	‘	õô
 �G‰G× Ñ ×3Ñ3°D·I±IÕ>rm   c                ó&  • U R                   c   e[        U R                   R                  [        R                  5      (       d  [        U R                   5      (       a  gU R                   H$  n[        UR                   [        5      (       d  M$    g   g©NFT)r•   r’   r=  r)   r=   rS   r-  Ú
OutputNode)ri   Úuses     rj   Úcan_freeÚSchedulerBuffer.can_freeì  sm   € à�y‰yÑ$Ð$Ð$Ü�d—i‘i×&Ñ&¬¯©×6Ñ6Ô:SØ�I‰I÷;
ñ ;
ð Ø—:”:ˆCÜ˜#Ÿ(™(¤J×/Ó/Ùñ ð rm   c                ó4  • 0 nU Hr  n[        UR                  5      U;   a?  UR                  U[        UR                  5         5      U[        UR                  5      '   M[  X2[        UR                  5      '   Mt     [        UR	                  5       5      U l        g ry   )Úidr•   Úmerger  rÃ   r-  )ri   r-  rC  ra  s       rj   Ú	set_usersÚSchedulerBuffer.set_usersø  sm   € à&(ˆÛˆCÜ�#—(‘(‹|˜vÓ%Ø'*§y¡y°¼¸3¿8¹8»Ñ1EÓ'F�”r˜#Ÿ(™(“|Ó$à'*”r˜#Ÿ(™(“|Ó$ñ	 ô
 ˜&Ÿ-™-›/Ó*ˆ�
rm   c                óT   • U R                   c   eU R                   R                  5       $ ry   )r•   rN  rh   s    rj   r>  ÚSchedulerBuffer.get_aliases  s%   € Ø�y‰yÑ$Ð$Ð$Ø�y‰y×5Ñ5Ó7Ð7rm   c                óT   • U R                   c   eU R                   R                  5       $ ry   )r•   rO  rh   s    rj   r@  ÚSchedulerBuffer.get_mutations  ó%   € Ø�y‰yÑ$Ð$Ð$Ø�y‰y×+Ñ+Ó-Ð-rm   c                óR   • U R                   R                  5       R                  5       $ ry   )r•   rP  rî   rh   s    rj   rî   ÚSchedulerBuffer.get_device
  s   € Ø�y‰y×(Ñ(Ó*×5Ñ5Ó7Ð7rm   )r-  N©r‹   r  ©r‹   r!  ©r‹   ÚNone©r‹   rx   )r-  r,  r‹   rs  ©r‹   zSequence[str]©r‹   úOptional[torch.device])r{   r|   r}   r~   r   ÚdataclassesÚfieldr  r-  r?   r.  r2  r6  rE  r0  r\  rb  rg  r>  r@  rî   r�   rw   rm   rj   r&  r&  ¢  sv   ‡ àÓØ
ƒOØ,Ó,Ø'×-Ò-¸dÑC€Eˆ>ÓCØ.9×.?Ò.?Ø3ñ/€JÐ+ó ôô
$ô$ô($ô?ôB
ô+ô8ô.÷8rm   r&  c                  ó$   • \ rS rSr% SrS\S'   Srg)ÚSchedulerDonatedBufferi  Nr)  r*  rw   )r{   r|   r}   r~   r*  r   r�   rw   rm   rj   r{  r{    s   ‡ à/3€KÐ,Ö3rm   r{  c                  ót  • \ rS rSr% S\S'   S\S'   S\S'   S\S'   S\S	'   S
\S'   S\S'   SrS\S'   S\S'   S\S'   SrS\S'   S\S'   S\S'   SrS\S'   STS jrSUS jr	SVS  jr
SVS! jrSVS" jrSWS# jrSVS$ jrSXS% jr      SYS& jrSZS' jrS[S( jrS\S) jrS]S* jr      S^S+ jrSXS, jrS_S- jrS_S. jrSXS/ jrSXS0 jr    S`S1 jrSVS2 jrSVS3 jr\S_S4 j5       r\S_S5 j5       r \S\S6 j5       r!\S\S7 j5       r"SaS8 jr#SbS9 jr$ScS: jr%SdS; jr&S\S< jr'S\S= jr(S\S> jr)S\S? jr*S\S@ jr+S\SA jr,S\SB jr-S\SC jr.SeSD jr/S\SE jr0SXSF jr1 Sf     SgSG jjr2\ShSH j5       r3\ShSI j5       r4\ShSJ j5       r5      SiSK jr6      SjSL jr7\SkSM j5       r8SlSN jr9\SlSO j5       r:SmSP jr;SnSQ jr<\=    SoSR j5       r>SSr?g)pr\   i  úOrderedSet[str]rï   z7tuple[torch.device, tuple[tuple[sympy.Expr, ...], ...]]r©   Ú
last_usager!  Ú	min_orderÚ	max_orderr@   Úmpi_nodeúdict[str, str]Úmutation_renamesNzOptional[ir.Operation]r•   úlist[SchedulerBuffer]Úoutputsúdict[str, SchedulerBuffer]Úoutputs_by_nameúOptional[float]Úoverride_estimated_runtimeúdependencies.ReadWritesrº   úOrderedSet[Dep]Úunmet_dependenciesFrx   Úwrittenc                ó    • Xl         S U l        g )Nc                 ó   • / $ ry   rw   )rL  Úkwargss     rj   Ú<lambda>Ú,BaseSchedulerNode.__init__.<locals>.<lambda>+  s   € ¡Brm   )r(  Údebug_device_str)ri   r(  s     rj   Ú__init__ÚBaseSchedulerNode.__init__(  s   € Ø$-Œá&ð 	Õrm   c           	     ó^  • Xl         [        5       U l        [        [           " 5       U l        SU l        UR                  5        Vs/ s H  n[        U R                  UU S9PM     snU l	        U R                   Vs0 s H  o3R                  5       U_M     snU l        0 U l        g s  snf s  snf )NF)r(  r•   r*  )r•   r   rï   r  r~  r�  Úget_outputsr&  r(  r…  r0  r‡  rƒ  )ri   r•   ÚoutputrÄ   s       rj   Ú_init_from_nodeÚ!BaseSchedulerNode._init_from_node.  sª   € ØŒ	Ü#›ˆŒÜ$Üò
ó ˆŒð ˆŒð ×*Ñ*Ô,ó
ò -�ô ØŸ.™.ØØ ôñ
 -ñ
ˆŒð @D¿|º|ÓLº|¸§¡£°Ò 3¹|ÑLˆÔð !#ˆÕùò
ùò  Ms   ÁB%Á;B*c                óV   • [        U 5      R                   SU R                  5       < S3$ )Nz(name=Ú)©rÀ   r{   r0  rh   s    rj   Ú__repr__ÚBaseSchedulerNode.__repr__F  s'   € Ü�t“*×%Ñ%Ð& f¨T¯]©]«_Ñ,?¸qÐAÐArm   c                óP  • U R                  5       n[        5       nUR                  U S[        U 5      R                   S[        [        U SS5      5      R                   SU S[        U R                  R                  5       SU S[        U R                  5       SU S	[        U R                  R                  U R                  -
  5       SU S
35        UR                  5          U R                  5        H"  nUR                  UR                  5       5        M$     SSS5        UR                  S5         UR                  U R                  5       5        UR'                  5       R)                  5       $ ! , (       d  f       N]= f! [          a    ["        R%                  SSS9   NOf = f)ú#Longer form printout for trace logsr9  Ú(r•   Nú)
ú
.writes = Ú
ú.unmet_dependencies = ú.met_dependencies = z.outputs = [
        r;  úIgnoring error in debug_str()T©Úexc_info)r0  rO   ÚsplicerÀ   r{   Úgetattrr?  rº   ÚwritesrŒ  r»   rA  r—  rE  r<  Údebug_str_extraÚ	ExceptionÚlogÚwarningrB  Úrstrip)ri   r¼   rÄ   rÌ   s       rj   rE  ÚBaseSchedulerNode.debug_strI  sv  € à�}‰}‹ˆÜÓˆØ�
‰
à€€bŒˆd‹×	Ñ	Ð˜Qœt¤G¨D°&¸$Ó$?Ó@×IÑIÐJð KØ€€j”˜×)Ñ)×0Ñ0Ó1Ð2ð 3Ø€ÐœW T×%<Ñ%<Ó=Ð>ð ?Ø€Ðœ7 4×#3Ñ#3×#9Ñ#9¸D×<SÑ<SÑ#SÓTÐUð VØ€ð 	ðô	
ð �Z‰Z�\Ø×'Ñ'Ö)�Ø—
‘
˜3Ÿ=™=›?Ö+ñ *÷ ð 	�‰�cÔð	HØ�J‰J�t×+Ñ+Ó-Ô.ð �‰Ó ×'Ñ'Ó)Ð)÷ �\ûô ó 	HÜ�K‰KÐ7À$ˆKÓGð	Hús   Ã%7E3Ä6F Å3
FÆF%Æ$F%c                ó   • g)NÚ rw   rh   s    rj   r®  Ú!BaseSchedulerNode.debug_str_extrab  ó   € Ørm   c                ó$   • U R                  U 5      $ ry   )r“  rh   s    rj   Ú_debug_str_for_deviceÚ'BaseSchedulerNode._debug_str_for_devicee  s   € Ø×$Ñ$ TÓ*Ð*rm   c                ó¸  • [        U R                  SS 5      nSn[        U[        R                  R
                  R                  5      (       a$  SUR                  UR                  5       /SSS9-   nOe[        U[        R                  R
                  R                  5      (       a2  SUR                  UR                  5       UR                  5       /SSS9-   nU  U 3$ )Nrã   rµ  ú, F)ÚshortenÚ	multiline)r¬  r•   r’   ÚtorchÚ	_inductorr)   Ú	PointwiseÚ
str_helperÚget_sizeÚ	ReductionÚget_reduction_sizerë   )ri   Ú
maybe_dataÚdata_strs      rj   Údebug_str_shortÚ!BaseSchedulerNode.debug_str_shorth  sÑ   € Ü˜TŸY™Y¨°Ó5ˆ
ØˆÜ�j¤%§/¡/×"4Ñ"4×">Ñ">×?Ñ?Ø˜j×3Ñ3Ø×$Ñ$Ó&Ð'°À%ð 4ð ñ ‰Hô ˜
¤E§O¡O×$6Ñ$6×$@Ñ$@×AÑAØ˜j×3Ñ3Ø×.Ñ.Ó0°*×2OÑ2OÓ2QÐRØØð 4ð ñ ˆHð
 �˜�zÐ"Ð"rm   c                óp   • [         R                  SU U R                  U R                  R                  5        g )Nz(%s: unmet_dependencies = %s, writes = %s)r°  ÚinforŒ  rº   r­  rh   s    rj   Úlog_detailsÚBaseSchedulerNode.log_detailsw  s,   € Ü�‰Ø6ØØ×#Ñ#Ø×Ñ×#Ñ#õ		
rm   c                ó   • g©NFrw   )ri   Úself_depÚ	other_deps      rj   Úreorder_loops_by_dep_pairÚ+BaseSchedulerNode.reorder_loops_by_dep_pair  ó   € ð rm   c                óø   • S U R                   R                  5        5        Vs0 s H  nX!;   d  M
  X!U   _M     snU l        U R                  U R                   R	                  U R                  5      5        g s  snf )Nc              3  ó8   #   • U  H  oR                   v •  M     g 7fry   ©r¼   ©r˜   rÆ   s     rj   rš   Ú9BaseSchedulerNode.update_mutated_names.<locals>.<genexpr>‡  s   é € ÐQÒ-P cŸžÒ-Pùó   ‚)rº   Úreads_and_writesrƒ  Úset_read_writesÚrename)ri   Úrenamesr¼   s      rj   Úupdate_mutated_namesÚ&BaseSchedulerNode.update_mutated_names„  ss   € ñ R¨T×-=Ñ-=×-NÑ-NÔ-PÔQó!
âQ�Ø‰ó  ˆD˜$‘-ÒÙQñ!
ˆÔð
 	×Ñ˜T×-Ñ-×4Ñ4°T×5JÑ5JÓKÕLùò!
s
   ¤	A7±	A7c                óX   • U R                  U R                  R                  U5      5        g ry   )rÜ  rº   Ú	with_read©ri   rÆ   s     rj   Úadd_fake_depÚBaseSchedulerNode.add_fake_depŒ  s!   € Ø×Ñ˜T×-Ñ-×7Ñ7¸Ó<Õ=rm   c                óB   • [        S U R                  5        5       5      $ )Nc              3  ón   #   • U  H+  oR                  5       =(       d    UR                  5       v •  M-     g 7fry   )r>  r@  )r˜   rÄ   s     rj   rš   Ú=BaseSchedulerNode.has_aliasing_or_mutation.<locals>.<genexpr>�  s*   é € ð 
Ú@R¸�O‰OÓ×4 ×!2Ñ!2Ó!4Ô4Ò@Rùs   ‚35)rö   r—  rh   s    rj   Úhas_aliasing_or_mutationÚ*BaseSchedulerNode.has_aliasing_or_mutation�  s%   € Üñ 
Ø@D×@PÑ@PÔ@Ró
ó 
ð 	
rm   c                óf   • Xl         U R                   R                  U l        U R                  5         g ry   )rº   r»   rŒ  Ú
prune_deps)ri   Úrws     rj   rÜ  Ú!BaseSchedulerNode.set_read_writes”  s&   € ØÔØ"&×"2Ñ"2×"8Ñ"8ˆÔØ�‰Õrm   c                ób   ^• U R                  5       n[        U4S jU 5       5      nX1-
  U l        g )Nc              3  óF   >#   • U  H  nTR                  X5      v •  M     g 7fry   )Úget)r˜   ÚkÚmutation_real_names     €rj   rš   Ú3BaseSchedulerNode.set_last_usage.<locals>.<genexpr>�  s    øé € Ð!UÊÀ1Ð"4×"8Ñ"8¸×">Ð">Êùó   ƒ!)Úused_or_aliased_buffer_namesr   r~  )ri   Úfuture_used_buffersró  Úused_bufferss     ` rj   Úset_last_usageÚ BaseSchedulerNode.set_last_usage™  s-   ø€ ð ×8Ñ8Ó:ˆÜ!Ô!UÉÓ!UÓUˆØ&Ñ<ˆ�rm   c                óJ   • U R                    H  nUR                  5         M     g ry   )r…  r\  )ri   rÄ   s     rj   Úmark_runÚBaseSchedulerNode.mark_run   s   € Ø—<”<ˆCØ�L‰LŽNò  rm   c                ó    • [        S [        R                  " U R                  R                  U R                  R
                  5       5       5      $ )Nc              3  ó:   #   • U  H  nUR                   v •  M     g 7fry   r×  rØ  s     rj   rš   Ú6BaseSchedulerNode.used_buffer_names.<locals>.<genexpr>¥  s   é € ð 
âW�ð �HŽHÚWùó   ‚)r   Ú	itertoolsÚchainrº   r»   r­  rh   s    rj   rÊ   Ú#BaseSchedulerNode.used_buffer_names¤  s?   € Üñ 
ä —’ t×'7Ñ'7×'=Ñ'=¸t×?OÑ?O×?VÑ?VÔWó
ó 
ð 	
rm   c                óŽ  ^• [        5       m[        R                  " U R                  R                  U R                  R
                  5       Vs/ s H7  n[        U[        5      (       a  UR                  (       a  M+  UR                  PM9     nn[        U5      S:”  a¤  UR                  5       nTR                  U5        [        R                  R                  R!                  U5      (       aD  UR#                  U4S j[        R                  R                  U   R%                  5        5       5        [        U5      S:”  a  M¤  T$ s  snf )z«
Returns buffer names used by this node, including aliases.

Note: is_fake WeakDeps are excluded since they are purely for ordering
and should not affect buffer lifetime.
r   c              3  ó8   >#   • U  H  nUT;  d  M  Uv •  M     g 7fry   rw   )r˜   ÚaliasÚ
used_namess     €rj   rš   ÚABaseSchedulerNode.used_or_aliased_buffer_names.<locals>.<genexpr>¼  s(   øé € ð ò"5˜ð  JÑ.÷	 ‘Eò"5ùs   ƒ
‘	)r   r  r  rº   r»   r­  r’   r4   Úis_faker¼   r²   ÚpopÚaddrW   r¤   Úname_to_bufferrñ  ÚextendrN  )ri   rÆ   Údepsr  s      @rj   rö  Ú.BaseSchedulerNode.used_or_aliased_buffer_namesª  sü   ø€ ô '1£lˆ
ô !—’ t×'7Ñ'7×'=Ñ'=¸t×?OÑ?O×?VÑ?VÔWó
âW�Ü˜s¤G×,Ñ,°·µó ˆC�HŒHÙWð 	ð 
ô
 �$‹i˜!‹mØ—(‘(“*ˆCØ�N‰N˜3ÔÜ�w‰w×%Ñ%×)Ñ)¨#×.Ñ.Ø—‘ô ä!"§¡×!7Ñ!7Øñ"ç2Ñ2Ó4ð"5óô ô	 �$‹i˜!�mð Ðùò!
s   Á*EÁ;Ec                óN   ^ • [        U 4S jT R                   5       5      T l        g )Nc              3  ót   >#   • U  H-  nUR                   TR                  R                  ;  d  M)  Uv •  M/     g 7fry   )r¼   r(  Úavailable_buffer_names©r˜   rÆ   ri   s     €rj   rš   Ú/BaseSchedulerNode.prune_deps.<locals>.<genexpr>Æ  s0   øé € ð -
â.�Ø�x‰x˜tŸ~™~×DÑDÑD÷ ‰CÚ.ùs   ƒ(8¯	8©r   rŒ  rh   s   `rj   rì  ÚBaseSchedulerNode.prune_depsÅ  s#   ø€ Ü",ô -
à×.Ò.ó-
ó #
ˆÕrm   c                ó¾   ^ ^• SU 4S jjm[        U4S jT R                  R                   5       5      nT R                  T R                  R	                  U5      5        g )Nc                ó  >• [        U [        5      (       d  gU R                  TR                  R                  ;  a  gTR                  R                  U R                     R                  5       nU[        R                  R                  ;   $ rÏ  )	r’   r4   r¼   r(  rX  r2  rW   r¤   Úremoved_operations)rÆ   Úop_nameri   s     €rj   Úshould_pruneÚ7BaseSchedulerNode.prune_weak_deps.<locals>.should_pruneÎ  sb   ø€ Ü˜c¤7×+Ñ+ØØ�x‰x˜tŸ~™~×9Ñ9Ó9Øà—n‘n×0Ñ0°·±Ñ:×KÑKÓMˆGØœaŸg™g×8Ñ8Ñ8Ð8rm   c              3  óF   >#   • U  H  nT" U5      (       d  M  Uv •  M     g 7fry   rw   ©r˜   rÆ   r  s     €rj   rš   Ú4BaseSchedulerNode.prune_weak_deps.<locals>.<genexpr>×  s   øé € ð 
Ú1�C±\À#×5F�C‰CÒ1ùó   ƒ!˜	!©rÆ   r1   r‹   rx   )r   rº   r»   rÜ  Úremove_reads)ri   Ú	to_remover  s   ` @rj   Úprune_weak_depsÚ!BaseSchedulerNode.prune_weak_depsÌ  sN   ù€ ÷	9ô ô 
Ø×+Ñ+×1Ò1ó
ó 
ˆ	ð 	×Ñ˜T×-Ñ-×:Ñ:¸9ÓEÕFrm   c                óD   • [        XU R                  R                  5        g ry   )Ú_prune_redundant_depsr(  rX  )ri   Úname_to_fused_nodes     rj   Úprune_redundant_depsÚ&BaseSchedulerNode.prune_redundant_depsÜ  s   € ô 	˜d¸¿¹×8RÑ8RÕSrm   c                óT   • U R                   c   eU R                   R                  5       $ ry   )r•   Úget_operation_namerh   s    rj   r0  ÚBaseSchedulerNode.get_nameá  rm  rm   c                ó"   • U R                  5       $ ry   ©r0  rh   s    rj   Úget_first_nameÚ BaseSchedulerNode.get_first_nameå  s   € Ø�}‰}‹Ðrm   c                óB   • [        S U R                  5        5       5      $ )Nc              3  ó@   #   • U  H  oR                  5       v •  M     g 7fry   r0  ©r˜   r•   s     rj   rš   Ú8BaseSchedulerNode.get_operation_names.<locals>.<genexpr>ê  s   é € ÐGÒ6F¨dŸ-™-Ÿ/˜/Ò6Fùó   ‚)r   r�   rh   s    rj   rð   Ú%BaseSchedulerNode.get_operation_namesè  s   € äÑG°d·n±nÔ6FÓGÓGÐGrm   c                ó:   • [        S U R                   5       5      $ )Nc              3  ó@   #   • U  H  oR                  5       v •  M     g 7fry   r0  ©r˜   rÌ   s     rj   rš   Ú5BaseSchedulerNode.get_buffer_names.<locals>.<genexpr>î  s   é € ÐA²L¨SŸ,™,Ÿ.˜.²Lùr7  )r   r…  rh   s    rj   Úget_buffer_namesÚ"BaseSchedulerNode.get_buffer_namesì  s   € äÑA°D·L²LÓAÓAÐArm   c                óB   • [        S U R                  5        5       5      $ )Nc              3  ód   #   • U  H&  n[        U[        5      =(       a
    [        US S9v •  M(     g7f)T)Údisallow_fp32_opsN©r’   r“   r+   ©r˜   Úns     rj   rš   ÚABaseSchedulerNode.can_codegen_in_low_precision.<locals>.<genexpr>ò  s6   é € ð 
ò &�ô �qœ-Ó(÷ GÜ+¨AÀÑFôGâ%ùs   ‚.0©rœ   r�   rh   s    rj   Úcan_codegen_in_low_precisionÚ.BaseSchedulerNode.can_codegen_in_low_precisionð  s%   € äñ 
ð —^‘^Ô%ó
ó 
ð 	
rm   c                óB   • [        S U R                  5        5       5      $ )Nc              3  óf   #   • U  H'  n[        U[        5      =(       a    [        U5      v •  M)     g 7fry   rB  rC  s     rj   rš   Ú@BaseSchedulerNode.can_codegen_without_upcasts.<locals>.<genexpr>ú  s,   é € ð 
â%�ô �qœ-Ó(×KÔ-HÈÓ-KÔKÚ%ùs   ‚/1rF  rh   s    rj   r+   Ú-BaseSchedulerNode.can_codegen_without_upcastsø  s#   € äñ 
à—^‘^Ô%ó
ó 
ð 	
rm   c                ó   • U /$ ry   rw   rh   s    rj   r�   ÚBaseSchedulerNode.get_nodesÿ  s	   € Øˆvˆrm   c                ó   • U R                   $ ry   )r…  rh   s    rj   r—  ÚBaseSchedulerNode.get_outputs  s   € Ø�|‰|Ðrm   c                ó    • U R                   U   $ ry   )r‡  )ri   Úbuf_names     rj   Ú
get_outputÚBaseSchedulerNode.get_output  s   € Ø×#Ñ# HÑ-Ð-rm   c                óT   • U R                   c   eU R                   R                  5       $ ry   )r•   rî   rh   s    rj   rî   ÚBaseSchedulerNode.get_device  s%   € Ø�y‰yÑ$Ð$Ð$Ø�y‰y×#Ñ#Ó%Ð%rm   c                óV   • U R                  5       nUS L=(       a    UR                  S:H  $ ©NÚcpu)rî   rÀ   ©ri   Údevices     rj   Úis_cpuÚBaseSchedulerNode.is_cpu  s'   € Ø—‘Ó"ˆØ˜TÐ!×: f§k¡k°UÑ&:Ð:rm   c                ób   • U R                  5       nUS L=(       a    [        UR                  5      $ ry   )rî   rR   rÀ   rZ  s     rj   rR   ÚBaseSchedulerNode.is_gpu  s'   € Ø—‘Ó"ˆØ˜TÐ!×9¤f¨V¯[©[Ó&9Ð9rm   c                ó   • grÏ  rw   rh   s    rj   r”   ÚBaseSchedulerNode.is_reduction  ó   € Ørm   c                ó   • grÏ  rw   rh   s    rj   Úis_native_matmulÚ"BaseSchedulerNode.is_native_matmul  rb  rm   c                ó   • grÏ  rw   rh   s    rj   Úis_split_scanÚBaseSchedulerNode.is_split_scan  rb  rm   c                ó   • grÏ  rw   rh   s    rj   Úis_templateÚBaseSchedulerNode.is_template  rb  rm   c                ó   • grÏ  rw   rh   s    rj   Ú	is_externÚBaseSchedulerNode.is_extern   rb  rm   c                ó   • grÏ  rw   rh   s    rj   Ú
is_foreachÚBaseSchedulerNode.is_foreach#  rb  rm   c                ó   • grÏ  rw   ©ri   Úread_deps     rj   Úcan_inplaceÚBaseSchedulerNode.can_inplace&  rb  rm   c                ó   • grÏ  rw   rh   s    rj   Úhas_side_effectsÚ"BaseSchedulerNode.has_side_effects)  rb  rm   c                óX  ^ • SSK Jn  [        T [        5      (       aÜ  [        R
                  (       aÇ  [        R                  R                  T R                  5       [        R                  5      (       a†  [        [        R                  [        R                  R                  R                   R"                  5      (       a  [%        [        R                  SS5      b  ['        [        R                  S5      (       d  gT R(                  [        R                  R*                  -  T R,                  R.                  -  nSU 4S jjnT R1                  5        GHQ  nUR2                  nUc   eUR5                  5       (       aV  UR7                  5       (       dA  UR9                  5       (       d,  UR;                  5       [        R                  R<                  ;   a  M‚  T R>                  R@                   GH´  nURB                  T R,                  RD                  ;   a$  T R,                  RD                  URB                     nO/T R,                  RF                  RI                  URB                  5      nU(       d  M„  [        R                  RJ                  RM                  UT 5      (       d  Mµ  [        URN                  [P        5      (       a  MÖ  URR                  c   eURR                   Vs/ s H%  nUR2                  R;                  5       U;  d  M#  UPM'     n	n[U        U	5      S:X  d  GM3  U	S   RV                  (       d  GMJ  U	S   R2                  T L d  GM_  UR2                  c  GMo  [        UR2                  RY                  5       [Z        R\                  [Z        R^                  [Z        R`                  45      (       a  GMÈ  URN                  (       am  [        URN                  R2                  [Z        Rb                  [Z        Rd                  45      (       a*  [U        UR2                  R7                  5       5      S:”  a  GMF  U" UR2                  UR2                  5      (       d  GMk  U" U5      (       d  GM{  [        R                  Rf                  Ri                  UR;                  5       UR;                  5       5        [        [        R                  [        R                  R                  R                   R"                  5      (       an  [        R                  Rj                  Rm                  UR;                  5       5        [        R                  Rj                  Rm                  UR;                  5       5        UR;                  5       [        R                  Rn                  UR;                  5       '     GMO     GMT     gs  snf )	zf
Decide if there should be inplace updates for the node
and record the decision in the active kernel.
r   )Úcan_match_buffer_sizeÚ	mutationsNrL  c                óÞ  >^• U R                   R                  T5      nU R                  5       m[        5       nU R                   H¦  nUR
                  n[        U[        5      (       d  M&  UR                  5       U R                   R                  ;  d  U R                   R                  U5      ULa  Mn  UU4S jUR                  R                  5        5       -  n[        U5      S:”  d  M¦    g   g)Nc              3  óL   >#   • U  H  nUR                   T:X  d  M  Uv •  M     g 7fry   r×  )r˜   ÚorR  s     €rj   rš   Ú^BaseSchedulerNode.decide_inplace_update.<locals>.single_index_in_fused_node.<locals>.<genexpr>_  s&   øé € ð âE˜Ø—v‘v Ñ)÷ ‘AÚEùs   ƒ$›	$r   FT)r(  Úget_fused_noder0  r   r-  r•   r’   r\   r1  r)  rº   rÛ  r²   )Úbuf_to_be_inplacedÚ
fused_noder  rD  Ú	user_noderR  ri   s        @€rj   Úsingle_index_in_fused_nodeÚKBaseSchedulerNode.decide_inplace_update.<locals>.single_index_in_fused_nodeG  sÛ   ù€ ð
 ,×5Ñ5×DÑDÀTÓJˆJØ)×2Ñ2Ó4ˆHô %/£LˆDØ*×0Ô0�Ø ŸI™I�	Ü! )Ô->×?Ñ?Ùð ×,Ñ,Ó.Ø-×7Ñ7×JÑJóKà)×3Ñ3×BÑBÀ9ÓMØ%ò&ñ àô à&×2Ñ2×CÑCÔEóñ �ô
 �t“9˜q•=Ù ñ' 1ð* rm   r   )r‚  r&  r‹   rx   )8Úcodegen.wrapperr{  r’   r“   r&   Úinplace_buffersrW   r¤   Úhas_featurerî   r,   ÚINPLACE_BUFFERSrU  r¿  rÀ  ÚcodegenÚsimdÚ
SIMDKernelr¬  rT  rï   r  r(  Úcompleted_operationsr—  r•   rM  rN  rO  r0  Úremoved_buffersrº   r»   r¼   rW  rX  rñ  rR  Ú	can_reuser*  ÚNopKernelSchedulerNoder-  r²   ru  rP  r)   r=   r<   ÚMutationLayoutSHOULDREMOVEÚFallbackKernelr;   rL  Úmake_inplacer|  r  rV  )
ri   r{  Úinconsequential_nodesr…  rÄ   Úbuf_nodeÚreadÚ	input_bufÚxÚremaining_usess
   `         rj   Údecide_inplace_updateÚ'BaseSchedulerNode.decide_inplace_update,  sÙ  ø€ õ
 	;ô �tœ]×+Ñ+Ü×&×&Ü—‘×#Ñ# D§O¡OÓ$5´~×7UÑ7U×VÑVäœqŸx™x¬¯©×)@Ñ)@×)EÑ)E×)PÑ)P×QÑQÜœ1Ÿ8™8 [°$Ó7ÑCô œŸ™ &×)Ñ)àð �N‰NÜ�g‰g×(Ñ(ñ)à�n‰n×1Ñ1ñ2ð 	÷ 	ðD ×#Ñ#×%ˆCØ—x‘xˆHØÑ'Ð'Ð'à×,Ñ,×.Ñ.Ø×8Ñ8×:Ñ:Ø×.Ñ.×0Ñ0Ø—<‘<“>¤Q§W¡W×%<Ñ%<Ó<áà×(Ñ(×.Õ.�à—9‘9 §¡× EÑ EÓEØ $§¡× EÑ EÀdÇiÁiÑ P‘Ià $§¡× :Ñ :× >Ñ >¸t¿y¹yÓ I�I÷ �IÜŸ™×,Ñ,×6Ñ6°yÀ$×GÓGÜ& y×'<Ñ'<Ô>T×UÓUà$Ÿ?™?Ñ6Ð6Ð6ð "+§¢ó&â!0˜AØŸ6™6Ÿ?™?Ó,Ð4IÑI÷ Ù!0ð #ð &ô ˜NÓ+¨qÖ0Ø*¨1Ñ-×9×9Ò9Ø*¨1Ñ-×2Ñ2°dÕ:Ø%ŸN™NÔ6Ü *Ø%ŸN™N×:Ñ:Ó<ä "§¡Ü "× 4Ñ 4Ü "× =Ñ =ð÷!ô !ð &×1×1Ü *Ø )× 5Ñ 5× :Ñ :Ü!#×!2Ñ!2´B·N±NÐ C÷!ñ !ô !$ I§N¡N×$OÑ$OÓ$QÓ RÐUVÖ Vá1°)·.±.À#Ç(Á(×KÔKÙ6°y×AÔAô
 Ÿ™Ÿ™×2Ñ2°9×3EÑ3EÓ3GÈÏÉËÔXä%ÜŸH™H¤e§o¡o×&=Ñ&=×&BÑ&B×&MÑ&M÷ñ ô ŸH™H×.Ñ.×2Ñ2°9×3EÑ3EÓ3GÔHÜŸH™H×.Ñ.×2Ñ2°3·<±<³>ÔBð &×.Ñ.Ó0ô Ÿ™×7Ñ7¸¿¹»ÑGó ôq /ò &ùò0&s   Ë"V'ÌV'c                ó€  • [         R                  (       d  g U(       a  U R                  (       a  g U R                  c   eU R                  R	                  5       n/ nU GH5  nUR
                  S:X  a  M  UR                  S5        UR                  S5        SUR
                   SUR                   3nSUR                  ;   a  USUR                  S    3-   nUR                  U5        SUR                  ;   d  Mœ  UR                  S    nUR                  S	S
S9S   nUR                  SUR                  SS5      R                  SS5      R                  SS5      R                  SS5      -   5        UR                  S5        UR                  S5        GM8     [        U5      S:X  a  g UR                  U5        SU l        g )Nr˜  rµ  z#pragma CMT ORIGIN:z#pragma CMT Ú Úseq_nrz seq_nr:Ústack_traceÚ|r   )Úmaxsplitr
  Ú{z{{Ú}z}}r¥  Ú\z\\z#pragma CMT END ORIGINr   T)r&   Úcomment_originr�  r•   Úget_originsr1  rË   ÚtargetÚmetaÚrsplitÚreplacer²   Ú
writelines)	ri   ÚbufferÚ	only_onceÚoriginsÚ	out_linesr  Úop_info_strr   Ústack_trace_last_lines	            rj   Úcodegen_originating_infoÚ*BaseSchedulerNode.codegen_originating_info®  s”  € ô ×$×$Øæ˜ŸŸØØ�y‰yÑ$Ð$Ð$Ø—)‘)×'Ñ'Ó)ˆØˆ	äˆAØ�t‰t�xÓáà×Ñ˜RÔ à×ÑÐ2Ô3Ø(¨¯©¨¨a°·±¨zÐ:ˆKØ˜1Ÿ6™6Ó!Ø)¨h°q·v±v¸hÑ7GÐ6HÐ,IÑI�Ø×Ñ˜[Ô)Ø §¡Õ&Ø!"§¡¨Ñ!6Ð 7�Ø(3×(:Ñ(:¸3ÈÐ(:Ð(KÈBÑ(OÐ%Ø× Ñ Ø"Ø+×3Ñ3°C¸Ó>ß‘W˜S $Ó'ß‘W˜T 4Ó(ß‘WØ˜fóñ	ôð × Ñ Ð!9Ô:Ø× Ñ  ×$ñ3 ô6 ˆy‹>˜QÓØð 	×Ñ˜)Ô$Øˆ�rm   c                ó"   • U R                  SSS9$ )NT©Úinclude_readsÚinclude_writes©Ú!get_read_write_buffers_sizes_implrh   s    rj   Úget_read_write_buffers_sizesÚ.BaseSchedulerNode.get_read_write_buffers_sizesÝ  s   € à×5Ñ5Ø¨tð 6ð 
ð 	
rm   c                ó"   • U R                  SSS9$ )NTFr¶  r¹  rh   s    rj   Úget_read_buffer_sizesÚ'BaseSchedulerNode.get_read_buffer_sizesã  s   € à×5Ñ5Ø¨uð 6ð 
ð 	
rm   c                ó"   • U R                  SSS9$ )NFTr¶  r¹  rh   s    rj   Úget_write_buffer_sizesÚ(BaseSchedulerNode.get_write_buffer_sizesé  s   € à×5Ñ5Ø°ð 6ð 
ð 	
rm   c                óL   • [        U R                  XS9R                  5       SS9$ )Nr¶  r   )Ústart)ré   Úget_read_write_buffer_accessesrÃ   )ri   r·  r¸  s      rj   rº  Ú3BaseSchedulerNode.get_read_write_buffers_sizes_implï  s1   € ô Ø×/Ñ/Ø+ð 0ð ç‰f‹hØñ	
ð 	
rm   c                óŽ  ^ ^^^^^• [        T [        5      (       a  0 $ [        T [        5      (       a!  [        T R                  [        5      (       a  0 $ [        T [        5      (       af  [        T R                  [
        R                  5      (       a=  T R                  R                  [        R                  R                  R                  L a  0 $ SS jm[        T [        5      (       a@  T" [        T R                  5       S   5      [        T R                  5       S   5      -  5      mO[        S5      m[         R"                  " [$        5      nU(       a:  T R&                  R(                   H   nX4R*                     R-                  U5        M"     U(       a:  T R&                  R.                   H   nX4R*                     R-                  U5        M"     U(       a&  [1        S T R&                  R(                   5       5      O	[1        5       nU(       a&  [1        S T R&                  R.                   5       5      O	[1        5       nSU 4S jjm[        T [2        5      (       a  [1        UU 4S jU 5       5      nXg-
  nXW-
  n0 nXV-   HÂ  n	[5        U4S	 jX9    5       5      mU	[6        R8                  R:                  ;   a  [6        R8                  R:                  U	   n
O>U	[6        R8                  R<                  ;   a  [6        R8                  R<                  U	   n
OM”      SUUU U4S
 jjmT" U
5      nX˜;  a  X¸U	'   M¶  X‰==   U-  ss'   MÄ     U$ )aâ  
Counting the number of bytes accessed for a kernel is
surprisingly tricky. In particular, there is a differentiation
between 'theoretical' memory accesses and practical memory
accesses. For example, a layernorm kernel may actually access an
input 3 times, but in theory, it only needs to access its input
once (and may be optimized to do so through say, persistent
reductions)

Another example is that even though a buffer is passed in, we may
not access the entire buffer. This may occur if we are accessing
a slice of the buffer. Another tricky case is for indirect
indexing, where the amount of bytes accessed depends on the
values of the input.

What this function aims to compute is the memory accesses for
worst-case inputs, best-case optimization. What this means is
that for each buffer we compute the amount of potential accesses in two ways and take the minimum.

1. Numel in ranges multiplied by number of deps the buffer has
2. The buffer size

Returns memory accesses per buffer.
c                óR   • [         R                  R                  R                  U SS9$ )Nr   rÖ   )rW   r¤   r¥   rØ   )Úss    rj   Útry_size_hintÚGBaseSchedulerNode.get_read_write_buffer_accesses.<locals>.try_size_hint#  s"   € Ü—7‘7×#Ñ#×5Ñ5°aÀ!Ð5ÐDÐDrm   r   r   ç    eÍÍAc              3  ó8   #   • U  H  oR                   v •  M     g 7fry   r×  rØ  s     rj   rš   ÚCBaseSchedulerNode.get_read_write_buffer_accesses.<locals>.<genexpr>8  s   é € ÐBÒ+A C—x–xÒ+AùrÚ  c              3  ó8   #   • U  H  oR                   v •  M     g 7fry   r×  rØ  s     rj   rš   rÎ  =  ó   é € ÐCÒ+B C—x–xÒ+BùrÚ  c                ó¢   >• TR                   R                  U    R                  n[        S U 5       5      n[	        U[        U5      -
  5      S:„  $ )Nc              3  ó8   #   • U  H  oR                   v •  M     g 7fry   rž   )r˜   rD  s     rj   rš   Ú\BaseSchedulerNode.get_read_write_buffer_accesses.<locals>.is_materialized.<locals>.<genexpr>D  s   é € Ð!>º°§)¦)ºùrÚ  r   )r(  rX  r-  r   r²   )rÄ   rÁ   r-  Úbuf_usesri   s       €rj   Úis_materializedÚIBaseSchedulerNode.get_read_write_buffer_accesses.<locals>.is_materializedB  sG   ø€ Ø—N‘N×.Ñ.¨sÑ3×9Ñ9ˆEÜ!Ñ!>¹Ó!>Ó>ˆHÜ�x¤*¨VÓ"4Ñ4Ó5¸Ñ9Ð9rm   c              3  ó\   >#   • U  H!  nT" UTR                   5      (       a  M  Uv •  M#     g 7fry   ©rÁ   )r˜   rÆ   rÕ  ri   s     €€rj   rš   rÎ  H  s#   øé € ð )Ú%˜©_¸SÀ$Ç+Á+×-N—‘švùs   ƒ,£	,c              3  ó(   >#   • U  H  nTv •  M	     g 7fry   rw   )r˜   rÆ   Ú
node_numels     €rj   rš   rÎ  Q  s   øé € Ð$RÒ;Q°C¥ZÒ;Qùs   ƒc                ó”  >• U (       d  g[        U [        R                  5      (       a  U R                  5       $ [        U R                  [
        5      (       aá  TR                  R                  U R                  5          R                  nSnU H¦  n[        UR                  [        5      (       a  M$  [        UR                  [        5      (       d   e[        UR                  R                  [        5      (       a8  UR                  R                  5        H  nUT" UR                  5      -  nM     M¦    g   U$ [        U R                  [        R                  5      (       a#  [!        U4S jU R#                  5        5       5      $ T	" [%        U R'                  5       5      5      n[)        U R+                  5       5      [-        TU5      -  $ )Nr   c              3  ón   >#   • U  H*  nT" [         R                  R                  U5      5      v •  M,     g 7fry   )rW   r¤   Ú
get_buffer)r˜   Úmut_nameÚget_buf_bytess     €rj   rš   ÚZBaseSchedulerNode.get_read_write_buffer_accesses.<locals>.get_buf_bytes.<locals>.<genexpr>u  s/   øé € ð â(@˜Hñ &¤a§g¡g×&8Ñ&8¸Ó&B×CÐCÚ(@ùó   ƒ25)r’   r)   ÚTorchBindObjectrß  r=  r<   r(  rX  r0  r-  r•   r`  r\   r;   r—  r=   ré   rO  rV   rÃ  rK   Ú	get_dtypeÚmin)
rÄ   r-  ÚtotrD  Ú	sched_bufÚ	buf_elemsÚbuf_accessed_elemsrß  ri   rÊ  s
         €€€€rj   rß  ÚGBaseSchedulerNode.get_read_write_buffer_accesses.<locals>.get_buf_bytesZ  s[  ø€ ö Øä˜c¤2×#5Ñ#5×6Ñ6Ø×,Ñ,Ó.Ð.Ü §
¡
Ô,=×>Ñ>ð !ŸN™N×6Ñ6°s·|±|³~ÑF×LÑL�EØ�CÛ %˜Ü% d§i¡i´×<Ñ<Ù$Ü)¨$¯)©)Ô5F×GÑGÐGÐGÜ% d§i¡i§n¡n´k×BÑBØ-1¯Y©Y×-BÑ-BÖ-D 	Ø #¡}°Y·^±^Ó'DÑ D¢ó .Eñ $%ñ !&ð �JÜ §
¡
¬B¯M©M×:Ñ:Üô à(+×(>Ñ(>Ô(@óó ð ñ
 !.¬m¸C¿L¹L»NÓ.KÓ L�IÜ)¨#¯-©-«/Ó:¼SØ*¨Ió>ñ ð rm   )rÉ  z
sympy.Exprr‹   r!  )rÄ   r  rÁ   úSequence[BaseSchedulerNode]r‹   rx   )rÄ   z<Optional[Union[ir.Buffer, ir.TensorBox, ir.TorchBindObject]]r‹   r!  )r’   r‘  ÚExternKernelSchedulerNoder•   r;   r)   r“  Úop_overloadr¿  Ú_primsÚ	rng_primsÚgraphsafe_run_with_rng_stater“   rV   Ú
get_rangesr!  Úcollectionsr   r  rº   r»   r¼   rË   r­  r   r¿   ré   rW   r¤   r  Úgraph_inputs)ri   r·  r¸  Úbuf_accessesrÆ   r»   r­  r�  Úbuf_byte_accessesrR  rÄ   Ú	buf_bytesrè  rß  rÕ  rÚ  rÊ  s   `           @@@@@rj   rÅ  Ú0BaseSchedulerNode.get_read_write_buffer_accessesù  s¯  ý€ ô6 �dÔ2×3Ñ3ØˆIÜ�dÔ5×6Ñ6¼:Ø�I‰I”{÷<
ñ <
ð ˆIä�tÔ6×7Ñ7Ü˜4Ÿ9™9¤b×&7Ñ&7×8Ñ8Ø—	‘	×%Ñ%Ü�|‰|×%Ñ%×BÑBòCð ˆIô	Eô �dœM×*Ñ*Ù&Ü˜dŸo™oÓ/°Ñ2Ó3Ü §¡Ó 1°!Ñ 4Ó5ñ6ó‰Jô
 ˜S›ˆJÜ"×.Ò.¬tÓ4ˆæØ×'Ñ'×-Ô-�ØŸX™XÑ&×-Ñ-¨cÖ2ñ .ö Ø×'Ñ'×.Ô.�ØŸX™XÑ&×-Ñ-¨cÖ2ñ /ö
 ô ÑB¨4×+;Ñ+;×+AÒ+AÓBÔBä“ð 	ö ô ÑC¨4×+;Ñ+;×+BÒ+BÓCÔCä“ð 	÷	:ô
 �dÔ.×/Ñ/Ü(õ )Ù%ó)ó ˆOð Ñ-ˆFØÑ+ˆEà,.ÐàœˆHÜ!$Ô$R¸<Ò;QÓ$RÓ!RÐàœ1Ÿ7™7×1Ñ1Ó1Ü—g‘g×,Ñ,¨XÑ6‘ØœQŸW™W×1Ñ1Ó1Ü—g‘g×*Ñ*¨8Ñ4‘áð#ØQð#à÷#ò #ñJ & cÓ*ˆIØÓ0Ø.7 (Ó+à!Ó+¨yÑ8Õ+ñg 'ðj !Ð rm   c                ó^  • U R                   c  g U R                   R                  5       nUc  g [        U5      nUc  g [        U[        R
                  5      (       a  UR                   R                  n[        R                  R                  R                  USS9n[        S   S==   U-  ss'   U$ )Nr   rÖ   ÚinductorÚ
flop_count)r•   Úget_origin_noder7   r’   r¿  ÚSymIntÚexprrW   r¤   r¥   rØ   r   )ri   Úfx_nodeÚflopsÚresolved_flopss       rj   Úestimate_flopsÚ BaseSchedulerNode.estimate_flops‡  s“   € à�9‰9ÑØØ—)‘)×+Ñ+Ó-ˆØ‰?Øä˜wÓ'ˆØ‰=Øä�eœUŸ\™\×*Ñ*Ø—J‘J—O‘OˆEäŸ™×)Ñ)×;Ñ;¸EÈAÐ;ÐNˆÜ�Ñ˜\Ó*¨nÑ<Ó*ØÐrm   c                óT   • U R                   b  U R                   $ U R                  5       $ ry   )r‰  Ú_get_estimated_runtimerh   s    rj   Úget_estimated_runtimeÚ'BaseSchedulerNode.get_estimated_runtimeš  s)   € Ø×*Ñ*Ñ6Ø×2Ñ2Ð2à×*Ñ*Ó,Ð,rm   c                ó,  • U R                  5       S   R                  5       S   nUR                  R                  5       n[	        [        U5      5      (       d  g[        U R                  5      (       aÌ  [        U R                  [        R                  5      (       d   e [        R                  (       av  [        U 5      n[        5       nUR                  U5      nUb  [        U[        5      (       d   eU$ [!        U 5      nUc  [#        U R                  5      nUR%                  X6S9  U$ [#        U R                  5      $ [/        U R                  5      (       a  g[1        U 5      nUb  U$ UR                  R3                  5       n	 [5        5       n
[7        U	5      S-  nU
S::  a  [9        SU
 35      eUS::  a  [9        SU 35      e U R=                  5       nUS:X  d  Uc  U R?                  5       U
-  nUS-  nU$ SnU R?                  5       nUc  SOUnXì-  U-  S	-  nXú-  n[A        UU5      nUS-  nU$ ! [&         a  n[(        R+                  U5         SnAgSnAf[,         a  n[(        R+                  U5         SnAgSnAff = f! [:         a     gf = f)
z3
Returns estimated op runtime in milliseconds (ms)
r   N©Úvaluel    J)£z-gpu_memory_bandwidth cannot be <= 0, but got z"gpu_flops cannot be <= 0, but got g    €„.Ag      ð?rÌ  )!r�   r—  r•   rP  rR   r9   rP   r’   r)   ÚIRNoder'   Ú,runtime_estimations_use_nccl_lib_estimationsÚ)get_estimate_runtime_cache_key_from_snodeÚget_estimate_runtime_cacheÚlookupÚfloatr0   r/   Ú	set_valueÚ
ValueErrorr°  rË  Ú	TypeErrorrU   Ú maybe_estimate_runtime_benchmarkÚmaybe_get_dtyperL   rJ   ÚAssertionErrorr¯  r   r»  Úmax)ri   rÄ   r=  Ú	cache_keyÚcacheÚ	cache_valÚmsr  ÚretÚdtypeÚgpu_memory_bandwidthÚ	gpu_flopsÚ	flops_estÚnsÚfactorÚcounted_bytesÚcompute_timeÚtransfer_times                     rj   r  Ú(BaseSchedulerNode._get_estimated_runtime   s  € ð
 �n‰nÓ˜qÑ!×-Ñ-Ó/°Ñ2ˆØ—‘×)Ñ)Ó+ˆÜ”o fÓ-×.Ñ.àô ˜Ÿ™×#Ñ#Ü˜dŸi™i¬¯©×3Ñ3Ð3Ð3ðÜ×L×LÜ IÈ$Ó O�IÜ6Ó8�EØ %§¡¨YÓ 7�IØ Ñ,Ü)¨)´U×;Ñ;Ð;Ð;Ø(Ð(äHÈÓN�BØ‘zä=¸d¿i¹iÓH˜à—O‘O I�OÑ8Ø�IÜ7¸¿	¹	ÓBÐBô �T—Y‘Y×Ñð
 ä.¨tÓ4ˆØ‰?ØˆJà—‘×(Ñ(Ó*ˆð	Ü#4Ó#6Ð Ü)¨%Ó0°6Ñ9ˆIð $ qÓ(Ü$ØCÐDXÐCYÐZóð ð ˜A‹~Ü$Ð'IÈ)ÈÐ%UÓVÐVð ð
 ×'Ñ'Ó)ˆ	à˜‹>˜YÑ.à×2Ñ2Ó4Ð7KÑKˆBØ�c‘ˆBØˆIð ˆØ×9Ñ9Ó;ˆØ*Ñ2™¸ˆØÑ*¨YÑ6¸#Ñ=ˆØ%Ñ<ˆô �˜}Ó-ˆØ�#‰XˆØˆ	øôo ó ô —‘˜”ÜûÜó ä—‘˜”Üûðûô: ó 	Ùð	úsD   ÂAH3 Ã63H3 Ä*H3 ÆA J È3
JÈ=IÉJÉ$I>É>JÊ
JÊJc                ó   • g ry   rw   rh   s    rj   Úget_template_nodeÚ#BaseSchedulerNode.get_template_nodeø  ó   € Ørm   c                ó0   • U R                  5       nUc   eU$ ry   ©r&  )ri   Útemplates     rj   Úget_template_node_or_throwÚ,BaseSchedulerNode.get_template_node_or_throwû  s!   € Ø×)Ñ)Ó+ˆØÑ#Ð#Ð#Øˆrm   c                ó`   • [        S [        U 5       5       5      nU SU nX   nXS-   S nX#U4$ )zA
For the list of nodes, get the prologue, template, and epilogue
c              3  óX   #   • U  H   u  pUR                  5       (       d  M  Uv •  M"     g 7fry   ©rj  )r˜   ÚirD  s      rj   rš   ÚCBaseSchedulerNode.get_prologue_template_epilogue.<locals>.<genexpr>  s   é € ÐPÒ,<¡D AÀÇÁÇŸa™aÒ,<ùs   ‚*¡	*Nr   )ÚnextÚ	enumerate)ÚnodesÚtemplate_indexÚprologueÚtemplate_nodeÚepilogues        rj   Úget_prologue_template_epilogueÚ0BaseSchedulerNode.get_prologue_template_epilogue   sH   € ô ÑP¬I°eÔ,<ÓPÓPˆà˜˜.Ð)ˆØÑ-ˆØ¨!Ñ+Ð-Ð.ˆØ¨Ð0Ð0rm   )rï   r“  r~  rƒ  r•   r…  r‡  rº   r(  rŒ  r�  )r(  r'  r‹   rs  )r•   úir.Operationr‹   rs  rp  )r‹   r   rr  ©rÐ  r2   rÑ  r2   r‹   rx   ©rÞ  r‚  r‹   rs  )rÆ   r1   r‹   rs  rt  )rí  rŠ  r‹   rs  ©r÷  r}  ró  r‚  r‹   rs  ©r‹   r}  ©r)  údict[str, BaseSchedulerNode]r‹   rs  ©r‹   rê  )r‹   zSequence[SchedulerBuffer])rR  r  r‹   r&  rv  ©rt  zdependencies.Depr‹   rx   ©T)r­  rO   r®  rx   r‹   rs  rq  )r·  rx   r¸  rx   r‹   r!  )r·  rx   r¸  rx   r‹   zdict[str, int]©r‹   z
int | None©r‹   r  ©r‹   zOptional[ir.TemplateBuffer])r‹   zir.TemplateBuffer)r5  úlist[BaseSchedulerNode]r‹   zJtuple[list[BaseSchedulerNode], BaseSchedulerNode, list[BaseSchedulerNode]])@r{   r|   r}   r~   r   r•   r‰  r�  r”  r™  rž  rE  r®  r¹  rÈ  rÌ  rÒ  rß  rä  ré  rÜ  rù  rü  rÊ   rö  rì  r%  r*  r0  r1  rF   rð   r=  rG  r+   r�   r—  rS  rî   r\  rR   r”   rd  rg  rj  rm  rp  ru  rx  r›  r³  r»  r¾  rÁ  rº  rÅ  r   r  r  r&  r,  r$  r:  r�   rw   rm   rj   r\   r\     sµ  ‡ ØÓØBÓBØÓð ƒNØƒNØ'Ó'Ø$Ó$Ø#'€DÐ
 Ó'Ø"Ó"Ø/Ó/Ø26Ð Ó6Ø(Ó(Ø'Ó'Ø€GˆTÓô
ô#ô0Bô*ô2ô+ô#ô
ðØ!ðØ.7ðà	ôô
Mô>ô
ô
ð
=Ø#2ð=ØHVð=à	ô=ôô
ôô6
ôGð TØ">ðTà	ôTô
.ôð óHó ðHð óBó ðBð ó
ó ð
ð ó
ó ð
ôôô.ô&ô;ô:ôôôôôôôôô@ðF 9=ð-Ø$ð-Ø15ð-à	õ-ð^ ó
ó ð
ð
 ó
ó ð
ð
 ó
ó ð
ð

Ø!ð
Ø37ð
à	ô
ðL!Ø!ðL!Ø37ðL!à	ôL!ð\ óó ðô$-ð óUó ðUônôð
 ð1Ø&ð1à	Só1ó ó1rm   c                 óR   • [         R                  R                  R                  5       $ ry   )r¿  rÀ  Ú	codecacheÚ
LocalCacherw   rm   rj   r  r    s   € ä�?‰?×$Ñ$×/Ñ/Ó1Ð1rm   c                óž  ^• [        U R                  SS5      nU R                  R                  nU R                  R                  / UQU R                  R                  QU R                  R
                  5      nU R                  R
                  n[        R                  " X#45      u  pESS jm[        U4[        U4S jU 5       5      -   5      nU$ )NÚpython_kernel_namerµ  c                ó‚   • [        U [        R                  5      =(       a    [        U [        R                  5      (       + $ ry   )r’   r)   r	  ÚGeneratorState©r™  s    rj   Ú_is_tensor_irÚ@get_estimate_runtime_cache_key_from_snode.<locals>._is_tensor_ir  s(   € Ü˜!œRŸY™YÓ'×P´
¸1¼b×>OÑ>OÓ0PÔ,PÐPrm   c              3  ót   >#   • U  H-  nT" U5      (       a  [        UR                  5       5      OS v •  M/     g 7fry   )r³   rÃ  )r˜   ÚarR  s     €rj   rš   Ú<get_estimate_runtime_cache_key_from_snode.<locals>.<genexpr>#  s+   øé € ÐUÊ9Àa¡}°Q×'7Ñ'7”�a—j‘j“lÔ#¸TÔAÊ9ùs   ƒ58rt  )
r¬  r•   ÚinputsÚfill_non_provided_argsÚconstant_argsr�  ÚpytreeÚtree_flattenr  r³   )ÚsnoderN  rL  r�  Ú	flat_argsÚflat_args_pytree_specr  rR  s          @rj   r  r    s¸   ø€ Ü  §¡Ð-AÀ2ÓFÐØ�:‰:×Ñ€DØ�:‰:×,Ñ,Ø*ˆ$Ð*�—‘×)Ñ)Ð*Ø�
‰
×Ñó€Dð �Z‰Z×Ñ€FÜ'-×':Ò':¸D¸>Ó'JÑ$€IôQô Ø	ÐÜ
ÔUÉ9ÓUÓ
Uñ	Vó€Ið Ðrm   c                óœ  • [        U [        5      (       d  g [        R                  R                  R
                  [        R                  R                  R                  [        R                  R                  R                  S.n[        U R                  SS5      nX!;  a  g [        U R                  [        R                  5      (       d  g X   $ )N)zextern_kernels.mmzextern_kernels.bmmzextern_kernels.addmmrN  rµ  )r’   rë  r¿  ÚopsÚatenÚmmÚbmmÚaddmmr¬  r•   r)   ÚExternKernel)r\  Úmms_fnsrN  s      rj   Ú_get_mm_like_fnrg  (  s�   € Ü�eÔ6×7Ñ7Øä"ŸY™YŸ^™^×.Ñ.Ü#Ÿi™iŸn™n×0Ñ0Ü %§	¡	§¡× 4Ñ 4ñ€Gô
 ! §¡Ð-AÀ2ÓFÐØÓ(ØÜ�e—j‘j¤"§/¡/×2Ñ2ØØÑ&Ð&rm   c           	     ód  ^ ^• S nS n[         R                  (       a  [        T 5      nUc  g UnU U4S jnOg [        T 5      n[	        5       nUR                  U5      nUb  [        U[        5      (       d   eU$ SSKJ	m  U" 5       u  pxSSK
Jn	  U	R                  UUUSSSS9n
UR                  XJS	9  U
$ )
Nc                 ó   >• T" T 5      $ ry   rw   )r\  Úsnode_args_kwargss   €€rj   r‘  Ú2maybe_estimate_runtime_benchmark.<locals>.<lambda>A  s   ø€ Ñ!2°5Ô!9rm   r   )rj  r   )Úbenchmarkeré   é
   )Úmemory_warmup_itersÚbenchmark_itersÚmax_benchmark_durationr  )r&   Ú!runtime_estimations_mms_benchmarkrg  r  r  r  r’   r  Úutilsrj  Ú$torch._inductor.runtime.benchmarkingrl  Ú	benchmarkr  )r\  Úbench_fnÚargs_kwargs_fnÚmm_fnr  r  r  rL  r�  rl  r  rj  s   `          @rj   r  r  8  sÀ   ù€ Ø€HØ€NÜ×/×/Ü Ó&ˆØ‰=ØØˆå9‰àä9¸%Ó@€IÜ&Ó(€EØ—‘˜YÓ'€IØÑÜ˜)¤U×+Ñ+Ð+Ð+ØÐå(á!Ó#�L€DÝ@à	×	Ñ	ØØØØØØ!ð 
ð 
€Bð 
‡O�O�I€OÑ(Ø€Irm   T)Úslotsc                  ó\   • \ rS rSr% S\S'   S\S'   S\S'   S\S'   SS jrSS	 jrSS
 jrSrg)Ú	WhyNoFusei^  r  Úname1Úname2Úreasonztuple[Any, ...]rL  c                óX   • UR                  5       U l        UR                  5       U l        g ry   )r0  r|  r}  ©ri   r…   r†   s      rj   r”  ÚWhyNoFuse.__init__e  s   € Ø—^‘^Ó%ˆŒ
Ø—^‘^Ó%ˆ�
rm   c                óF   • Xl         X l        [        R                  U 5        g ry   )r~  rL  Ú
fusion_logÚdebug)ri   r~  rL  s      rj   Ú__call__ÚWhyNoFuse.__call__i  s   € ØŒØŒ	Ü×Ñ˜Õrm   c                óp   • SU R                    SU R                   S3U R                  U R                  -  -   $ )Nzcannot fuse z with r9  )r|  r}  r~  rL  rh   s    rj   Ú__str__ÚWhyNoFuse.__str__n  s6   € Ø˜dŸj™j˜\¨°·
±
¨|¸2Ð>Ø�K‰K˜$Ÿ)™)Ñ#ñ
ð 	
rm   )rL  r|  r}  r~  N©r…   r\   r†   r\   r‹   rs  )r~  r  rL  r   r‹   rs  rp  )	r{   r|   r}   r~   r   r”  r…  rˆ  r�   rw   rm   rj   r{  r{  ^  s&   ‡ àƒJØƒJØƒKØ
Óô&ô÷

rm   r{  c                óÂ   • [        U [        [        45      (       a  [        U [        S9n [
        R                  " U SS9nSU;   a  S[        R                  " US5       3$ U$ )N©Úkeyé   )rA  r¥  ú    )	r’   r   ÚsetÚsortedr  Úpprintr?  ÚtextwraprA  )ÚobjrC  s     rj   r?  r?  t  sU   € Ü�#œ
¤CÐ(×)Ñ)ä�SœcÑ"ˆÜ�^Š^˜C¨Ñ*€FØˆvƒ~Ø”H—O’O F¨GÓ4Ð5Ð6Ð6Ø€Mrm   c                  ó@   • \ rS rSrSS jrS	S jrS
S jrSS jr\rSr	g)r`  i~  c                ó&   • [        U/5      U l        g ry   r  rã  s     rj   r”  ÚOutputNode.__init__  s   € Ü",¨c¨UÓ"3ˆÕrm   c                ó   • grÏ  rw   rh   s    rj   r”   ÚOutputNode.is_reduction‚  rb  rm   c                ó   • g)Nrw   rw   rh   s    rj   rN  Ú'OutputNode.get_inputs_that_alias_output…  r·  rm   c                ó   • g)NÚOUTPUTrw   rh   s    rj   r0  ÚOutputNode.get_nameˆ  s   € Ørm   )rŒ  N)rÆ   r3   r‹   rs  rt  ru  rp  )
r{   r|   r}   r~   r”  r”   rN  r0  rž  r�   rw   rm   rj   r`  r`  ~  s   † ô4ôôôð ƒHrm   r`  c                óâ  ^ ^^^^• [         R                  " 5       mT R                   HU  n[        U[        5      (       a  M  TUR
                     R                  5       nTTU   R                  5       ==   S-  ss'   MW     SUUUU 4S jjm[        U4S jT R                   5       5      nU(       a?  T R                  U-
  T l        T R                  T R                  R                  U5      5        gg)aU  
Prunes weakdeps intended for mutation ordering
on an upstream fused node if after fusion there is another dependency
on the fused upstream node, making the weakdep redundant

In essence this enforces an ordering on fusions. As fusions occur, weakdeps will
be incrementally removed, enabling other fusions, ensuring they are fused in order.
r   c                ó  >• [        U [        5      (       ap  TU R                     R                  5       nTTU   R	                  5          S:„  =(       a     TR
                  R                  U TU   T5      nTU   T:H  nU=(       d    U$ g)Nr   F)r’   r4   r¼   r2  r0  r(  Úfusable_weak_dep)rÆ   r  Úis_redundantÚis_self_deprX  Úname_to_dep_countr)  r•   s       €€€€rj   r  Ú+_prune_redundant_deps.<locals>.should_prune¢  s�   ø€ Ü�cœ7×#Ñ#Ø! #§(¡(Ñ+×<Ñ<Ó>ˆGØ,Ø" 7Ñ+×4Ñ4Ó6ñàñ÷ à—n‘n×5Ñ5ØÐ'¨Ñ0°$óð ð -¨WÑ5¸Ñ=ˆKØ×. ;Ð.àrm   c              3  óF   >#   • U  H  nT" U5      (       d  M  Uv •  M     g 7fry   rw   r  s     €rj   rš   Ú(_prune_redundant_deps.<locals>.<genexpr>²  s   øé € ð Ú.�±,¸s×2C�‰Ò.ùr!  Nr"  )rñ  r   rŒ  r’   r4   r¼   r2  r0  r   rÜ  rº   r#  )r•   r)  rX  rÆ   r  Údeps_to_pruner¤  r  s   ```   @@rj   r(  r(  Ž  sÌ   ü€ ô '2×&9Ò&9Ó&;Ðà×&Ô&ˆÜ˜#œw×'Ó'Ø! #§(¡(Ñ+×<Ñ<Ó>ˆGØÐ0°Ñ9×BÑBÓDÓEÈÑJÕEñ '÷
ò ô  ô Ø×.Ò.óó €Mö Ø"&×"9Ñ"9¸MÑ"IˆÔØ×Ñ˜T×-Ñ-×:Ñ:¸=ÓIÕJð rm   c                  óJ   ^ • \ rS rSrSU 4S jjrSS jrS	S jrS	S jrSrU =r	$ )
rë  i»  c                ó„   >• [         TU ]  U5        U R                  U5        U R                  UR	                  5       5        g ry   ©Úsuperr”  r™  rÜ  Úget_read_writes©ri   r(  r•   Ú	__class__s      €rj   r”  Ú"ExternKernelSchedulerNode.__init__¼  ó5   ø€ Ü‰Ñ˜Ô#Ø×Ñ˜TÔ"Ø×Ñ˜T×1Ñ1Ó3Õ4rm   c                óV   • U R                  5        S[        U R                  SS 5       3$ )Nz.node.kernel = rN  )r0  r¬  r•   rh   s    rj   r®  Ú)ExternKernelSchedulerNode.debug_str_extraÁ  s*   € Ø—-‘-“/Ð" /´'¸$¿)¹)ÐEYÐ[_Ó2`Ð1aÐbÐbrm   c                ó   • g©NTrw   rh   s    rj   rm  Ú#ExternKernelSchedulerNode.is_externÄ  r(  rm   c                óŽ   • U R                   c   e[        U R                   S5      =(       a    U R                   R                  5       $ )Nrx  )r•   rT  rx  rh   s    rj   rx  Ú*ExternKernelSchedulerNode.has_side_effectsÇ  s6   € Ø�y‰yÑ$Ð$Ð$Ü�t—y‘yÐ"4Ó5×V¸$¿)¹)×:TÑ:TÓ:VÐVrm   rw   ©r(  r'  r•   r<  r‹   rs  rp  rt  )
r{   r|   r}   r~   r”  r®  rm  rx  r�   Ú__classcell__©r¯  s   @rj   rë  rë  »  s   ø† ÷5ô
cô÷Wò Wrm   rë  c                  ó,   ^ • \ rS rSrSU 4S jjrSrU =r$ )r‘  iÌ  c                ó„   >• [         TU ]  U5        U R                  U5        U R                  UR	                  5       5        g ry   r«  r®  s      €rj   r”  ÚNopKernelSchedulerNode.__init__Í  r±  rm   rw   r¹  )r{   r|   r}   r~   r”  r�   rº  r»  s   @rj   r‘  r‘  Ì  s   ø† ÷5õ 5rm   r‘  c                  óà  ^ • \ rS rSr% SrS\S'   S\S'         S#U 4S jjr  S$     S%S jjr  S$     S&S	 jjr      S'S
 jr	S(S jr
S)S jrS*S jrS)S jr      S+S jrS)S jr      S,S jrS-S jrS.S jrS/S jrS/S jrS/S jrS/S jrS0S jrS1S jr    S2S jrS3S jr S4   S5S jjr\S6S j5       r\S6S j5       rS7S jr\S8S  j5       r \S/U 4S! jj5       r!S"r"U =r#$ )9r“   iÓ  zi
A SchedulerNode is a node for scheduling that encapsulates either
a ComputedBuffer or a TemplateBuffer.
z tuple[Sequence[sympy.Expr], ...]Ú_sizesr>   r  c                óf   >• [         TU ]  U5        U R                  U5        U R                  5         g ry   )r¬  r”  r™  Ú_compute_attrsr®  s      €rj   r”  ÚSchedulerNode.__init__Ü  s,   ø€ ô
 	‰Ñ˜Ô#Ø×Ñ˜TÔ"Ø×ÑÕrm   c                ó  • [        U R                  [        R                  [        R                  45      (       d   eU R                  R                  UUS9u  U l        nX0l        U R                  R                  5       nU R                  R                  U5      R                  nXE" U R                  5      4U l        [        R                  (       + =(       d    [        UR                   5      (       + n[        U R                  [        R                  5      (       a)  U R#                  U R                  R%                  US95        g U R#                  [&        R$                  " U R                  /U R                  Q7SU065        g )N©Úextra_indexing_constraintsÚrecompute_sizes_body_func)Ú	normalizerÈ  )r’   r•   r)   r   ÚTemplateBufferÚsimplify_and_reorderrÀ  r  Úget_device_or_errorr(  Úget_backendÚgroup_fnr©   r&   Úloop_ordering_after_fusionrR   rÀ   rÜ  Úextract_read_writesr(   )ri   rÆ  rÇ  Úbodyr[  rÍ  Úshould_normalizes          rj   rÂ  ÚSchedulerNode._compute_attrså  s;  € ô
 ˜$Ÿ)™)¤b×&7Ñ&7¼×9JÑ9JÐ%K×LÑLÐLÐLØ ŸI™I×:Ñ:Ø'AØ&?ð ;ð 
ÑˆŒ�Tð Œ
à—‘×.Ñ.Ó0ˆØ—>‘>×-Ñ-¨fÓ5×>Ñ>ˆØ˜h t§{¡{Ó3Ð4ˆŒ
ô  &×@Ñ@Ô@÷ 
ÌØ�K‰KóI
ô E
Ðô �d—i‘i¤×!2Ñ!2×3Ñ3Ø× Ñ Ø—	‘	×-Ñ-Ð8HÐ-ÐIõð × Ñ Ü×0Ò0Ø—J‘JðØ!%§¡òØ8Hñõrm   c                ó$   • U R                  UUS9  g )NrÅ  )rÂ  )ri   rÆ  rÇ  s      rj   Úrecompute_size_and_bodyÚ%SchedulerNode.recompute_size_and_body  s   € ð
 	×ÑØ'AØ&?ð 	ò 	
rm   c                ó   • [        S U R                  R                   5       5      nU R                  [        R
                  " U R                  /U R                  Q7SU06R                  U5      R                  U R                  5      5        U R                  R                  U 5        U(       a!  SSKJn  UR                  R!                  5         g g )Nc              3  ó`   #   • U  H$  n[        U[        [        45      (       d  M   Uv •  M&     g 7fry   )r’   r4   r3   rØ  s     rj   rš   Ú5SchedulerNode.refresh_dependencies.<locals>.<genexpr>  s$   é € ð 0
Ú1�C´ZÀÄgÌwÐEW×5X�C‰CÒ1ùs   ‚.¥	.rÈ  r   ©ÚSIMDScheduling)r   rº   r»   rÜ  r(   rÏ  r  rÀ  râ  rÝ  rƒ  Úpointwise_read_writesÚclear_cacheÚcodegen.simdrÚ  Úcandidate_tilingsÚcache_clear)ri   rÈ  Úneed_clear_tiling_cacheÚ	fake_depsrÚ  s        rj   Úrefresh_dependenciesÚ"SchedulerNode.refresh_dependencies  s±   € ô
 &0ñ 0
Ø×+Ñ+×1Ò1ó0
ó &
ˆ	ð 	×ÑÜ×,Ò,Ø—
‘
ðØ!Ÿ[™[òØ4=ñ÷ ‰Y�yÓ!ß‰V�D×)Ñ)Ó*ô	
ð 	×"Ñ"×.Ñ.¨tÔ4æ"Ý4ð ×,Ñ,×8Ñ8Õ:ð #rm   c                óš   • U R                   R                  U5      U l         U R                   R                  U l        U R	                  SSS9  g )NFT©rÈ  rà  )r  Úreorder_iter_loopsÚsizesrÀ  râ  )ri   Ú	new_orders     rj   Úapply_new_loop_orderÚ"SchedulerNode.apply_new_loop_order.  sA   € Ø—Z‘Z×2Ñ2Øó
ˆŒ
ð —j‘j×&Ñ&ˆŒà×!Ñ!¨EÈ4Ð!ÒPrm   c                ó¤  • U R                   R                  5       n[        U R                   R                  5      U-
  n[	        [        U5      5      n[	        [        X"U-   5      5      nU R                  XC-   5        [        U R                  S   5      S:X  d   eU R                  S   U R                  S   S   U R                  S   S   44U l        g )Nr   r±   r   )r  Úget_original_num_rdimsr²   Ú	iter_varsr³   Úrangeré  r©   )ri   Ú	num_rdimsÚ
num_pwdimsÚpwdimsÚrdimss        rj   Úswap_pw_red_dimensionÚ#SchedulerNode.swap_pw_red_dimension6  s®   € Ø—J‘J×5Ñ5Ó7ˆ	Ü˜Ÿ™×-Ñ-Ó.°Ñ:ˆ
Ü”u˜ZÓ(Ó)ˆÜ”e˜J°YÑ(>Ó?Ó@ˆà×!Ñ! %¡.Ô1Ü�4—:‘:˜a‘=Ó! QÓ&Ð&Ð&Ø—Z‘Z ‘] T§Z¡Z°¡]°1Ñ%5°t·z±zÀ!±}ÀQÑ7GÐ$HÐHˆ�
rm   c                óD   • U R                   R                  5       U l         U $ ry   )r  Úextract_pw_from_reductionrh   s    rj   rö  Ú'SchedulerNode.extract_pw_from_reduction@  s   € Ø—Z‘Z×9Ñ9Ó;ˆŒ
Øˆrm   c                ó  • [         R                  U 5      (       d  g [        U R                  [        R
                  5      (       d   eU R                  R                  5          U R                  5         S S S 5        g ! , (       d  f       g = fry   )rŽ   rŸ   r’   r•   r)   r   Úwith_original_inner_fnrÂ  rh   s    rj   Úcancel_reduction_splitÚ$SchedulerNode.cancel_reduction_splitD  s[   € Ü ×3Ñ3°D×9Ñ9ØÜ˜$Ÿ)™)¤R×%6Ñ%6×7Ñ7Ð7Ð7Ø�Y‰Y×-Ñ-Õ/Ø×ÑÔ!÷ 0×/Ö/ús   Á!A;Á;
B	c                ó¾  • [        U R                  [        R                  [        R                  45      (       d   eU R
                  R                  X5      U l        U R
                  R                  U l        U R                  R                  5       nU R                  R                  U5      R                  nX4" U R                  5      4U l        U R                  SSS9  g )NTrå  )r’   r•   r)   r   rÉ  r  Ú#expand_dimension_for_pointwise_noderç  rÀ  rË  r(  rÌ  rÍ  r©   râ  )ri   Ú	dimensionÚ	new_ranger[  rÍ  s        rj   rý  Ú1SchedulerNode.expand_dimension_for_pointwise_nodeK  s®   € ô ˜$Ÿ)™)¤b×&7Ñ&7¼×9JÑ9JÐ%K×LÑLÐLÐLà—Z‘Z×CÑCØó
ˆŒ
ð —j‘j×&Ñ&ˆŒà—‘×.Ñ.Ó0ˆØ—>‘>×-Ñ-¨fÓ5×>Ñ>ˆØ˜h t§{¡{Ó3Ð4ˆŒ
ð 	×!Ñ!¨DÈ$Ð!ÒOrm   c                ó˜   • U R                   R                  5       U l         U R                   R                  U l        U R	                  SSS9  g )NTFrå  )r  Úmerge_loopsrç  rÀ  râ  rh   s    rj   r  ÚSchedulerNode.merge_loops\  s<   € Ø—Z‘Z×+Ñ+Ó-ˆŒ
Ø—j‘j×&Ñ&ˆŒð 	×!Ñ!¨DÈ%Ð!ÒPrm   c                ó˜  • S nU R                   S   n[        U5      UR                  s=:X  a  UR                  :X  a  O  OUR                  U5      nU(       aP  [        =R
                  S-  sl        [        R                  SU R                  5       U5        U R                  U5        g[        R                  SU R                  5       5        g)Nr   r   z"Reorder loops for %s with order %sTzEDon't reordering %s because we can not decide the suitable loop orderF)
rÀ  r²   Únum_varsÚdecide_loop_order_to_matchr*   Únum_loop_reorderingÚloop_ordering_logr„  r0  ré  )ri   rÐ  rÑ  rè  Ú
self_sizess        rj   rÒ  Ú'SchedulerNode.reorder_loops_by_dep_pairh  s¤   € ð ˆ	Ø—[‘[ ‘^ˆ
Üˆz‹?˜h×/Ñ/ÕE°9×3EÑ3EÖEØ ×;Ñ;¸IÓFˆIæä×'Ò'¨1Ñ,Õ'Ü×#Ñ#Ø4°d·m±m³oÀyôð ×%Ñ% iÔ0Øä×#Ñ#ØWØ—‘“ôð rm   c                óN  • U R                  5       nU SU R                  S    3U SU R                  S    3U SU R                   3/nU R                  R	                  5        H�  n[        U[        5      (       a  M  UR                  n[        R                  R                  U5      n[        U[        R                  5      (       a  Mf  UR                  U S[        UR                  5       35        M‘     [        U R                   ["        5      (       aS  UR                  SU S35        UR                  [$        R&                  " U R                   R)                  5       S	5      5        U R*                  c   eUR-                  U R/                  5       5        S
R1                  U5      $ )Nz.group.device = r   z.group.iteration = r   z	.sizes = z
_layout = zclass z_loop_body:r�  r¥  )r0  r©   rÀ  rº   rÛ  r’   r4   r¼   rW   r¤   rÝ  r)   râ  rË   r?  r=  r  r>   r“  rA  rE  r•   r  r¹  Újoin)ri   r¼   ÚlinesrÆ   rR  rÄ   s         rj   r®  ÚSchedulerNode.debug_str_extra  sM  € Ø�}‰}‹ˆàˆfÐ$ T§Z¡Z°¡] OÐ4ØˆfÐ'¨¯
©
°1© Ð7Øˆf�I˜dŸk™k˜]Ð+ð
ˆð
 ×#Ñ#×4Ñ4Ö6ˆCÜ˜c¤7×+Ó+ØŸ8™8�Ü—g‘g×(Ñ(¨Ó2�Ü! #¤r×'9Ñ'9×:Ó:Ø—L‘L H :¨Z¼ÀÇ
Á
Ó8KÐ7LÐ!MÖNñ 7ô �d—j‘j¤(×+Ñ+Ø�L‰L˜6 $  {Ð3Ô4Ø�L‰LœŸš¨¯©×)=Ñ)=Ó)?ÀÓHÔIà�y‰yÑ$Ð$Ð$Ø�‰�T×/Ñ/Ó1Ô2à�y‰y˜ÓÐrm   c                ó   • U R                   $ ry   )rÀ  rh   s    rj   rð  ÚSchedulerNode.get_ranges•  ó   € Ø�{‰{Ðrm   c                ód  • [        U R                  [        R                  [        R                  45      (       d   S[        U R                  5      < 35       e[        U R                  R                  5       5      =(       a0    U R                  S L =(       d    U R                  R                  (       + $ ©Nútype(self.node)=)
r’   r•   r)   r   rÉ  rÀ   rx   rë   r  Úhas_partial_accumulaterh   s    rj   r”   ÚSchedulerNode.is_reduction˜  sƒ   € Ü˜$Ÿ)™)¤b×&7Ñ&7¼×9JÑ9JÐ%K×LÑLð 	
ØŒt�D—I‘I‹Ñ Ð!ó	
ÐLô �D—I‘I×0Ñ0Ó2Ó3÷ 
Ø�J‰J˜$Ð×G d§j¡j×&GÑ&GÔ"Gð	
rm   c                óÊ   • [        U R                  [        R                  5      (       d   S[	        U R                  5      < 35       eU R                  R                  5       S:H  $ )Nr  Údot)r’   r•   r)   r   rÀ   rë   rh   s    rj   rd  ÚSchedulerNode.is_native_matmul¥  sM   € Ü˜$Ÿ)™)¤R×%6Ñ%6×7Ñ7ÐNÐ<L¼DÀÇÁ»OÑ;MÐ9NÓNÐ7Ø�y‰y×+Ñ+Ó-°Ñ6Ð6rm   c                ób  • [        U R                  [        R                  [        R                  45      (       d   S[        U R                  5      < 35       e[        U R                  [        R                  5      =(       a.    [        U R                  R                  [        R                  5      $ r  )r’   r•   r)   r   rÉ  rÀ   rã   Ú	SplitScanrh   s    rj   rg  ÚSchedulerNode.is_split_scan©  s|   € Ü˜$Ÿ)™)¤b×&7Ñ&7¼×9JÑ9JÐ%K×LÑLð 	
ØŒt�D—I‘I‹Ñ Ð!ó	
ÐLô ˜$Ÿ)™)¤R×%6Ñ%6Ó7÷ 
¼JØ�I‰I�N‰NœBŸL™Ló=
ð 	
rm   c                óJ   • [        U R                  [        R                  5      $ ry   ©r’   r•   r)   rÉ  rh   s    rj   rj  ÚSchedulerNode.is_template±  s   € Ü˜$Ÿ)™)¤R×%6Ñ%6Ó7Ð7rm   c                óp   • [        U R                  [        R                  5      (       a  U R                  $ S $ ry   r  rh   s    rj   r&  ÚSchedulerNode.get_template_node´  s'   € Ü& t§y¡y´"×2CÑ2C×DÑDˆt�y‰yÐNÈ$ÐNrm   c                óf   • U R                  5         U R                  5         U R                  U5        g ry   )r›  rü  r‹  )ri   Ú
index_varss     rj   ÚrunÚSchedulerNode.run·  s#   € Ø×"Ñ"Ô$Ø�‰ŒØ�‰�ZÕ rm   c                ó(  • U R                   n[        [        [        U5      5      [        [        [        U5      5      :X  d   e[	        [        [        R                  R                  U5      [        R                  R                  U5      5      5      nU$ ry   )	rÀ  ré   Úmapr²   ÚdictÚzipr  r  Úfrom_iterable)ri   r#  rç  r¾   s       rj   Úranges_from_index_varsÚ$SchedulerNode.ranges_from_index_vars¼  sp   € ð —‘ˆÜ”3”s˜E“?Ó#¤s¬3¬s°JÓ+?Ó'@Ó@Ð@Ð@ÜÜÜ—‘×-Ñ-¨jÓ9Ü—‘×-Ñ-¨eÓ4óó
ˆ
ð Ðrm   c                ó°  • U R                  U5      n [        R                  " [        [        R                  " 5       U5      5         [        R
                  R                  U 5         U R                  " U6   SSS5        SSS5        g! , (       d  f       N= f! , (       d  f       g= f! [         a"    [        R                  SU R                  5        e f = f)aª  
Generate code for this node using the provided index variables.

This method sets up the appropriate context for code generation, including
simplifying indexing expressions based on the variable ranges, and then
calls the node's body function with the index variables.

Args:
    index_vars: A sequence of sequences of sympy expressions representing
                the index variables for each dimension of the computation.
NzError in codegen for %s)r+  rW   Úset_ops_handlerrD   Úget_ops_handlerrU  Úset_current_noder  r¯  r°  Úfatalr•   )ri   r#  r¾   s      rj   r‹  ÚSchedulerNode.codegenÉ  s›   € ð ×0Ñ0°Ó<ˆ
ð	ä×!Ò!Ô"2´1×3DÒ3DÓ3FÈ
Ó"SÕTÜ—‘×)Ñ)¨$Õ/à—
’
˜JÑ'÷ 0÷ UÐTß/Õ/ú÷ UÕTûô ó 	Ü�I‰IÐ/°·±Ô;Øð	úsA   “3B) Á BÁ&BÁ6BÁ>B) Â
B	ÂBÂ
B&Â"B) Â&B) Â),Cc                óâ   • U(       a  U R                   O[        U R                   5      u  p#[        R                  " U R                  U[
        R                  R                  /[        U5      -  /S9$ )zL
Get the memory dependencies in either the pointwise or the reduction axes.
)Úhidden_args)	rÀ  r´   r(   rÏ  r  rô   ÚSÚZeror²   )ri   Ú	pointwiseÚ
keep_sizesÚignore_sizess       rj   Ú"pointwise_or_reduction_read_writesÚ0SchedulerNode.pointwise_or_reduction_read_writesà  sR   € ö 3< 4§;¢;ÄÈ$Ï+É+ÓAVÑ ˆ
Ü×/Ò/Ø�J‰J˜
´%·'±'·,±,°Ä#ÀlÓBSÑ1SÐ0Tñ
ð 	
rm   c                ó    • U R                  SS9$ )z8
Get the memory dependencies in the non-reduction axes.
T©r7  ©r:  rh   s    rj   rÛ  Ú#SchedulerNode.pointwise_read_writesë  s   € ð
 ×6Ñ6ÀÐ6ÐFÐFrm   c                ó    • U R                  SS9$ )z4
Get the memory dependencies in the reduction axes.
Fr=  r>  rh   s    rj   Úreduction_read_writesÚ#SchedulerNode.reduction_read_writesò  s   € ð
 ×6Ñ6ÀÐ6ÐGÐGrm   c                ó(  • U R                  5       (       a  g[        S U R                  5        5       5      (       a  g[        U R                  R
                  5      S:X  a³  [        U[        R                  5      (       a”  [        [        U R                  R
                  5      5      n[        U[        R                  5      (       d   S[        U5      < 35       eUR                  UR                  :H  =(       a    UR                  UR                  :H  $ g)NFc              3  ó@   #   • U  H  oR                  5       v •  M     g 7fry   )r>  r;  s     rj   rš   Ú,SchedulerNode.can_inplace.<locals>.<genexpr>ü  s   é € Ð?Ò,> S�‰× Ð Ò,>ùr7  r   ztype(write_dep)=)rj  rö   r—  r²   rº   r­  r’   r(   r2   r3  ÚiterrÀ   r½   rÂ   )ri   rt  Ú	write_deps      rj   ru  ÚSchedulerNode.can_inplaceù  sÑ   € Ø×Ñ×ÑØÜÑ?¨D×,<Ñ,<Ô,>Ó?×?Ñ?ØÜˆt×Ñ×&Ñ&Ó'¨1Ó,´Ø”l×,Ñ,÷2
ñ 2
ô œT $×"2Ñ"2×"9Ñ"9Ó:Ó;ˆIÜ˜i¬×)?Ñ)?×@Ñ@ÐWÐEUÄTÈ)Ã_ÑDVÐBWÓWÐ@Ø—>‘> Y§_¡_Ñ4×X¸¿¹È)Ï.É.Ñ9XÐXØrm   c                ó8  • [        5       n[        U R                  [        5      (       að  U R                  R	                  5        HÒ  nUR
                  S:X  d  M  UR                  S:X  d  M'  SUR                  ;   a  UR                  S   S:X  d0  [        UR                  5      S:X  d  Me  UR                  S   S:X  d  Mz  UR                  SUR                  ;   a  UR                  S   O)[        UR                  5      S:¼  a  UR                  S	   OS
5        MÔ     U$ )NÚcall_methodÚstoreÚmodeÚ
atomic_addrm  rŽ  r¼   r±   r   rµ  )r   r’   r  r>   r�   r1  r¨  r�  r²   rL  r  )ri   Úbuffers_store_as_atomic_addr•   s      rj   Ú_get_atomic_add_buffersÚ%SchedulerNode._get_atomic_add_buffers  sÓ   € ä7A³|Ð#Ü�d—j‘j¤(×+Ñ+ØŸ
™
×,Ñ,Ö.�à—G‘G˜}Õ,ØŸ™ wÕ.à 4§;¡;Ó.°4·;±;¸vÑ3FÈ,Ó3VÜ §	¡	›N¨aÕ/°D·I±I¸a±LÀLÕ4Pð 0×3Ñ3à! T§[¡[Ó0ð Ÿ™ FÒ+ä.1°$·)±)«nÀÓ.A˜dŸi™i¨šlÀröñ /ð +Ð*rm   c                ó|   >• U R                   b!  U R                   R                  S5      (       a  g[        TU ]  5       $ )NÚdevice_assert_asyncT)r  Úhas_opr¬  rx  ©ri   r¯  s    €rj   rx  ÚSchedulerNode.has_side_effects  s5   ø€ ð �:‰:Ñ! d§j¡j×&7Ñ&7Ð8M×&NÑ&NØÜ‰wÑ'Ó)Ð)rm   )r  rÀ  r©   )r(  r'  r•   z+Union[ir.ComputedBuffer, ir.TemplateBuffer]r‹   rs  ©NN)rÆ  ú*Optional[tuple[dict[Any, Any], list[Any]]]rÇ  zOptional[Callable[_P, _T]]r‹   rs  )rÆ  rW  rÇ  zOptional[Callable[..., Any]]r‹   rs  )rÈ  rx   rà  rx   r‹   rs  )rè  úSequence[int]r‹   rs  rr  ©r‹   r\   )rþ  r!  rÿ  r!  r‹   rs  r=  rp  )r‹   úSequence[Sequence[sympy.Expr]]rt  rH  )r#  úSequence[sympy.Expr]r‹   rs  )r#  rZ  r‹   zdict[sympy.Expr, sympy.Expr])r#  rZ  r‹   rs  rE  )r7  rx   r‹   rŠ  )r‹   rŠ  rD  r@  )$r{   r|   r}   r~   r#  r   r”  rÂ  rÔ  râ  ré  ró  rö  rú  rý  r  rÒ  r®  rð  r”   rd  rg  rj  r&  r$  r+  r‹  r:  rF   rÛ  rA  ru  rO  rx  r�   rº  r»  s   @rj   r“   r“   Ó  s»  ø‡ ñð
 -Ó,ØƒOðàðð :ðð 
÷	ð RVØ@Dðà$Nðð $>ðð 
õ	ðF RVØBFð
à$Nð
ð $@ð
ð 
õ	
ð;Øð;Ø8<ð;à	ô;ô<QôIôô"ðPØðPØ),ðPà	ôPô"
QðØ!ðØ.7ðà	ôô. ô,ô
ô7ô
ô8ôOô!ð
Ø8ðà	%ôôð0 !%ð	
Øð	
à	 õ	
ð óGó ðGð óHó ðHôð ó+ó ð+ð& ö*ó ö*rm   r“   c           	     óz  ^ • T R                   nT R                  [        R                  R	                  U Vs/ s H  o"R
                  PM     sn5      5        [        U 4S j[        R                  " U Vs/ s H  o"R                  PM     sn6  5       5      T R
                  R                  -
  T l        g s  snf s  snf )Nc              3  óh   >#   • U  H'  nUR                   TR                  5       ;  d  M#  Uv •  M)     g 7fry   ©r¼   r=  )r˜   rÆ   Úgroup_snodes     €rj   rš   Ú2refresh_group_node_dependencies.<locals>.<genexpr>+  s/   øé € ð 
âP�Ø�x‰x˜{×;Ñ;Ó=Ñ=÷ ‰CÚPùó   ƒ"2©	2)
rÁ   rÜ  r(   Ú
ReadWritesÚ
merge_listrº   r   ÚunionrŒ  r­  )r_  rÁ   r™  s   `  rj   Úrefresh_group_node_dependenciesre  "  s¢   ø€ ð ×Ñ€FØ×ÑÜ×Ñ×*Ñ*Á6Ó+JÂ6¸a¯M¬MÁ6Ñ+JÓKôô
 	ô 
ä!×'Ò'ÉÓ)OÊÀ1×*>Ô*>ÉÑ)OÑPó
ó 	
ð
 ×
!Ñ
!×
(Ñ
(ñ	)ð Õ"ùò ,Kùò *Ps   ¶B3Á4B8r'  c                óü  • [        U [        [        45      (       d   eX l        Xl        S U l        [        R                  " U Vs/ s H  o3R                  c  M  UR                  PM     sn6 U l        [        U 5        [        S U R                   5       5      U l        [        S U R                   5       5      U l        U R                  5        Vs0 s H  oDR                  5       U_M     snU l        g s  snf s  snf )Nc              3  ó8   #   • U  H  oR                   v •  M     g 7fry   ©r  ©r˜   r™  s     rj   rš   Ú"init_group_node.<locals>.<genexpr>C  ó   é € ÐHÒ5G°§¦Ò5GùrÚ  c              3  ó8   #   • U  H  oR                   v •  M     g 7fry   )r€  ri  s     rj   rš   rj  D  rk  rÚ  )r’   r¿   ÚGroupedSchedulerNoderÁ   r(  r•   r   rd  rï   re  rä  r  r  r€  r—  r0  r‡  )r_  r(  rÁ   r™  rÄ   s        rj   Úinit_group_nodern  4  s×   € ô
 �kÔ$6Ô8LÐ#M×NÑNÐNÐNØÔØ%ÔØ€KÔÜ&×,Ò,Ù%Ó	Ašv˜!¯©‹+ˆ!�+Œ+™vÑ	Að€KÔô $ KÔ0äÑH°[×5GÒ5GÓHÓH€KÔÜÑH°[×5GÒ5GÓHÓH€KÔà'2×'>Ñ'>Ô'@ó#Ú'@ �‰‹˜ÒÑ'@ñ#€KÕùò 
Bùò#s   ÁC4ÁC4ÃC9c                  ó  ^ • \ rS rSr% SrS\S'   \      S#S j5       rS$S jrS%S jr	\
S&S j5       r      S'S	 jrS(U 4S
 jjr\
S)S j5       rS)S jr\
S*S j5       rS+S jrS)S jrS)S jr      S,U 4S jjr\
S*S j5       r\
S*S j5       rS-S jrS)S jr\
S.S j5       r\
S.S j5       r\
S.S j5       r\
S.S j5       r\
S/S j5       rS0S jr\
S.S j5       rS1S jr S2S jr!S3S jr"S)S  jr#\
S.U 4S! jj5       r$S"r%U =r&$ )4r¿   iJ  zÖ
This is a "fake" scheduler node that represents a group of scheduler nodes
that are meant to be fused together. The way it does this is by maintaining
its unmet dependencies as the union of its constituent nodes.
rI  rÁ   c           	     ó  • UR                   UR                   L d   e[        U[        [        45      (       d   eUR	                  5       (       GaË  [        U[
        5      (       Gaµ  [        UR                  [        5      (       d   e[        UR                  R                  5      S:X  d   e[        [        [        UR                  R                  5      5      [        5      (       d   e[        [        UR                  R                  5      5      R                  nUR                  5        Vs/ s H  oDR	                  5       (       d  M  UPM     nn[        U5      S:X  d   eUS   n[        UR                  R                  5      S:X  d   e[        [        UR                  R                  5      5      n[        U[         5      (       d   e[#        [!        X7R$                  UR&                  UR(                  UR*                  5      /5      UR                  l
        O[        U[        [        45      (       d   e[-        [.        R0                  " UR                  5       UR                  5       5      5      nU " UR                   U5      $ s  snf )Nr   r   )r(  r’   r“   r¿   rj  rë  r•   r;   r²   rº   r­  r3  rF  r3   r¼   r�   r2   r   r½   Ú	var_namesrÂ   rL  r  r  r  )	rp   r…   r†   r¼   r•   Útemplate_nodesr8  Úwriter5  s	            rj   rq   ÚFusedSchedulerNode.fuseS  sï  € ð �‰ %§/¡/Ò1Ð1Ð1Ü˜%¤-Ô1CÐ!D×EÑEÐEÐEØ×Ñ×Ò¤:¨eÔ5N×#OÒ#Oô ˜eŸj™j¬+×6Ñ6Ð6Ð6Ü�u×(Ñ(×/Ñ/Ó0°AÓ5Ð5Ð5Üœd¤4¨×(9Ñ(9×(@Ñ(@Ó#AÓBÄG×LÑLÐLÐLÜœ˜U×.Ñ.×5Ñ5Ó6Ó7×<Ñ<ˆDØ/4¯©Ô/@ÓWÒ/@ t×DTÑDT×DVŸdÑ/@ˆNÐWÜ�~Ó&¨!Ó+Ð+Ð+Ø*¨1Ñ-ˆMÜ�}×0Ñ0×7Ñ7Ó8¸AÓ=Ð=Ð=Üœ˜m×7Ñ7×>Ñ>Ó?Ó@ˆEÜ˜e¤Y×/Ñ/Ð/Ð/Ü'1äØŸk™k¨5¯?©?¸E¿J¹JÈÏ
É
óðó(ˆE×ÑÕ$ô ˜e¤mÔ5GÐ%H×IÑIÐIÐIÜ”Y—_’_ U§_¡_Ó%6¸¿¹Ó8IÓJÓKˆÙ�5—?‘? EÓ*Ð*ùò! Xs   Ä,JÅJc                ó¨   • U R                    HA  n[        U[        5      (       d   eUR                  5       (       d   eUR	                  5         MC     U $ ry   )rÁ   r’   r“   r”   rö  ©ri   r™   s     rj   rö  Ú,FusedSchedulerNode.extract_pw_from_reductionu  sK   € Ø—{”{ˆGÜ˜g¤}×5Ñ5Ð5Ð5Ø×'Ñ'×)Ñ)Ð)Ð)Ø×-Ñ-Ö/ñ #ð ˆrm   c                óx   • U R                    H*  n[        U[        5      (       d   eUR                  5         M,     g ry   )rÁ   r’   r“   ró  rv  s     rj   ró  Ú(FusedSchedulerNode.swap_pw_red_dimension|  s/   € Ø—{”{ˆGÜ˜g¤}×5Ñ5Ð5Ð5Ø×)Ñ)Ö+ò #rm   c                ó�   • [        [        S S U R                  5        5       5      5      n[        U5      S:X  a  g [	        U5      nU$ )Nc              3  óš   #   • U  HA  nUR                  5       (       d  UR                  5       (       d  M/  UR                  5       v •  MC     g 7fry   ©rj  rm  r   r5  s     rj   rš   Ú4FusedSchedulerNode.estimate_flops.<locals>.<genexpr>‡  ó=   é € ð â 0˜Ø×'Ñ'×)Ñ)¨T¯^©^×-=ó *�D×'Ñ'×)Ð)Ú 0ùó
   ‚.A´Ar   ©r  Úfilterr�   r²   ré   ©ri   Úfpsr  s      rj   r   Ú!FusedSchedulerNode.estimate_flops�  óK   € ô ÜØñà $§¡Ô 0óóó	
ˆô ˆs‹8�q‹=ØÜ�#‹hˆØˆ
rm   c                ó  • U R                  5       (       a  gSnU R                   Hh  n[        U[        5      (       d   eUb<  [	        U5      [	        UR
                  S   5      :w  a  [        R                  S5          gUR
                  S   nMj     SnUc   e[        U5      UR                  s=:X  a  UR                  :X  a  O  OUR                  U5      nU(       d%  [        R                  SU R                  5       5        g[        =R                  S-  sl        [        R                  SU R                  5       U5        U R                   H+  n[        U[        5      (       d   eUR                  U5        M-     [        U 5        g)	z0
Return true if a loop reordering is performed.
FNr   z1Can not reorder fused node due to different sizeszODont reordering fused node %s because we can not decide the suitable loop orderr   z-Reorder loops for fused node %s with order %sT)rj  rÁ   r’   r“   r³   rÀ  r  r„  r²   r  r  r0  r*   r  ré  re  )ri   rÐ  rÑ  r	  r\  rè  s         rj   rÒ  Ú,FusedSchedulerNode.reorder_loops_by_dep_pair“  sK  € ð ×Ñ×ÑàØˆ
Ø—[”[ˆEÜ˜e¤]×3Ñ3Ð3Ð3ØÑ%¬%°
Ó*;¼uÀUÇ\Á\ÐRSÁ_Ó?UÓ*UÜ!×'Ñ'ØGôñ ØŸ™ a™ŠJñ !ð ˆ	àÑ%Ð%Ð%Üˆz‹?˜h×/Ñ/ÕE°9×3EÑ3EÖEØ ×;Ñ;¸IÓFˆIæÜ×#Ñ#ØaØ—‘“ôð ä×#Ò# qÑ(Õ#Ü×ÑØ;¸T¿]¹]»_Èiô	
ð —[”[ˆEÜ˜e¤]×3Ñ3Ð3Ð3Ø×&Ñ& yÖ1ñ !ô 	(¨Ô-Ørm   c                ó~   >• [         TU ]  U5        [        XU5        / U l        [	        US S9R
                  U l        g )Nc                ó4   • [        U R                  5       5      $ ry   )r!  r”   rQ  s    rj   r‘  Ú-FusedSchedulerNode.__init__.<locals>.<lambda>Á  s   € ¬s°1·>±>Ó3CÔ/Drm   rŒ  )r¬  r”  rn  r-  r  r©   )ri   r(  rÁ   r¯  s      €rj   r”  ÚFusedSchedulerNode.__init__½  s6   ø€ Ü‰Ñ˜Ô#Ü˜¨Ô0Ø%'ˆŒ
Ü˜Ñ%DÑE×KÑKˆ�
rm   c                ó~   • SR                  U R                   Vs/ s H  oR                  5       PM     sn5      $ s  snf ©NÚ_©r  rÁ   r0  ©ri   r™  s     rj   r0  ÚFusedSchedulerNode.get_nameÃ  ó+   € à�x‰x¨t¯{ª{Ó;ª{¨!Ÿ™ž©{Ñ;Ó<Ð<ùÒ;ó   š:c                ó<   • U R                   S   R                  5       $ rÑ   ©rÁ   r0  rh   s    rj   r1  Ú!FusedSchedulerNode.get_first_nameÇ  ó   € Ø�{‰{˜1‰~×&Ñ&Ó(Ð(rm   c                ó‚   • [         R                  " U R                   Vs/ s H  oR                  5       PM     sn6 $ s  snf ry   ©r   rd  rÁ   r=  r�  s     rj   r=  Ú#FusedSchedulerNode.get_buffer_namesÊ  ó0   € ä×ÒÀÇÂÓ!LÂ¸1×"4Ñ"4Ö"6ÁÑ!LÐMÐMùÒ!Ló   Ÿ<c                ón   • / nU R                    H"  nUR                  UR                  5       5        M$     U$ ry   ©rÁ   r  r—  ©ri   rC  r•   s      rj   r—  ÚFusedSchedulerNode.get_outputsÎ  ó/   € Ø(*ˆØ—K”KˆDØ�M‰M˜$×*Ñ*Ó,Ö-ñ  àˆrm   c           
     ó†  • [        U R                  5       VVs/ s H+  u  pU R                  5        SU SUR                  5        3PM-     nnnU R                  S   R                  nUb  UR                  U R                  5       5        [        R                  " SR                  U5      R                  5       S5      $ s  snnf )Nz.snodes[z] =
r   r¥  r�  )r4  rÁ   r0  rE  r•   r  r¹  r“  rA  r  r²  )ri   r1  r•   r  s       rj   r®  Ú"FusedSchedulerNode.debug_str_extraÔ  s§   € ô % T§[¡[Ô1ô
â1‘�ð �}‰}‹Ð˜x¨ s¨%°·±Ó0@Ð/AÓBÙ1ð 	ñ 
ð �{‰{˜1‰~×"Ñ"ˆØÑØ�L‰L˜×3Ñ3Ó5Ô6ä�Š˜tŸy™y¨Ó/×6Ñ6Ó8¸&ÓAÐAùó
s   ™2B=c                ól   • U R                    Vs/ s H  oR                  5       PM     nnU  SU 3$ s  snf )Nz
, snodes: )rÁ   rÈ  )ri   r•   Ú
snodes_strs      rj   rÈ  Ú"FusedSchedulerNode.debug_str_shortß  s8   € Ø9=¿ºÓEº°×*Ñ*Ö,¹ˆ
ÐEØ��z * Ð.Ð.ùò Fs   �1c                óÈ   >• [         TU ]  X5        [        5       n[        U R                  5       H/  nUR                  X5        UR                  UR                  5        M1     g ry   )r¬  rù  r   r´   rÁ   Úupdater~  )ri   r÷  ró  r•   r¯  s       €rj   rù  Ú!FusedSchedulerNode.set_last_usageã  sQ   ø€ ô
 	‰ÑÐ2ÔGô 0:«|ÐÜ˜TŸ[™[Ö)ˆDØ×ÑÐ 3ÔHØ×&Ñ& t§¡Ö7ò *rm   c                ó‚   • [         R                  " U R                   Vs/ s H  oR                  5       PM     sn6 $ s  snf ry   )r   rd  rÁ   rÊ   r�  s     rj   rÊ   Ú$FusedSchedulerNode.used_buffer_namesð  s0   € ä×ÒÀÇÂÓ!MÂ¸A×"5Ñ"5Ö"7ÁÑ!MÐNÐNùÒ!Mrœ  c                ó‚   • [         R                  " U R                   Vs/ s H  oR                  5       PM     sn6 $ s  snf ry   )r   rd  rÁ   rö  r�  s     rj   rö  Ú/FusedSchedulerNode.used_or_aliased_buffer_namesô  s5   € ä×ÒØ8<¿ºÓDº°1×,Ñ,Ö.¹ÑDð
ð 	
ùÚDrœ  c                ó   • U R                   $ ry   rØ  rh   s    rj   r�   ÚFusedSchedulerNode.get_nodesú  r  rm   c                óT   • [        U 5      R                   SU R                  5        S3$ )Nz(nodes=rœ  r�  rh   s    rj   rž  ÚFusedSchedulerNode.__repr__ý  s'   € Ü�t“*×%Ñ%Ð& g¨d¯m©m«oÐ->¸aÐ@Ð@rm   c                ó:   • [        S U R                   5       5      $ )Nc              3  ó@   #   • U  H  oR                  5       v •  M     g 7fry   )r”   ri  s     rj   rš   Ú2FusedSchedulerNode.is_reduction.<locals>.<genexpr>  s   é € Ð9ª[¨—>‘>×#Ð#ª[ùr7  ©rö   rÁ   rh   s    rj   r”   ÚFusedSchedulerNode.is_reduction   s   € äÑ9¨T¯[ª[Ó9Ó9Ð9rm   c                ó:   • [        S U R                   5       5      $ )Nc              3  ó@   #   • U  H  oR                  5       v •  M     g 7fry   )rd  ri  s     rj   rš   Ú6FusedSchedulerNode.is_native_matmul.<locals>.<genexpr>  s   é € Ð=²¨A×%Ñ%×'Ð'²ùr7  rµ  rh   s    rj   rd  Ú#FusedSchedulerNode.is_native_matmul  s   € äÑ=°·²Ó=Ó=Ð=rm   c                ó:   • [        S U R                   5       5      $ )Nc              3  ó@   #   • U  H  oR                  5       v •  M     g 7fry   )rg  ri  s     rj   rš   Ú3FusedSchedulerNode.is_split_scan.<locals>.<genexpr>
  s   é € Ð:ªk¨—?‘?×$Ð$ªkùr7  rµ  rh   s    rj   rg  Ú FusedSchedulerNode.is_split_scan  s   € äÑ:¨d¯kªkÓ:Ó:Ð:rm   c                ó:   • [        S U R                   5       5      $ )Nc              3  ó@   #   • U  H  oR                  5       v •  M     g 7fry   r0  ri  s     rj   rš   Ú1FusedSchedulerNode.is_template.<locals>.<genexpr>  s   é € Ð8ªK q—=‘=—?�?ªKùr7  rµ  rh   s    rj   rj  ÚFusedSchedulerNode.is_template  s   € äÑ8¨D¯KªKÓ8Ó8Ð8rm   c                óx   • U R                    H*  nUR                  5       (       d  M  UR                  5       s  $    g ry   )rÁ   rj  r&  ©ri   r•   s     rj   r&  Ú$FusedSchedulerNode.get_template_node  s3   € à—K”KˆDØ×Ñ×!Ó!Ø×-Ñ-Ó/Ò/ñ  ð rm   c                ó    • U R                   S   $ rÑ   )r©   rh   s    rj   rî   ÚFusedSchedulerNode.get_device  s   € Ø�z‰z˜!‰}Ðrm   c                ó:   • [        S U R                   5       5      $ )Nc              3  ó@   #   • U  H  oR                  5       v •  M     g 7fry   )ré  ri  s     rj   rš   Ú>FusedSchedulerNode.has_aliasing_or_mutation.<locals>.<genexpr>  s   é € ÐEº°A×-Ñ-×/Ð/ºùr7  rµ  rh   s    rj   ré  Ú+FusedSchedulerNode.has_aliasing_or_mutation  s   € äÑE¸¿ºÓEÓEÐErm   c                ó   • [         ery   ©ÚNotImplementedError)ri   rÞ  s     rj   rß  Ú'FusedSchedulerNode.update_mutated_names   ó   € Ü!Ð!rm   c                ó   • [         ery   rÍ  )ri   r¼   s     rj   rä  ÚFusedSchedulerNode.add_fake_dep#  rÐ  rm   c                ó   • [         ery   rÍ  rs  s     rj   ru  ÚFusedSchedulerNode.can_inplace&  rÐ  rm   c                óX  • U R                  5       nSR                  S U R                   5       5      n[        5       nUR	                  U S[        U 5      R                   SU SU S[        U R                  R                  5       SU S[        U R                  5       SU S	[        U R                  R                  U R                  -
  5       SU S
35        UR                  5          U R                  5        H"  nUR	                  UR                  5       5        M$     SSS5        UR                  S5         UR	                  U R!                  5       5        UR)                  5       R+                  5       $ ! , (       d  f       N]= f! ["         a    [$        R'                  SSS9   NOf = f)r¡  r:  c              3  óL   #   • U  H  n[        U5      R                  v •  M     g 7fry   )rÀ   r{   rC  s     rj   rš   Ú/FusedSchedulerNode.debug_str.<locals>.<genexpr>,  s   é € ÐFº+°Q¤ Q£× 0Ö 0º+ùs   ‚"$r9  r¢  r£  r¤  r¥  r¦  r§  z.outputs = [
            Nr;  r¨  Tr©  )r0  r  rÁ   rO   r«  rÀ   r{   r?  rº   r­  rŒ  r»   rA  r—  rE  r<  r®  r¯  r°  r±  rB  r²  )ri   r¼   Únode_typestrrÄ   rÌ   s        rj   rE  ÚFusedSchedulerNode.debug_str)  sx  € à�}‰}‹ˆØ—x‘xÑF¸$¿+º+ÓFÓFˆÜÓˆØ�
‰
à€€bŒˆd‹×	Ñ	Ð˜Q˜|˜nð -Ø€€j”˜×)Ñ)×0Ñ0Ó1Ð2ð 3Ø€ÐœW T×%<Ñ%<Ó=Ð>ð ?Ø€Ðœ7 4×#3Ñ#3×#9Ñ#9¸D×<SÑ<SÑ#SÓTÐUð VØ€ð ðô	
ð �Z‰Z�\Ø×'Ñ'Ö)�Ø—
‘
˜3Ÿ=™=›?Ö+ñ *÷ ð 	�‰�cÔð	HØ�J‰J�t×+Ñ+Ó-Ô.ð �‰Ó ×'Ñ'Ó)Ð)÷ �\ûô ó 	HÜ�K‰KÐ7À$ˆKÓGð	Hús   Ã)7E7Ä:F Å7
FÆF)Æ(F)c                ór   >• U R                   b  [        S U R                    5       5      $ [        TU ]  5       $ )Nc              3  ó@   #   • U  H  oR                  5       v •  M     g 7fry   )rx  r5  s     rj   rš   Ú6FusedSchedulerNode.has_side_effects.<locals>.<genexpr>F  s   é € ÐGº;°4×,Ñ,×.Ð.º;ùr7  )rÁ   rö   r¬  rx  rT  s    €rj   rx  Ú#FusedSchedulerNode.has_side_effectsC  s0   ø€ à�;‰;Ñ"ÜÑG¸4¿;º;ÓGÓGÐGÜ‰wÑ'Ó)Ð)rm   )r©   r-  ©r…   r\   r†   r\   r‹   r¿   rY  rr  rF  r=  )r(  r'  rÁ   rI  r‹   rs  rp  r@  ©r‹   r„  r?  rC  rt  rH  )r‹   útorch.devicer>  )r¼   r1   r‹   rs  rD  )'r{   r|   r}   r~   r#  r   r€   rq   rö  ró  rF   r   rÒ  r”  r0  r1  r=  r—  r®  rÈ  rù  rÊ   rö  r�   rž  r”   rd  rg  rj  r&  rî   ré  rß  rä  ru  rE  rx  r�   rº  r»  s   @rj   r¿   r¿   J  sµ  ø‡ ñð $Ó#àð+Ø%ð+Ø.?ð+à	ó+ó ð+ôBô,ð
 óó ðð"(Ø!ð(Ø.7ð(à	ô(÷TLð ó=ó ð=ô)ð óNó ðNôô	Bô/ð8Ø#2ð8ØHVð8à	÷8ð óOó ðOð ó
ó ð
ô
ôAð ó:ó ð:ð ó>ó ð>ð ó;ó ð;ð ó9ó ð9ð óó ðôð óFó ðFô
"ô"ô"ô*ð4 ö*ó ö*rm   r¿   c                  óV   ^ • \ rS rSrSU 4S jjr      SS jrS	S jrS	S jrSrU =r	$ )
ÚFusedMixOrderReductionsiJ  c                ól  >• [         R                  U5      (       d  [         R                  U5      (       d   eX!p!Xl        X l        [        TU ]  UR                  [        UR                  5       5      [        UR                  5       5      -   5        [         R                  U R                  5      U l
        g ry   )rŽ   rñ   r…   r†   r¬  r”  r(  r  r�   rÙ   Únumel)ri   r…   r†   r¯  s      €rj   r”  Ú FusedMixOrderReductions.__init__K  s…   ø€ Ü ×3Ñ3°E×:Ñ:Ü$×7Ñ7¸×>Ñ>Ð>Ð>Ø �5àŒ
ØŒ
Ü‰ÑØ�O‰OœT %§/¡/Ó"3Ó4´t¸E¿O¹OÓ<MÓ7NÑNô	
ô '×0Ñ0°·±Ó<ˆ�
rm   c           	     óH  • [        U[        5      (       a   e[        U[        5      (       a   eU R                  R                  XSS9(       d  g[        R                  U5      (       a  [        R                  U5      (       d  gSS jn    SS jnU(       a/  U" X45      U" U5      -  (       d  U" U5      U" X45      -  (       a  gUR                  5       (       + =(       d@    [        R                  " [        U R                  R                  XSS95      U R                  :¬  $ )zô
node1 is from the current mix order reduction; node2 is another node we want to fuse in.

other_nodes are passed in to check if fusion will introduce producer/consumer relationship
between the inner and outer reduction. If yes, we don't fuse.
F©Úallow_mix_order_reductionc                óB   • [        5       nUR                  " S U  5       6 $ )Nc              3  ó8   #   • U  H  oR                   v •  M     g 7fry   )rï   rC  s     rj   rš   ÚTFusedMixOrderReductions.sub_node_can_fuse.<locals>._get_ancestors.<locals>.<genexpr>u  s   é € Ð:²E¨qŸ{ž{²EùrÚ  ©r   rd  ©r5  rÌ   s     rj   Ú_get_ancestorsÚAFusedMixOrderReductions.sub_node_can_fuse.<locals>._get_ancestorss  s   € Ü“,ˆCØ—9’9Ñ:±EÓ:Ð;Ð;rm   c                óB   • [        5       nUR                  " S U  5       6 $ )Nc              3  ó@   #   • U  H  oR                  5       v •  M     g 7fry   )rð   rC  s     rj   rš   ÚZFusedMixOrderReductions.sub_node_can_fuse.<locals>._get_operation_names.<locals>.<genexpr>{  s   é € ÐFÂ¸1×4Ñ4×6Ð6Âùr7  rì  rí  s     rj   Ú_get_operation_namesÚGFusedMixOrderReductions.sub_node_can_fuse.<locals>._get_operation_namesw  s    € ô “,ˆCØ—9’9ÑFÁÓFÐGÐGrm   )Úcount_bytes)r5  útuple[BaseSchedulerNode, ...]r‹   r}  )r’   râ  r(  rþ   rŽ   rñ   r”   ÚtypingÚcastr!  Úscore_fusion_memoryrä  )ri   r…   r†   Úother_nodesrî  ró  s         rj   Úsub_node_can_fuseÚ)FusedMixOrderReductions.sub_node_can_fuseW  s  € ô ˜eÔ%<×=Ñ=Ð=Ð=Ü˜eÔ%<×=Ñ=Ð=Ð=ð
 �~‰~×&Ñ& uÈuÐ&ÖUØô ×/Ñ/Ø÷
ñ 
ä#×6Ñ6°u×=Ñ=Øô	<ð	HØ0ð	Hàô	Hö Ù ˜~Ó.Ñ1EÀkÓ1R×RÙ˜{Ó+Ñ.BÀEÀ>Ó.R×Ràð ×"Ñ"Ó$Ô$÷ Ü�{Š{Ü�T—^‘^×7Ñ7¸ÐRWÐ7ÐXóð �z‰zñð	
rm   c                ó¼  • [        U[        5      (       dU  U R                  U R                  XR                  45      =(       d'    U R                  U R                  XR                  45      $ U R                  U R                  UR                  U R                  UR                  45      =(       a/    U R                  U R                  UR                  [        5       5      $ ry   )r’   râ  rû  r…   r†   r³   ©ri   Úothers     rj   Úcan_fuse_withÚ%FusedMixOrderReductions.can_fuse_with‹  s§   € Ü˜%Ô!8×9Ñ9Ø×)Ñ)Ø—
‘
˜E§J¡J =ó÷ Jà×'Ñ'¨¯
©
°E¿J¹J¸=ÓIðJð ×)Ñ)Ø—
‘
˜EŸK™K¨$¯*©*°e·k±kÐ)Bó÷ Kà×(Ñ(¨¯©°U·[±[Ä%Ã'ÓJðKrm   c                ób  • U R                   R                  5       nU R                  R                  U5      n[	        U[
        5      (       aW  UR                  U R                   UR                   5      nUR                  U R                  UR                  5      n[        XE5      $ U R                  U R                   XR                  45      (       a1  UR                  U R                   U5      n[        X`R                  5      $ UR                  U R                  U5      n[        U R                   U5      $ ry   )	r…   rî   r(  rÌ  r’   râ  rq   r†   rû  )ri   rÿ  r[  ÚbackendÚfused_node1Úfused_node2rƒ  s          rj   Ú	fuse_withÚ!FusedMixOrderReductions.fuse_with—  sÖ   € Ø—‘×&Ñ&Ó(ˆØ—.‘.×,Ñ,¨VÓ4ˆä�eÔ4×5Ñ5Ø!Ÿ,™, t§z¡z°5·;±;Ó?ˆKØ!Ÿ,™, t§z¡z°5·;±;Ó?ˆKÜ*¨;ÓDÐDà×%Ñ% d§j¡j°%¿*¹*¸×GÑGØ$Ÿ\™\¨$¯*©*°eÓ<�
Ü.¨z¿:¹:ÓFÐFà$Ÿ\™\¨$¯*©*°eÓ<�
Ü.¨t¯z©z¸:ÓFÐFrm   )r…   r†   rä  rŠ  )r…   r\   r†   r\   rú  rö  )rÿ  r\   )
r{   r|   r}   r~   r”  rû  r   r  r�   rº  r»  s   @rj   râ  râ  J  s<   ø† ÷
=ð2
à ð2
ð !ð2
ð 3ô	2
ôh
K÷Gò Grm   râ  c                  óz  ^ • \ rS rSr% Sr    SS jr    SS jr\SS j5       r\      SS j5       r	   S             SU 4S jjjr
\    SS j5       r\    SS	 j5       r\rS
\S'   \    SS j5       r\    SS j5       rSS jrSS jrS S jrS!S jrS"S jrS#S jr    S$S jrSrU =r$ )%ÚForeachKernelSchedulerNodei¨  zŽ
This is a schedular node that consists of a set of scheduler nodes that
has no data dependencies among them and can be executed in parallel.
c                ó¬   • UR                  5        H@  nUR                  5       U R                  ;   d  M#  U R                  UR                  5          s  $    g ry   )r—  r0  Úread_to_node)ri   ÚproducerrÄ   s      rj   Úget_consumer_subnode_forÚ3ForeachKernelSchedulerNode.get_consumer_subnode_for®  sG   € ð ×'Ñ'Ö)ˆCØ�|‰|‹~ ×!2Ñ!2Õ2Ø×(Ñ(¨¯©«Ñ8Ò8ñ *ð rm   c                ó´  • [         [           " 5       nUR                  R                   H‰  nUR                  U R
                  R                  ;  a  M)  U R
                  R                  UR                     R                  5       nX@R                  ;   d  Mk  UR                  U R                  U   5        M‹     [        U5      S:X  a  [        [        U5      5      $ g ©Nr   )r   r\   rº   r»   r¼   r(  rX  r2  Úname_to_noder  r²   r3  rF  )ri   ÚconsumerÚ	producersÚrdÚ	node_names        rj   Úget_producer_subnode_forÚ3ForeachKernelSchedulerNode.get_producer_subnode_for·  s¥   € ô Ô0Ò1Ó3ˆ	Ø×&Ñ&×,Ô,ˆBØ�w‰w˜dŸn™n×8Ñ8Ó8ÙàŸ™×2Ñ2°2·7±7Ñ;×LÑLÓNˆIØ×-Ñ-Õ-Ø—‘˜d×/Ñ/°	Ñ:Ö;ñ -ô ˆy‹>˜QÓÜœ˜Y›Ó(Ð(àrm   c                óø  ^• [        TU5      nTR                  5       (       aÁ  UR                  5       (       a¬  [        R                  " [        T5      m[        R                  " [        U5      n[        TR                  5      [        UR                  5      :H  nU(       d  U" S5        U=(       a3    [        U4S j[        TR                  UR                  5       5       5      $ UR                  5       (       ar  TR                  5       (       a	  U" S5        g[        R                  " [        U5      nUR                  T5      nUb  UR                  R                  TU5      $ U" S5        gTR                  5       (       aq  UR                  5       (       a	  U" S5        g[        R                  " [        T5      mTR                  U5      nUb  TR                  R                  Xb5      $ U" S5        g[        S5      e)	Nzforeach do not have same lengthc              3  ó^   >#   • U  H"  u  pTR                   R                  X5      v •  M$     g 7fry   )r(  rþ   )r˜   ÚlÚrr  s      €rj   rš   Ú6ForeachKernelSchedulerNode.can_fuse.<locals>.<genexpr>Ó  s.   øé € ð )âA‘D�Að ×"Ñ"×+Ñ+¨A×1Ð1ÚAùó   ƒ*-zXcandidate producer is a reduction, foreach ops cannot be fused with reductions currentlyFz5candidate producer is not dep of any foreach consumerzXcandidate consumer is a reduction, foreach ops cannot be fused with reductions currentlyz5candidate consumer has no dep in any foreach producerzXAt least one node passed to ForeachKernelSchedulerNode.can_fuse should be a foreach node)r{  rp  r÷  rø  r	  r²   rÁ   rœ   r)  r”   r  r(  rþ   r  r  )rp   r  r  ÚwhyÚforeach_matchÚconsumer_subnodeÚproducer_subnodes    `     rj   rþ   Ú#ForeachKernelSchedulerNode.can_fuseÊ  s®  ø€ ä˜ (Ó+ˆØ×Ñ× Ñ  X×%8Ñ%8×%:Ñ%:Ü—{’{Ô#=¸xÓHˆHÜ—{’{Ô#=¸xÓHˆHÜ §¡Ó0´C¸¿¹Ó4HÑHˆMÞ ÙÐ5Ô6Ø ÷ ¤Sô )ä §¡°·±ÔAó)ó &ð ð × Ñ ×"Ñ"Ø×$Ñ$×&Ñ&ÙØnôð ä—{’{Ô#=¸xÓHˆHØ'×@Ñ@ÀÓJÐØÑ+Ø×)Ñ)×2Ñ2°8Ð=MÓNÐNáÐGÔHØà× Ñ ×"Ñ"Ø×$Ñ$×&Ñ&ÙØnôð ä—{’{Ô#=¸xÓHˆHØ'×@Ñ@ÀÓJÐØÑ+Ø×)Ñ)×2Ñ2Ð3CÓNÐNáÐGÔHØäØfó
ð 	
rm   c           	     ó`  • UR                  5       (       d  UR                  5       (       d   eUR                  5       (       a4  [        R                  " [        U5      nUR                  nUR
                  nO3[        R                  " [        U5      nUR                  nUR
                  nS nS nUR                  5       (       a”  UR                  5       (       a  [        R                  " [        U5      n[        R                  " [        U5      n[        UR                  UR                  5       VVs/ s H  u  px[        R                  Xx5      PM     n	nnGO?UR                  5       (       a…  [        R                  " [        U5      nUR                  U5      n
/ n	UnS nUR                   HB  nXºL a*  [        R                  X²5      nUnU	R                  U5        M1  U	R                  U5        MD     O¥UR                  5       (       a…  [        R                  " [        U5      nUR                  U5      n/ n	UnS nUR                   HB  nX½L a*  [        R                  X5      nUnU	R                  U5        M1  U	R                  U5        MD     O[        S5      eU " UR                  U	UUUUS9$ s  snnf )NzTAt least one node passed to ForeachKernelSchedulerNode.fuse should be a foreach node)Úuse_custom_partition_algoÚprev_node_1Úprev_node_2Úenable_autotune)rp  r÷  rø  r	  r$  r'  r)  rÁ   r¿   rq   r  rË   r  r  r(  )rp   r  r  r$  r'  r%  r&  r  r  Úfused_nodesr!  r•   Únew_noder   s                 rj   rq   ÚForeachKernelSchedulerNode.fuseù  s\  € ð ×"Ñ"×$Ñ$¨×(;Ñ(;×(=Ñ(=Ð=Ð=Ø×Ñ× Ñ Ü—{’{Ô#=¸xÓHˆHØ(0×(JÑ(JÐ%Ø&×6Ñ6‰Oä—{’{Ô#=¸xÓHˆHØ(0×(JÑ(JÐ%Ø&×6Ñ6ˆOØˆØˆà×Ñ× Ñ  X×%8Ñ%8×%:Ñ%:Ü—{’{Ô#=¸xÓHˆHÜ—{’{Ô#=¸xÓHˆHô   §¡°·±ÔAôâA‘D�Aô #×'Ñ'¨Ö-ÙAð ñ ‰Kð × Ñ ×"Ñ"Ü—{’{Ô#=¸xÓHˆHØ'×@Ñ@ÀÓJÐØˆKØ"ˆKØˆKØ Ÿœ�ØÒ+Ü1×6Ñ6°tÓF�HØ"*�KØ×&Ñ& xÖ0à×&Ñ& tÖ,ò (ð × Ñ ×"Ñ"Ü—{’{Ô#=¸xÓHˆHØ'×@Ñ@ÀÓJÐØˆKØ"ˆKØˆKà Ÿœ�ØÒ+Ü1×6Ñ6°xÓF�HØ"*�KØ×&Ñ& xÖ0à×&Ñ& tÖ,ò (ô !Øfóð ñ Ø×ÑØØ&?Ø#Ø#Ø+ñ
ð 	
ùóKs   Ä0!J*c                ó  >^ • 0 T l         0 T l        Ub  Ucv  [        TT ]  X5        U H_  nUR                  R
                   H  nUT R                   UR                  '   M     UR                  5        H  n	UT R                  U	'   M     Ma     GOUT l        UT l	        S T l
        / T l        T R                  [        R                  R                  UR                  UR                  /5      5        [!        U 4S j[         R"                  " UR$                  UR$                  5       5       5      T R                  R&                  -
  T l        [)        UR*                  UR*                  /5      T l        [-        UR.                  UR.                  /5      T l        UR1                  5       (       a  [3        U[4        5      (       d   eXEpºO[3        U[4        5      (       d   eXTpºU
R6                  T l        T R6                  R9                  UR6                  5        U
R                  T l        UR                  5        H  n	UT R                  U	'   M     T R                   VVVs0 s H(  oÌR:                  R=                  5         H  u  pÞXÞ_M	     M*     snnnT l        UT l        US   RA                  5       nU(       d   eU[B        RD                  " S5      444T l#        [         [H        RJ                  RL                     " 5       T l'        UT l(        g s  snnnf )Nc              3  óh   >#   • U  H'  nUR                   TR                  5       ;  d  M#  Uv •  M)     g 7fry   r^  r  s     €rj   rš   Ú6ForeachKernelSchedulerNode.__init__.<locals>.<genexpr>\	  s5   øé € ð ò ˜ð —x‘x t×'<Ñ'<Ó'>Ñ>÷	 ‘Cò ùra  r   Úcombo_kernel))r  r  r¬  r”  rº   r»   r¼   rð   r(  rÁ   r•   r-  rÜ  r(   rb  rc  r   rd  rŒ  r­  rä  r  r  r€  rp  r’   r	  rï   r¨  r‡  Úitemsr$  rî   rô   ÚExprr©   r¿  ÚfxÚNoder¯  r'  )ri   r(  rÁ   r$  r%  r&  r'  r•   r—  r¼   Úforeach_noderú   r\  rò  Úvr[  r¯  s   `               €rj   r”  Ú#ForeachKernelSchedulerNode.__init__:	  s   ù€ ð ˆÔØˆÔàÑ +Ñ"5Ü‰GÑ˜YÔ/ã�Ø ×,Ñ,×2Ô2�DØ37�D×%Ñ% d§i¡iÓ0ñ 3ð !×4Ñ4Ö6�DØ.2�D×%Ñ% dÓ+ó 7ó	 ð 'ˆDŒNØ ˆDŒKØˆDŒIØ)+ˆDŒJà× Ñ Ü×'Ñ'×2Ñ2Ø ×,Ñ,¨k×.EÑ.EÐFóôô ô ä)×/Ò/Ø#×6Ñ6¸×8VÑ8Vô óó ð ×"Ñ"×)Ñ)ñ*ð Ô#ô ! +×"7Ñ"7¸×9NÑ9NÐ!OÓPˆDŒNÜ  +×"7Ñ"7¸×9NÑ9NÐ!OÓPˆDŒNà×%Ñ%×'Ñ'Ü! +Ô/I×JÑJÐJÐJØ+6™jä! +Ô/I×JÑJÐJÐJØ+6˜jà)×3Ñ3ˆDŒNØ�N‰N×!Ñ! *×"6Ñ"6Ô7à ,× 9Ñ 9ˆDÔØ"×6Ñ6Ö8�Ø*4�×!Ñ! $Ó'ñ 9ð #'§+¢+õ@Ú"-˜×:OÑ:O×:UÑ:U×:W±$°!�’Ñ:W‘¡+ó@ˆDÔ ð *CˆÔ&Ø˜‘×%Ñ%Ó'ˆÞˆˆvØ¤§
¢
¨>Ó :Ð<Ð>Ð?ˆŒ
Ü!¤%§(¡(§-¡-Ò0Ó2ˆŒØ.ˆÕùô@s   É/Lc           
     ó  • U Vs/ s H  n[        U[        5      (       d  M  UPM     nnU(       aW  [        R                  S[	        U5      U Vs/ s H+  oDR
                  c  M  UR
                  R                  5       PM-     sn5        U Vs/ s H  n[        U[        5      (       d  M  UPM     nnU(       a  [        R                  S[	        U5      5        U Vs/ s H  n[        U[        5      (       d  M  UPM     nnU(       a  [        R                  S[	        U5      5        U Vs/ s H,  n[        U[        [        [        [        45      (       a  M*  UPM.     nnU Vs/ s H  n[        U[        5      (       d  M  UPM     nnU(       a  [        R                  S[	        U5      5        U Vs/ s H  n[        U[        5      (       a  M  UPM     nnU Vs/ s H  o"R                  5       (       d  M  UPM     n	nU	(       a   [        R                  S[	        U	5      U	5        U Vs/ s H  o"U	;  d  M
  UPM     nn[        R                  (       av  U Vs/ s H  o"R                  5       (       d  M  UPM     n
nU
(       a  [        R                  S[	        U
5      5        U Vs/ s H  o"R                  5       (       a  M  UPM     nnU$ s  snf s  snf s  snf s  snf s  snf s  snf s  snf s  snf s  snf s  snf s  snf )Nz/ComboKernels: %d external nodes are filtered %sz+ComboKernels: %d grouped nodes are filteredz;ComboKernels: %d FusedMixOrderReductions nodes are filteredz+ComboKernels: %d foreach nodes are filteredz0ComboKernels: %d template nodes are filtered: %szCComboKernels: %d reduction nodes are filtered (pointwise_only mode))r’   rë  r°  r„  r²   r•   r§  rm  râ  r‘  r	  rj  r&   Úcombo_kernels_pointwise_onlyr”   )rp   r5  r™  Úexternr•   ÚgroupedÚ	mix_orderÚfiltered_nodesÚforeach_nodesrr  Úreduction_nodess              rj   Úcombinable_nodesÚ+ForeachKernelSchedulerNode.combinable_nodes‚	  sl  € ñ #ÓOšU˜¤j°Ô4M×&N—!™UˆÐOÞÜ�I‰IØAÜ�F“Ù5;ÓU²V¨T¿y¹yÓ(�—‘×&Ñ&Ö(±VÑUôñ
 $ÓKše˜¤z°!Ô5I×'J—1™eˆÐKÞÜ�I‰IØ=Ü�G“ôñ !&ÓP¢˜1¬°AÔ7N×)O—Q¡ˆ	ÐPÞÜ�I‰IØMÜ�I“ôñ ó
â�ÜØä*Ü-Ü(Ü+ð	÷÷ Ùð 	ð 
ñ &ó
Ú%�!¬°AÔ7Q×)R�A‘~ð 	ð 
ö Ü�I‰IÐCÄSÈÓEWÔXá%ó
Ú%�!¬Z¸Ô;U×-V�A‘~ð 	ð 
ñ &4ÓG¢^ ·}±}·Ÿ!¡^ˆÐGÞÜ�I‰IØBÜ�NÓ#Øôñ
 &4ÓO¢^ ÀÑ7NŸ!¡^ˆÐOô ×.×.Ù*8ÓMª. Q¿N¹N×<LŸq©.ˆOÐMÞÜ—	‘	ØYÜ˜Ó(ôñ *8ÓPª A¿~¹~×?OŸa©ˆNÐPàÐùòy Pùò
 VùâKùò Qùò
ùò
ùò

ùò Hùò Pùò Nùò Qs‚   …K¢KÁKÁ#KÂKÂ)KÃKÃ8KÄ*)K ÅK Å#K%Æ K%Æ2K*ÇK*ÇK/Ç7K/È*	K4È7K4ÉK9É4K9Ê&K>ËK>c                ó¨  • U R                  5       n/ nSn[        U VVVs/ s H>  nU  H4  n[        U[        5      (       d  M  UR	                  5         H  nUPM     M6     M@     snnn5      nU HÒ  n[        [        5      n	U Hi  nUR                  5       n
U
(       a"  U
R                  S:X  d  U
R                  S:X  a  M<  UR                  5       U-  (       a  MV  Xš   R                  U5        Mk     U	R                  5        H=  nUR                  [        S[        U5      U5       Vs/ s H	  nX¼XÃ-    PM     sn5        M?     MÔ     U$ s  snnnf s  snf )zC
Returns a list of lists of nodes that are to be grouped together.
é   ÚmpsrY  r   )Ú_topological_sort_nodesr   r’   râ  r=  r   r  rî   rÀ   rÊ   rË   rÃ   r  rî  r²   )r(  Úsorted_nodesÚgrouped_nodesÚmax_num_nodesr©   r•   rR  Úexcluded_buffer_namesr5  Údevice_groupsr[  Údevice_nodesr1  s                rj   Ú&_default_group_nodes_for_combo_kernelsÚAForeachKernelSchedulerNode._default_group_nodes_for_combo_kernelsÄ	  sZ  € ð !×8Ñ8Ó:ˆØˆØˆä1;ñ *õâ)�EÜ!�DÜ˜dÔ$;×<ó ð !%× 5Ñ 5× 7�Hó	 ñ !8ñ	 á!ñ Ù)óó2
Ðó "ˆEô œDÓ!ð ó �ØŸ™Ó*�Þ˜vŸ{™{¨eÓ3°v·{±{ÀeÓ7KÙð ×)Ñ)Ó+Ð.C×CÙØÑ%×,Ñ,¨TÖ2ñ ð !.× 4Ñ 4Ö 6�Ø×$Ñ$ô "' q¬#¨lÓ*;¸]Ô!Kóâ!K˜Að %¨Ñ):Ó;Ù!Kñöó !7ñ! "ð. Ðùô?ùò4s    EÁ"EÄ'Eú4Callable[[Scheduler], list[list[BaseSchedulerNode]]]Ú!group_algorithm_for_combo_kernelsc                ó   • U [         l        g ry   ©r	  rM  )Úcustom_group_algorithms    rj   Ú%set_group_algorithm_for_combo_kernelsÚ@ForeachKernelSchedulerNode.set_group_algorithm_for_combo_kernelsõ	  s   € ð
 #ô 	#ÕDrm   c                ó,   • [         R                  U 5      $ ry   rO  ©r(  s    rj   Úgroup_nodes_for_combo_kernelsÚ8ForeachKernelSchedulerNode.group_nodes_for_combo_kernelsý	  s   € ô *×KÑKÈIÓVÐVrm   c                ó   • [         ery   rÍ  rh   s    rj   rü  Ú#ForeachKernelSchedulerNode.mark_run
  rÐ  rm   c                ó   • [         ery   rÍ  rh   s    rj   r‹  Ú"ForeachKernelSchedulerNode.codegen
  rÐ  rm   c                ó   • grµ  rw   rh   s    rj   rp  Ú%ForeachKernelSchedulerNode.is_foreach	
  r(  rm   c                ó,   • [        U R                  5      $ )z]Returns a list of nodes which comprise the combo kernel.
These nodes may be vertically fused.)r  rÁ   rh   s    rj   Úget_subkernel_nodesÚ.ForeachKernelSchedulerNode.get_subkernel_nodes
  s   € ô �D—K‘KÓ Ð rm   c                ót   • [        [        R                  R                  S U R                   5       5      5      $ )ziReturns all nodes contained in this kernel, unpacking fused nodes
into their constituent scheduler nodes.c              3  ó@   #   • U  H  oR                  5       v •  M     g 7fry   )r�   ri  s     rj   rš   Ú7ForeachKernelSchedulerNode.get_nodes.<locals>.<genexpr>
  s   é € Ð1UÊÀA·+±+·-°-Êùr7  )r  r  r  r*  rÁ   rh   s    rj   r�   Ú$ForeachKernelSchedulerNode.get_nodes
  s(   € ô ”I—O‘O×1Ñ1Ñ1UÈÏÊÓ1UÓUÓVÐVrm   c                ó<   • U R                   S   R                  5       $ rÑ   )rÁ   r1  rh   s    rj   r1  Ú)ForeachKernelSchedulerNode.get_first_name
  s   € Ø�{‰{˜1‰~×,Ñ,Ó.Ð.rm   c                óŒ   • [        XU R                  R                  5        U R                   H  nUR	                  U5        M     g ry   )r(  r(  rX  rÁ   r*  )ri   r)  r•   s      rj   r*  Ú/ForeachKernelSchedulerNode.prune_redundant_deps
  s5   € ô 	˜d¸¿¹×8RÑ8RÔSà—K”KˆDØ×%Ñ%Ð&8Ö9ò  rm   )rï   r'  r©   r€  r  r  r•   r¯  r‡  r  r(  rÁ   rŒ  r$  r-  )r  r\   r‹   r)  )r  r\   r‹   r)  ©r  r\   r  r\   r‹   rx   )r  r\   r  r\   r‹   r	  )NNF)r(  r'  rÁ   rI  r$  rx   r%  r)  r&  r)  r'  rx   r‹   rs  ©r5  rI  r‹   rI  )r(  r'  r‹   úlist[list[BaseSchedulerNode]])rP  rL  r‹   rs  rr  rt  ©r‹   rI  rC  rp  rA  )r{   r|   r}   r~   r#  r  r  r€   rþ   rq   r”  r>  r$  rJ  rM  r   rQ  rU  rü  r‹  rp  r^  r�   r1  r*  r�   rº  r»  s   @rj   r	  r	  ¨  sº  ø‡ ñð
Ø)ðà	$ôðØ)ðà	$ôð& ó,
ó ð,
ð\ ð>
Ø(ð>
Ø4Eð>
à	#ó>
ó ð>
ðJ 48Ø37Ø %ðF/àðF/ð (ðF/ð $(ð	F/ð
 1ðF/ð 1ðF/ð ðF/ð 
÷F/ð F/ðP ð?Ø+ð?à	 ó?ó ð?ðB ð*Øð*à	&ó*ó ð*ð\ 	/ð &ð (ó /ð ð
Ø Tð
à	ó
ó ð
ð ðWØðWà	&óWó ðWô
"ô"ôô!ô
Wô
/ð:Ø">ð:à	÷:ò :rm   r	  c                  óð   ^ • \ rS rSr% SrS\S'   \SS j5       r S       SU 4S jjjrSS jr	SS jr
\SS	 j5       rSS
 jr\SS j5       rSS jr\SS j5       rSS jrSS jr\SS j5       rSrU =r$ )rm  i"
  a'  
This is a "fake" scheduler node that represents a group of scheduler nodes
that are meant to be *grouped* together (it does not allow another node to be scheduled
in between its constituent nodes, nor does it allow another node to fuse into any of its constituent nodes).
The way it does this is by maintaining its unmet dependencies as the union of its constituent nodes.
Fusion will still happen among the nodes within each GroupedSchedulerNode.
At codegen time, this scheduler node will be unpacked and codegen is called on each constituent node.
rI  rÁ   c                óö   ^• US   R                   m[        U4S jU 5       5      (       d   eU " TU5      nU H   nUTR                  UR                  5       '   M"     UTR                  UR                  5       '   U$ )Nr   c              3  ó>   >#   • U  H  oR                   TL v •  M     g 7fry   rT  )r˜   r•   r(  s     €rj   rš   Ú.GroupedSchedulerNode.create.<locals>.<genexpr>1
  s   øé € ÐBº6°4—>‘> YÕ.º6ùs   ƒ)r(  rœ   r)  r0  )rp   rÁ   Úgrouped_snoder\  r(  s       @rj   ÚcreateÚGroupedSchedulerNode.create.
  su   ø€ à˜1‘I×'Ñ'ˆ	ÜÔB¹6ÓB×BÑBÐBÐBÙ˜I vÓ.ˆÛˆEØ=JˆI×(Ñ(¨¯©Ó)9Ó:ñ àANˆ	×$Ñ$ ]×%;Ñ%;Ó%=Ñ>ØÐrm   c                óH   >• [         TU ]  U5        [        XU5        X0l        g ry   )r¬  r”  rn  Útemp_grouping)ri   r(  rÁ   rt  r¯  s       €rj   r”  ÚGroupedSchedulerNode.__init__8
  s$   ø€ ô 	‰Ñ˜Ô#Ü˜¨Ô0ð +Õrm   c                óB  • U R                   (       a  U R                  $ U R                   H)  nXR                  R                  UR	                  5       '   M+     U R                  R                  U R	                  5       	 U R                  R                  U R                  5      $ )zw
Do fusion among nodes within this GroupedSchedulerNode,
and then unpack this GroupedSchedulerNode into regular nodes.
)rt  rÁ   r(  r)  r0  Ú
fuse_nodes)ri   r\  s     rj   ÚunpackÚGroupedSchedulerNode.unpackG
  so   € ð
 ××Ø—;‘;Ðà—[”[ˆEØBG�N‰N×-Ñ-¨e¯n©nÓ.>Ó?ñ !à�N‰N×-Ñ-¨d¯m©m«oÐ>Ø�~‰~×(Ñ(¨¯©Ó5Ð5rm   c                óŽ   • U R                  U R                  R                  U5      5        U R                  R	                  U5        g ry   )rÜ  rº   râ  rŒ  r  )ri   Úfake_deps     rj   rä  Ú!GroupedSchedulerNode.add_fake_depT
  s5   € Ø×Ñ˜T×-Ñ-×7Ñ7¸ÓAÔBØ×Ñ×#Ñ# HÕ-rm   c                ó~   • SR                  U R                   Vs/ s H  oR                  5       PM     sn5      $ s  snf r�  r�  r�  s     rj   r0  ÚGroupedSchedulerNode.get_nameX
  r’  r“  c                ó<   • U R                   S   R                  5       $ rÑ   r•  rh   s    rj   r1  Ú#GroupedSchedulerNode.get_first_name\
  r—  rm   c                ó‚   • [         R                  " U R                   Vs/ s H  oR                  5       PM     sn6 $ s  snf ry   r™  r�  s     rj   r=  Ú%GroupedSchedulerNode.get_buffer_names_
  r›  rœ  c                ón   • / nU R                    H"  nUR                  UR                  5       5        M$     U$ ry   rž  rŸ  s      rj   r—  Ú GroupedSchedulerNode.get_outputsc
  r¡  rm   c                ó�   • [        [        S S U R                  5        5       5      5      n[        U5      S:X  a  g [	        U5      nU$ )Nc              3  óš   #   • U  HA  nUR                  5       (       d  UR                  5       (       d  M/  UR                  5       v •  MC     g 7fry   r|  r5  s     rj   rš   Ú6GroupedSchedulerNode.estimate_flops.<locals>.<genexpr>o
  r~  r  r   r€  r‚  s      rj   r   Ú#GroupedSchedulerNode.estimate_flopsi
  r…  rm   c                ó   • U R                   $ ry   rØ  rh   s    rj   r�   ÚGroupedSchedulerNode.get_nodes{
  r  rm   c                ób   • U R                   (       a  U R                   S   R                  5       $ S $ rÑ   )rÁ   rî   rh   s    rj   rî   ÚGroupedSchedulerNode.get_device~
  s$   € Ø.2¯k¯kˆt�{‰{˜1‰~×(Ñ(Ó*ÐC¸tÐCrm   c                ó   • grÏ  rw   )rp   r  r  s      rj   rþ   ÚGroupedSchedulerNode.can_fuse�
  rÔ  rm   )rt  )rÁ   rI  r‹   rm  )F)r(  r'  rÁ   rI  rt  rx   r‹   rs  rk  )r{  r1   r‹   rs  rp  r@  rß  rF  rC  rv  rh  )r{   r|   r}   r~   r#  r   r€   rq  r”  rx  rä  rF   r0  r1  r=  r—  r   r�   rî   rþ   r�   rº  r»  s   @rj   rm  rm  "
  sÈ   ø‡ ñð $Ó#àóó ðð $ð	+àð+ð (ð+ð ð	+ð
 
÷+ð +ô6ô.ð ó=ó ð=ô)ð óNó ðNôð óó ðô"ôDð óó örm   rm  c           
     ó0  ^ ^• [         R                  SUU 4S jj5       n[        [        [	        [        T S   5      5      5      5      n[        U5      S:”  a  U Vs/ s H  nT U   PM
     snm [        R                  (       a  UR                  US9  U$ s  snf )zu
A heuristic to decide loop iteration orders.  This has not been well
tuned and may be something we should autotune.
c                óz  >• TU    S:X  d	  TU   S:X  a  [        TU    S:H  TU   S:H  5      $ T Vs/ s H  n[        X    5      PM     nnT Vs/ s H  n[        X!   5      PM     nn[        S [        X45       5       5      n[        S [        X45       5       5      nXV:”  a  gXe:”  a  g[        X5      $ s  snf s  snf )Nr   c              3  óF   #   • U  H  u  pUS :H  =(       d    X:  v •  M     g7f©r   Nrw   ©r˜   Úsl_aÚsl_bs      rj   rš   Ú5pick_loop_order.<locals>.index_cmp.<locals>.<genexpr>ž
  ó$   é € ð 
Ú7V©¨ˆD�A‰I×$˜™Ô$Ò7Vùó   ‚!c              3  óF   #   • U  H  u  pUS :H  =(       d    X!:  v •  M     g7fr’  rw   r“  s      rj   rš   r–  ¡
  r—  r˜  r
  )rG   Úabsré   r)  )	rU  ÚbÚslÚstride_len_aÚstride_len_bÚa_firstÚb_firstrç  Ústride_lengthss	          €€rj   Ú	index_cmpÚ"pick_loop_order.<locals>.index_cmp‘
  sÏ   ø€ à�‰8�q‹=˜E !™H¨›Mä�u˜Q‘x 1‘} e¨A¡h°!¡mÓ4Ð4ñ .<Ó<ª^ rœ˜B™Ež
©^ˆÐ<Ù-;Ó<ª^ rœ˜B™Ež
©^ˆÐ<ô ñ 
Ü7:¸<Ô7Vó
ó 
ˆô ñ 
Ü7:¸<Ô7Vó
ó 
ˆð ÓØØÓØô �1‹yÐùò# =ùÚ<s   °B3ÁB8r   rŒ  )rU  r!  r›  r!  r‹   r!  )	Ú	functoolsÚ
cmp_to_keyr  r´   rî  r²   r&   Úpick_loop_ordersÚsort)r¡  rç  Úpriority_idxr¢  ÚorderÚpis   ``    rj   Úpick_loop_orderr«  ‡
  s…   ù€ ô ×Ñ÷ó ðô4 ”œ%¤ N°1Ñ$5Ó 6Ó7Ó8Ó9€EÜ
ˆ<Ó˜1Óá7CÓD²|°˜.¨Ô,±|ÑDˆÜ××Ø�
‰
�yˆ
Ñ!Ø€Lùò Es   ÁBc                óè  • UR                  5       nU R                  5       n[        U[        5      (       a  [        U[        5      (       d   eUR                  5       nU R                  5       n[        U[        5      (       a  [        U[        5      (       d   e[        R
                  R                  U	 X1l        [        R
                  R                  U	 XQl	        [        R
                  R                  R                  U 5      n[        R
                  R                  R                  U5        U[        R
                  R                  U'   U[        R
                  R                  U'   [        R
                  R                  R                  U 5      n[        R
                  R                  R                  U5        U[        R
                  R                  U'   U[        R
                  R                  U'   g ry   )r0  r’   r  r-  rW   r¤   r  r¼   Ú
name_to_opÚoperation_nameÚbuffersr½   ÚremoveÚ
operations)Ú	orig_noder)  Úreplaced_buf_nameÚorig_buf_nameÚreplaced_op_nameÚorig_op_nameÚorigs          rj   Ú_replace_operation_bufferr¸  µ
  s]  € ð !×)Ñ)Ó+ÐØ×&Ñ&Ó(€MÜ�m¤S×)Ñ)¬jÐ9JÌC×.PÑ.PÐPÐPà×2Ñ2Ó4ÐØ×/Ñ/Ó1€LÜ�l¤C×(Ñ(¬ZÐ8HÌ#×-NÑ-NÐNÐNä	�‰×ÑÐ0Ð1Ø!„Mä	�‰×ÑÐ+Ð,Ø*Ôä�7‰7�?‰?× Ñ  Ó+€DÜ‡G�G‡O�O×Ñ˜8Ô$Ø$„A‡G�G‡O�O�DÑØ,4„A‡G�G×Ñ˜=Ñ)ä�7‰7×Ñ×#Ñ# IÓ.€DÜ‡G�G×Ñ×Ñ˜hÔ'Ø'„A‡G�G×Ñ�tÑØ'/„A‡G�G×Ñ�|Ò$rm   c                ój   • UR                  5       nU R                  5       nX4-
  nXT-  nUSU-   -  nXr-  $ r  )r¾  rÁ  )r…   r†   Úepilogue_runtimeÚtotal_read_bytesÚtemplate_write_bytesÚextra_bytesÚextra_bytes_ratioÚextra_memory_ratios           rj   Ú _estimate_fused_epilogue_runtimerÀ  Ñ
  sO   € ð ×2Ñ2Ó4ÐØ ×7Ñ7Ó9ÐØ"Ñ9€KØ#Ñ:Ðð +¨aÐ2CÑ.CÑDÐØÑ0Ð0rm   c                  ód   • \ rS rSr% S\S'   SrS\S'   SrS\S'   SS jrSS	 jrSS
 jr	SS jr
Srg)ÚNodeUseriÞ
  ú$Union[BaseSchedulerNode, OutputNode]r•   Frx   ru  Úis_weakc                óv   • [        U R                  R                  5       U R                  U R                  45      $ ry   )r5  r•   r0  ru  rÄ  rh   s    rj   r6  ÚNodeUser.__hash__ç
  s+   € Ü�T—Y‘Y×'Ñ'Ó)¨4×+;Ñ+;¸T¿\¹\ÐJÓKÐKrm   c                óò   • [        U[        5      =(       aa    U R                  5       UR                  5       :H  =(       a9    U R                  UR                  :H  =(       a    U R                  UR                  :H  $ ry   )r’   rÂ  r0  ru  rÄ  rþ  s     rj   Ú__eq__ÚNodeUser.__eq__ê
  s[   € ä�uœhÓ'÷ .Ø—‘“ 5§>¡>Ó#3Ñ3÷.à× Ñ  E×$5Ñ$5Ñ5÷.ð —‘ §¡Ñ-ð		
rm   c                ó6   • U R                   R                  5       $ ry   rH  rh   s    rj   r0  ÚNodeUser.get_nameò
  rJ  rm   c                óÚ   • U R                   UR                   L d   e[        U R                   U R                  =(       a    UR                  U R                  =(       a    UR                  5      $ ry   )r•   rÂ  ru  rÄ  rþ  s     rj   rf  ÚNodeUser.mergeõ
  sP   € Ø�y‰y˜EŸJ™JÒ&Ð&Ð&ÜØ�I‰IØ×Ñ×2 ×!2Ñ!2Ø�L‰L×*˜UŸ]™]ó
ð 	
rm   rw   Nrq  )rÿ  Úobjectr‹   rx   rp  )rÿ  rÂ  r‹   rÂ  )r{   r|   r}   r~   r   ru  rÄ  r6  rÈ  r0  rf  r�   rw   rm   rj   rÂ  rÂ  Þ
  s3   ‡ à
.Ó.Ø€K�Óð €GˆTÓôLô
ô$÷
rm   rÂ  c                 ó"   • [         R                  $ ry   )r&   rr  rw   rm   rj   Ú*used_non_deterministic_runtime_estimationsrÐ    s   € Ü×3Ñ3Ð3rm   c                ó¼  • [        5       nU R                  5       n[        U[        R                  5      (       a•  UR                  [        UR                  5      [        UR                  5      -  [        UR                  5      -  5        [        U[        R                  5      (       a$  UR                  [        UR                  5      5        U$ Ub
   SU 35       eU$ )z=Get free symbols from a node's layout (size, stride, offset).z*Expect layout to be None but found layout=)r   Úmaybe_get_layoutr’   r)   ÚLayoutr¨  r    rÂ   ÚstrideÚoffsetr’  Úget_layout_symintsr¨  )r•   Úfree_symbol_usesr=  s      rj   rÖ  rÖ    s¹   € ä1;³ÐØ×"Ñ"Ó$€FÜ�&œ"Ÿ)™)×$Ñ$Ø×ÑÜ˜Ÿ™Ó%Ü˜6Ÿ=™=Ó)ñ*ä˜6Ÿ=™=Ó)ñ*ô	
ô
 �fœb×;Ñ;×<Ñ<à×#Ñ#Ô$6°v·}±}Ó$EÔFð Ðð ‰~ÐTÐ!KÈFÈ8ÐTÓTˆ~ØÐrm   c                ó.  • [        U [        5      (       a(  [        5       R                  " S U R                   5       6 $ U R
                  c   eU R
                  R                  5       nUR                  " S U R
                  R                  5        5       6   U$ )z{
Gets symbols used in a scheduler node, including free symbols from
the node's operations and layout symints from outputs.
c              3  ó8   #   • U  H  n[        U5      v •  M     g 7fry   ©Úget_scheduler_node_symbol_uses)r˜   r\  s     rj   rš   Ú1get_scheduler_node_symbol_uses.<locals>.<genexpr>   s   é € ÐMÂ¸Ô,¨U×3Ð3ÂùrÚ  c              3  ó8   #   • U  H  n[        U5      v •  M     g 7fry   )rÖ  )r˜   Úir_nodes     rj   rš   rÜ  %  s   é € Ð	MÒ5L¨'Ô
˜W×
%Ð
%Ò5LùrÚ  )	r’   r¿   r   rd  rÁ   r•   Úget_free_symbol_usesr¨  r—  )r•   r×  s     rj   rÛ  rÛ    sƒ   € ô �$Ô*×+Ñ+Ü‹|×!Ò!ÙMÀÇÂÓMð
ð 	
ð �9‰9Ñ Ð Ð Ø—y‘y×5Ñ5Ó7ÐØ×ÒÙ	M°T·Y±Y×5JÑ5JÔ5LÓ	Mñð Ðrm   c                óˆ   • U R                  5       =(       a,    [        R                  =(       a    UR                  5       (       + $ ry   )rj  r&   Úepilogue_fusionrˆ   s     rj   Úis_epilogue_fusionrâ  *  ó-   € Ø×ÑÓ×U¤6×#9Ñ#9×UÀ%×BSÑBSÓBUÔ>UÐUrm   c                óˆ   • UR                  5       =(       a,    [        R                  =(       a    U R                  5       (       + $ ry   )rj  r&   Úprologue_fusionrˆ   s     rj   Úis_prologue_fusionræ  .  rã  rm   c                ó<   • [        X5      =(       d    [        X5      $ ry   )râ  ræ  rˆ   s     rj   Úis_template_fusionrè  2  s   € Ü˜eÓ+×OÔ/AÀ%Ó/OÐOrm   c                ó*   • [        X5      (       a  U$ U $ ry   )râ  rˆ   s     rj   Útemplate_fusion_pw_noderê  6  s   € Ü& u×4Ñ4ˆ5Ð?¸%Ð?rm   c                  ó&  ^ • \ rS rSrSrS^S jrS^U 4S jjrS_S jr\S`S j5       r	\	R                  SaS j5       r	SbS jrScS	 jrSdS
 jrSbS jrSbS jrSbS jrSbS jrSeS jr    SfS jrSgS jrShS jrSbS jrSbS jrSfS jrSbS jr    SiS jr Sj       SkS jjr      SlS jr    SmS jrSbS jr          SnS jrSoS jr  Sj     SpS jjr!      SqS jr"SrS  jr#        SsS! jr$        StS" jr%      SuS# jr&          SvS$ jr'    SwS% jr(    SxS& jr)      SyS' jr*SjSzS( jjr+S{S) jr,      S|S* jr-      S}S+ jr.      S}S, jr/        S~S- jr0      S}S. jr1        SS/ jr2      S€S0 jr3      S€S1 jr4S�S2 jr5        S‚S3 jr6      SƒS4 jr7  S„         S…S5 jjr8      S}S6 jr9        S†S7 jr:S‡S8 jr;SˆS‰S9 jjr<   SŠ           S‹S: jjr=    SŒS; jr>    S�S< jr?SbS= jr@SbS> jrASbS? jrBSŽS@ jrCS�SA jrDS�SB jrES‘SC jrF      S’SD jrGS“SE jrH\IS”SF j5       rJ    S“SG jrK  S•SH jrL    S–SI jrM      S—SJ jrN      S˜SK jrO    S™SL jrP    SfSM jrQ    SfSN jrR    SfSO jrS  SšSP jrT      S›SQ jrUS‘SR jrVSbSS jrW      SœST jrX      S�SU jrY      S›SV jrZSbSW jr[S{SX jr\    SžSY jr]SŸSZ jr^S S[ jr_SbS\ jr`S]raU =rb$ )¡r'  i:  z�
A Scheduler is a graph of BaseSchedulerNodes. It is responsible for
optimizations such as fusion, reorder, and graph partition.
c                óp   • [        S5         U R                  U5        S S S 5        g ! , (       d  f       g = f)NzScheduler.__init__)r   Ú_init©ri   r5  s     rj   r”  ÚScheduler.__init__@  s#   € ÜÐ.Õ/Ø�J‰J�uÔ÷ 0×/Ö/ús   Œ'§
5c           
     ó  >^ • [         TT ]  5         T [        R                  l        0 T l        [        [        5      T l        [        R                  " 5       T l        [        5       T l        [        / [        R                  R                  R                  5       Q[        R                  R                   R                  5       Q[        R                  R"                  R                  5       Q5      T l        U Vs/ s H  nT R'                  U5      PM     snT l        S T l        S T l        T R/                  5         T R$                  R1                  [        R                  R                   R                  5       5        T R(                   H  nUR3                  5         M     S T l        T R7                  5       T l        T R(                   Vs0 s H  o"R;                  5       U_M     snT l        T R(                   VVs0 s H*  o3R?                  5         H  oDR;                  5       U_M     M,     snnT l         T R<                  RC                  5       T l"        0 T l#        0 T l$        [        5       T l%        [L        RN                  " T R(                  T R@                  T RD                  5      T l        T RQ                  5         T RS                  T R(                  5      T l        T RU                  5         T R(                   Vs0 s H  o"R;                  5       U_M     snT l"        T RW                  5         [X        =RZ                  []        T R(                  5      -  sl-        SSK/J0nJ1n  U" T R(                  5        []        T R(                  5      T l2        T Rg                  5         T RS                  T R(                  5      T l        [        [h        [j        [j        4      " 5       T l6        [n        Rp                  b%  [n        Rp                  " T R(                  5      T l        [n        Rr                  (       a'  SSK:J;n  URy                  T 5        T RW                  5         T R{                  T R(                  5      T l        [n        R|                  b%  [n        R|                  " T R(                  5      T l        T R                  5         T R�                  5         [n        R‚                  (       d  [n        R„                  (       aA  [‡        5       (       a2  [ˆ        RŠ                  RŒ                  RŽ                  R‘                  5         [n        R’                  (       a#  [•        SSSS9   T R—                  S S9  S S S 5        [n        R˜                  (       a‰  SS	KMJLn  U" T R(                  T R@                  T RD                  [        [        R                  R                  R                  5       5      [        [        R                  R�                  5       5      5      T l        [n        Rž                  (       Gd;  [n        R                   (       Ga%  [n        R˜                  (       d#  SS
KMJQn	  U	" T R(                  T R@                  5        [¥        5       (       a‘  [¦        R¨                  (       a|  [n        Rª                  (       d  [¦        R¬                  (       aR  Sn
T R(                   H!  n[¯        UR°                  5      (       d  M  Sn
  O   U
(       a  SSK&JYn  U" T R(                  5        [¦        R´                  (       a  SSK[J\n  U" SS U 4S jS9  [L        Rº                  " T R(                  5      T l        T R½                  5         [n        R¾                  (       a~  [n        RÀ                  RÂ                  (       a_  [n        RÀ                  RÄ                  (       a@  T RÇ                  T R(                  5      T l        T RÉ                  T R(                  5      T l        T RË                  5         [ˆ        RŠ                  Rn                  RÌ                  RÎ                  (       a  T RÑ                  5         U" T R(                  5        [        RÒ                  RÕ                  T R(                  5        T R×                  5         [        5       T ll        0 T lm        [Ý        S5      Rß                  U 4S j5        [        5       T lp        g s  snf s  snf s  snnf s  snf ! , (       d  f       GN˜= f)Nr   )Úlog_ir_post_fusionÚlog_ir_pre_fusionr   )Údistributed_autotunez#Scheduler.create_combo_kernel_nodesT©Úlog_pt2_compile_eventÚlog_waitcounter)Únum_ck_nodes)Úreorder_for_peak_memory)Ú1assign_memory_planning_info_for_scheduler_buffersF)Ú6align_runtime_estimations_across_all_distributed_ranks)Útrace_structuredÚartifactc                 ó   • SSS.$ )NÚ#scheduler_nodes_before_comm_overlapÚstring)r¼   Úencodingrw   rw   rm   rj   r‘  Ú!Scheduler._init.<locals>.<lambda>ã  s   € Ø EØ$,ò)rm   c            
     óÔ   >• SR                  [        TR                  5       V Vs/ s H0  u  pSU  S3UR                  5       -   SUR	                  5        3-   PM2     snn 5      $ s  snn f )Nz

zsnode[r;  z buffer_names:)r  r4  r5  rE  r=  )r1  rD  ri   s     €rj   r‘  r  ç  so   ø€  v§{¡{ô
 )2°$·*±*Ô(=ô	ò )>¡ ð % Q C q˜MØŸk™k›mñ,à .¨q×/AÑ/AÓ/CÐ.DÐEôFñ )>ò	ô(ùós   ¥7A$
)Úmetadata_fnÚ
payload_fnÚgraph_statsc                 ó^   >• T R                   T R                  [        T R                  5      S.$ )N)Úgraph_idÚnum_nodes_before_fusionÚnum_nodes_after_fusion)Úpost_grad_graph_idÚnum_orig_nodesr²   r5  rh   s   €rj   r‘  r    s%   ø€ Ø ×3Ñ3Ø+/×+>Ñ+>Ü*-¨d¯j©j«/òrm   )qr¬  r”  rW   r¤   r(  Úbackendsr3  Ú_post_grad_graph_counterr
  r  ÚcountÚ_graph_partition_counterr   rŽ  rò  r  Ú	constantsÚtorchbind_constantsr  Úcreate_scheduler_noder5  Úprevious_nodeÚcurrent_nodeÚupdate_zero_dim_cpu_tensorr¨  rì  Údefault_device_contextÚget_donated_buffersrW  r0  r  r—  rX  Úcopyr)  ró  rƒ  Úseen_template_fusionsr%   Údecide_global_ordering_of_commsrZ   Útopological_sort_scheduleÚdead_node_eliminationÚcompute_ancestorsr*   Úir_nodes_pre_fusionr²   Útorch._inductor.debugrñ  rò  r  Úcreate_foreach_nodesr³   r  Úlogged_slow_fusionr&   Ú_pre_fusion_custom_passÚdistributed_max_autotune_gemmrµ  ró  Úschedulerw  Ú_post_fusion_custom_passr  Úfinalize_multi_template_buffersÚmax_autotune_gemmÚmax_autotuner   r¿  rÀ  Úselect_algorithmÚPrecompileThreadPoolÚshutdown_instanceÚcombo_kernelsr   Úcreate_combo_kernel_nodesrø  ÚmemoryÚget_output_namesÚdeterministicÚ reorder_for_compute_comm_overlaprù  rÐ  r'   Ú6runtime_estimations_align_across_all_distributed_ranksrr  r
  rP   r•   rú  Úreorder_sink_verbose_loggingÚtorch._loggingrû  Ú$reorder_compute_and_comm_for_overlapÚprocess_grouped_nodesÚgraph_partitionrá   r[   Ú%reorder_for_reducing_graph_partitionsÚ&maybe_reorder_for_minimizing_partitionÚ,reorder_for_partition_with_simple_dependencyÚcompute_last_usageÚtest_configsÚtrack_memory_lifecycleÚinsert_memory_check_nodesr„  Úgraph_diagramÚdebug_draw_graphÚbuffer_names_to_freeÚorigin_to_indexr   Úadd_rowÚremoved_ops)ri   r5  rD  r•   rÄ   rñ  rò  ró  rø  rù  Úhas_collectivesrú  rû  r¯  s   `            €rj   rí  ÚScheduler._initD  sN  ù€ Ü‰ÑÔØ Œ�‰ÔØ<>ˆŒÜ"&Ô'?Ó"@ˆÔÜ(1¯ªÓ(9ˆÔ%ä5?³\ˆÔ!Ü&0ðÜ—‘×%Ñ%×*Ñ*Ó,ðä—‘×"Ñ"×'Ñ'Ó)ðô —‘×,Ñ,×1Ñ1Ó3ðó'
ˆÔ#ñ >CÓCºU¸�d×0Ñ0°Ö3¹UÑCˆŒ
Ø:>ˆÔØ9=ˆÔØ×'Ñ'Ô)à×#Ñ#×*Ñ*¬1¯7©7×+<Ñ+<×+AÑ+AÓ+CÔDØ—J”JˆDØ�O‰OÖñ ð ?CˆÔ#ð ×$Ñ$Ó&ð 	Ô#ð &*§Z¢Zó;
Ú%/ �J‰J‹L˜!ŠO¡Zñ;
ˆÔð
 -1¯JªJô8
Ú,6 D×BRÑBR×BT¸3�L‰L‹N˜CÒÑBT‰N©Jò8
ˆÔð AE×@QÑ@Q×@VÑ@VÓ@XˆÔð 35ˆÔð 13ˆÔô ‹Lð 	Ô"ô
 ×:Ò:Ø�J‰JØ×ÑØ×#Ñ#ó
ˆŒ
ð 	×!Ñ!Ô#Ø×3Ñ3°D·J±JÓ?ˆŒ
Ø×"Ñ"Ô$Ø<@¿JºJÓ"GºJ°q§:¡:£<°¢?¹JÑ"GˆÔØ×ÑÔ ô 	×#Ò#¤s¨4¯:©:£Ñ6Õ#ßOá˜$Ÿ*™*Ô%Ü! $§*¡*›oˆÔØ×!Ñ!Ô#Ø×3Ñ3°D·J±JÓ?ˆŒ
Ü",¬U´3¼°8©_Ò"=Ó"?ˆÔÜ×)Ñ)Ñ5Ü×7Ò7¸¿
¹
ÓCˆDŒJä×/×/Ý.à ×)Ñ)¨$Ô/Ø×"Ñ"Ô$à—_‘_ T§Z¡ZÓ0ˆŒ
Ü×*Ñ*Ñ6Ü×8Ò8¸¿¹ÓDˆDŒJà×ÑÔØ×,Ñ,Ô.ä×$×$¬×(;×(;Ü&×(Ñ(Ü�O‰O×,Ñ,×AÑA×SÑSÔUä××ÜØ5Ø&*Ø $óð
 ×.Ñ.¸DÐ.ÑA÷ô ×)×)Ý7á0Ø—
‘
Ø× Ñ Ø×'Ñ'Üœ1Ÿ7™7×/Ñ/×4Ñ4Ó6Ó7Üœ1Ÿ7™7×3Ñ3Ó5Ó6óˆDŒJô ×#×#Ð#¬×(O×(OÐ(OÜ×1×1ÝUáAØ—J‘J × 0Ñ 0ôô
 ;×<Ñ<Ü ×W×Wä×<×<Ü#×P×Pð #(�Ø ŸJœJ�DÜ$ T§Y¡Y×/Ó/Ø*.˜Ùñ 'ö #õñ KÈ4Ï:É:ÔVô ×8×8Ý;á Øñ!ô òô ×CÒCÀDÇJÁJÓOˆDŒJØ×"Ñ"Ô$ô ×"×"ä—‘×(×(ä—‘×C×Cà×DÑDÀTÇZÁZÓPˆDŒJØ×JÑJÈ4Ï:É:ÓVˆDŒJà×ÑÔ!ä�?‰?×!Ñ!×.Ñ.×E×EØ×*Ñ*Ô,á˜4Ÿ:™:Ô&ä	�‰×Ñ˜dŸj™jÔ)Ø×ÑÔô 6@³\ˆÔ!ð :<ˆÔä˜Ó'×/Ñ/ôô	
ô -7«LˆÕùòM Dùò;
ùó8
ùòH #H÷Bö ús$   Ã6cÇcÇ61c$Ë5c*Õc/ã/
c>c                ó  • 0 n[         R                  R                   Hg  n[        [         R                  R                  U   [        R
                  5      (       d  M?  [        U [         R                  R                  U   S S9X'   Mi     U$ )N)r*  )rW   r¤   Úgraph_inputs_originalr’   r)   ÚDonatedBufferr{  )ri   Úname_to_donated_bufr¼   s      rj   r  ÚScheduler.get_donated_buffers  sl   € Ø ÐÜ—G‘G×1Ô1ˆDÜœ!Ÿ'™'×7Ñ7¸Ñ=¼r×?OÑ?O×PÓPÜ,BØÜ—G‘G×1Ñ1°$Ñ7Ø $ñ-Ð#Ó)ñ 2ð #Ð"rm   c                ó6   • [         R                  R                  $ ry   ©rW   r¤   Úcurrent_devicerh   s    rj   rN  ÚScheduler.current_device&  s   € ä�w‰w×%Ñ%Ð%rm   c                ó.   • U[         R                  l        g ry   rM  rZ  s     rj   rN  rO  *  s   € à!'Œ�‰Õrm   c                ó|   • [         R                  R                  SS5      S:X  a  SSKJn  U" U R
                  SS9  gg)z,Generate an image of the graph for debuggingÚINDUCTOR_WRITE_SCHEDULER_GRAPHNÚ1r   )Údraw_buffersT)Úprint_graph)ÚosÚenvironrñ  r„  rT  r5  )ri   rT  s     rj   r@  ÚScheduler.debug_draw_graph.  s1   € ä�:‰:�>‰>Ð:¸DÓAÀSÓHÝ+á˜Ÿ™°Ó6ð Irm   c                óÈ   • [         R                  [        R                  5      (       a:  [         R	                  SU5        U R
                   H  nUR                  5         M     g g )Nz%s:)r°  ÚisEnabledForÚloggingÚINFOrË  r5  rÌ  )ri   Úlabelr•   s      rj   Údebug_print_nodesÚScheduler.debug_print_nodes5  sD   € Ü×ÑœGŸL™L×)Ñ)Ü�H‰H�U˜EÔ"ØŸ
œ
�Ø× Ñ Ö"ò #ð *rm   c                óP  • UR                  5       c   S5       eUR                  5       (       a  [        X5      $ [        U[        R
                  [        R                  45      (       a  [        X5      $ [        U[        R                  5      (       a  [        X5      $ [        U5      e)Nz2All nodes passed to scheduling must have an origin)r§  Úis_no_opr‘  r’   r)   r   rÉ  r“   re  rë  rÎ  rÄ  s     rj   r  ÚScheduler.create_scheduler_node;  s‰   € Ø×ÑÓ!Ñ-ð 	
Ø@ó	
Ð-ð �=‰=�?‰?Ü)¨$Ó5Ð5Ü˜œr×0Ñ0´"×2CÑ2CÐD×EÑEÜ  Ó,Ð,Ü˜œbŸo™o×.Ñ.Ü,¨TÓ8Ð8ä% dÓ+Ð+rm   c                óÊ  • [        5       n/ nU R                  R                  5       n[        R                  R
                  R                  5        H¿  nU Vs/ s H0  nXS;   d  M
  [        U R                  U   [        5      (       a  M.  UPM2     nnU(       d  MI  UR                  U5        U Vs/ s H  oPR                  U   PM     nn[        R                  S:„  n[        U USUS9nUR                  U5        U H  nX€R                  U'   M     MÁ     U R                   V	s/ s H  o™R!                  5       U;  d  M  U	PM     sn	[#        U5      -   U l        g s  snf s  snf s  sn	f )Nr   F©r$  r'  )r   r)  r  rW   r¤   ÚlistsrÃ   r’   r  r‘  r¨  r&   Úcombo_kernels_autotuner	  rË   r5  r0  r  )
ri   Úremoved_node_namesÚfe_nodesÚkept_node_namesÚnamesr¼   rÁ   r'  Úfe_noder•   s
             rj   r   ÚScheduler.create_foreach_nodesH  sK  € Ü.8«lÐØˆØ×1Ñ1×6Ñ6Ó8ˆä—W‘W—]‘]×)Ñ)Ö+ˆEñ "óâ!�DØÑ*ó ô # 4×#4Ñ#4°TÑ#:Ô<R×S÷ Ù!ð ð ö áà×%Ñ% eÔ,Ù:?Ó@º%°$×'Ñ'¨Ô-¹%ˆFÐ@ä$×;Ñ;¸aÑ?ˆOÜ0ØØØ*/Ø /ñ	ˆGð �O‰O˜GÔ$ã�Ø07×'Ñ'¨Ó-ó ñ1 ,ð8 "ŸZšZó
Ú'�T¯=©=«?ÐBTÑ+T�D™Zñ
ä�‹Nñˆ�
ùò5ùò Aùò
s$   Á	EÁ# EÂEÂ-EÄ E Ä;E c                óX  ^ ^'^(^)•  " U'4S jS[         [           5      m'[        R                  " T'5      m(T R                   Hç  nUR                  5        HÐ  nUR                  5       n[        UR                  R                  [        R                  5      (       a  [        UR                  5       5      S:”  a  Me  UR                  5        HW  nUT(;   a6  UT(;   a0  T(U   nT(U   nXV-   nT( H  nT(U   UL d
  T(U   UL d  M  UT(U'   M     M?  UT(;   a
  T(U   T(U'   MO  T(U   T(U'   MY     MÒ     Mé     SU)U 4S jjm)  S         SU(U)4S jjjn	0 n
[        R                  R                   R#                  5        H½  n[        U[$        R&                  5      (       a  UR(                   H  nSX¬'   M	     M;  [        U[        R*                  5      (       d  M\  UR-                  5        Vs/ s H&  n[        U[$        R&                  5      (       d  M$  UPM(     nnU H  nUR(                   H  nSX¬'   M	     M     M¿     SnT R                   Hz  nUR                  c   e[/        UR                  R1                  5       S S	9nU H?  n[        U[$        R2                  5      (       d   eS
nXÚ;  d  M-  UR                  5       X­'   MA     M|     T R                   GHd  n[4        R7                  SUR                  5        U(       a   UR                  c   e[/        UR                  R9                  S
S9S S	9nU Hi  nXÚ;   d   U SU
 35       eX­   =nc  M  T R:                  U   R                  5        H+  nUR=                  [?        UR                  5       5      5        M-     Mk     [        UR@                  RB                  5      S:X  aQ  [E        [G        UR@                  RB                  5      5      =n(       a"  [        U[H        5      (       a  URJ                  nOSnUR                  5        GHB  n[        URM                  5       5      S::  d   eURM                  5        GH
  nT)" U5      nU	" UU5        UR=                  [?        UUS95        T(U   RN                   HÉ  nUR                  5       UR                  5       :X  a  M'  [        UR                  [P        5      (       d   eUR                  R                  5        Hc  nUR                  5       nT)" U5      nUUR                  5       ;   nUR=                  [S        UUR                  5       U(       + S95        U	" UUS
S9  Me     MË     GM     GME     [        R                  RT                  UR                  5           H3  nU	" UUS
S9  UR=                  [S        UUR                  5       S
S95        M5     [        R                  RV                  UR                  5           H%  nU	" UUSS9  UR=                  [?        U5      5        M'     UR@                  RX                   H<  n[        U[R        5      (       a  M  U	" URZ                  XR]                  U5      5        M>     UR_                  T R`                  5        UR                  5        H‘  nURM                  5        Hz  nUR                  5       T R`                  T)" U5      '   UR                  5       T R`                  U'   T Rb                  Re                  UU5      T Rb                  UR                  5       '   M|     M“     GMg     [        R                  Rg                  5        H4  n[4        R7                  SU5        U	" U[i        [?        U5      5      5        M6     U(       a¹  [        R                  Rj                   H›  nUR9                  S
S9 H…  nXÚ;   d   U SU
Rm                  5        35       eX­   =n(       d  M/  T R:                  U   Ro                  5        H5  n[4        R7                  SUU5        U	" U[i        [?        U5      5      5        M7     M‡     M�     T R`                   H¢  nU[        R                  R                   ;   aF  U	" U[i        [?        U5      5      5        [        R                  Rp                  Rs                  U5        Mg  U[        R                  Rt                  ;   d  M‡  U	" U[i        [?        U5      5      5        M¤     [w        [        R                  R                   Rm                  5       5       V Vs0 s H	  u  n nUU _M     n!n n[        R                  Rp                   Vs/ s H  nU!U   PM
     sn[        R                  l<        T R                   HF  nUR                  5        H/  nUR{                  T(UR                  5          RN                  5        M1     MH     T R|                   H.  nT R|                  U   R{                  T(U   RN                  5        M0     [        5       n"U"R�                  S5        T(RO                  5        Ha  u  nn#U"Rƒ                  5          U#RN                   V$s/ s H  n$U$R                  5       PM     n%n$U"R�                  SU SU% S35        SSS5        Mc     U"R�                  S5        U"R…                  5       R‡                  5       n&[ˆ        R7                  S5        [ˆ        R7                  SU&5        gs  snf s  snn f s  snf s  sn$f ! , (       d  f       Mä  = f)zQ
Create dependency edges between nodes, handling aliasing and
mutation properly.
c                  óP   >• \ rS rSrSr  S     S	S jjrS
S jrSU 4S jjrSrg)Ú1Scheduler.compute_dependencies.<locals>.DedupListir  a  
This data structure behaves like a list except it makes sure the
elements remain unique.
Normally one could use a OrderedSet/dict for this purpose however
the list in question gets elements appended as it is being
iterated over which means that we need to keep the list
semantics.
Nc                óT   • U=(       d    / U l         U=(       d
    [        5       U l        g ry   )r/  r   Ú
membership)ri   r/  rq  s      rj   r”  Ú:Scheduler.compute_dependencies.<locals>.DedupList.__init__|  s   € ð
 #Ÿ[ b�”
Ø",×"<´
³�•rm   c                ó�   • XR                   ;   a  g U R                  R                  U5        U R                   R                  U5        g ry   )rq  r/  rË   r  )ri   Ú	node_users     rj   rË   Ú8Scheduler.compute_dependencies.<locals>.DedupList.append„  s3   € Ø§¡Ó/ØØ—
‘
×!Ñ! )Ô,Ø—‘×#Ñ# IÕ.rm   c                óê   >• [         R                  " U R                  UR                  5      nU R                  UR                   Vs/ s H  o3U R                  ;  d  M  UPM     sn-   nT" XB5      $ s  snf ry   )r   rd  rq  r/  )ri   rÿ  Únew_membershipr™  Ú	new_itemsÚ	DedupLists        €rj   Ú__add__Ú9Scheduler.compute_dependencies.<locals>.DedupList.__add__Š  sc   ø€ Ü!+×!1Ò!1°$·/±/À5×CSÑCSÓ!T�Ø ŸJ™JØ$Ÿ{š{ó*Ú*˜!°t·±Ñ.F—A™{ñ*ñ �	ñ ! Ó;Ð;ùò*s   ÁA0ÁA0)r/  rq  rV  )r/  zOptional[list[_T]]rq  zOptional[OrderedSet[_T]]r‹   rs  )rt  r^   r‹   rs  )rÿ  úDedupList[_T]r‹   r|  )	r{   r|   r}   r~   r#  r”  rË   rz  r�   )ry  s   €rj   ry  ro  r  s@   ø† ñð -1Ø7;ð=à)ð=ð 5ð=ð õ	=ô/÷<ò <rm   ry  r   c                óR   >• U TR                   ;   a  T" TR                   U    5      $ U $ ry   )rƒ  )rD  rÝ  ri   s    €€rj   rÝ  Ú.Scheduler.compute_dependencies.<locals>.rename·  s,   ø€ Ø�D×)Ñ)Ó)Ù˜d×3Ñ3°AÑ6Ó7Ð7ØˆHrm   Fc                óN   >• TT" U 5         R                  [        XU5      5        g ry   )rË   rÂ  )Úused_by_namer„  ru  rÄ  Úname_to_usersrÝ  s       €€rj   Úadd_userÚ0Scheduler.compute_dependencies.<locals>.add_user¼  s'   ø€ ð ™& Ó.Ñ/×6Ñ6Ü˜°Ó9õrm   Nc                ó   • U R                   $ ry   r×  rQ  s    rj   r‘  Ú0Scheduler.compute_dependencies.<locals>.<lambda>ß  s   € ÀAÇFÂFrm   rŒ  Tzscheduling %s)Úunbacked_onlyc                ó   • U R                   $ ry   r×  rQ  s    rj   r‘  r…  ò  s   €  !§&¢&rm   z not in )rL  )Úmutating_bufr
  )rÄ  )r
  zscheduling output %sz+scheduling output %s for unbacked symint %sr£  Ú'z': r:  r¤  zBUFFER USER LIST
z===== AFTER SCHEDULING =====
%s)rD  r  r‹   r  )FF)
r€  r  r„  rÃ  ru  rx   rÄ  rx   r‹   rs  )Er	   r^   rñ  r   r5  r—  r0  r’   r•   r=  r)   r=   r²   r>  rW   r¤   rò  rÃ   rô   r0  r    Ú	TensorBoxrÃ  r‘  Úget_unbacked_symbol_defsÚSymbolr°  r„  rß  r  rä  r3   rº   r­  r3  rF  r2   rL  r@  r/  r\   r4   Úadditional_buffer_depsÚadditional_star_depsr»   r¼   ru  rß  rƒ  ró  rñ  r/  r`  Úgraph_outputsr  r=  Úmutated_inputsr  r  r4  Úmutated_input_idxsrg  rW  rO   r«  rA  rB  r²  Úcompute_dependencies_log)*ri   r•   Úbuf1Ú	buf1_nameÚ	buf2_nameÚlist1Úlist2Úcombinedr�  r‚  Úunbacked_symbol_to_origin_nodeÚvalÚfsrÉ  Úsym_sizeÚhas_non_input_unbacked_defsÚunbacked_symbol_defsÚunbacked_symbol_usesr  rÄ   rÆ   Ú	node_modeÚalt_namerD  Úout_bufÚ
other_nameÚis_aliasÚadd_depr—  rR  rÌ   r¼   r½   Ú	inp_namesÚlogbufr  r4  r-  r  ry  r�  rÝ  s*   `                                      @@@rj   rZ   ÚScheduler.compute_dependenciesl  s…	  û€ ÷	<œ¤™ô 	<ô@ @K×?VÒ?VØó@
ˆð —J”JˆDØ×(Ñ(Ö*�Ø ŸM™M›O�	ô ˜tŸy™y×/Ñ/´·±×?Ñ?Ü˜D×,Ñ,Ó.Ó/°!Ó3áØ!%×!1Ñ!1Ö!3�IØ  MÓ1°iÀ=Ó6Pà -¨iÑ 8˜Ø -¨iÑ 8˜Ø#(¡=˜Û#0˜Cà -¨cÑ 2°eÒ ;Ø#0°Ñ#5¸Ô#>à5= ¨cÓ 2ó $1ð # mÓ3Ø3@ÀÑ3K˜ iÓ0à3@ÀÑ3K˜ iÓ0ó "4ó +ñ ÷<	ð 	ð !&Ø!ð		àð		ð <ð		ð ð			ð
 ð		ð ÷		ñ 		ð MOÐ&ô
 —7‘7×'Ñ'×.Ñ.Ö0ˆCÜ˜#œuŸz™z×*Ñ*Ø×*Ô*�BØ9=Ð2Ó6ó +ä˜C¤§¡×.Ó.ð (+§|¡|¤~ÓS¢~ !¼ÀAÄuÇzÁz×9RŸA¡~�ÐSÛ!�AØŸnœn˜Ø=AÐ6Ó:ó -ó "ñ 1ð ',Ð#Ø—J”JˆDØ—9‘9Ñ(Ð(Ð(ô $*Ø—	‘	×2Ñ2Ó4Ñ:Jñ$Ð ó *�Ü! !¤U§\¡\×2Ñ2Ð2Ð2ð /3Ð+ØÕ:Ø8<¿¹»Ð2Ó5ó *ñ ð  —J•JˆDÜ�I‰I�o t§y¡yÔ1æ*Ø—y‘yÑ,Ð,Ð,ä'-Ø—I‘I×2Ñ2ÀÐ2ÐFÙ(ñ(Ð$ó
 .�AØÓ>ð Ø˜#˜XÐ&DÐ%EÐFóÐ>ð <Ñ>Ð>˜ÓKØ#'×#4Ñ#4°QÑ#7×#CÑ#CÖ#E˜CØ ×-Ñ-¬g°c·l±l³nÓ.EÖFó $Fñ .ô �D×$Ñ$×+Ñ+Ó,°Ó1Ü ¤ d×&6Ñ&6×&=Ñ&=Ó!>Ó?Ð?�SÕ?Ü˜s¤I×.Ñ.àŸH™H‘	à �	ð ×'Ñ'×)�ä˜3×,Ñ,Ó.Ó/°1Ó4Ð4Ð4Ø #× 1Ñ 1× 3�HÙ% hÓ/�Há˜X tÔ,Ø×%Ñ%¤g¨h¸YÑ&GÔHØ -¨hÑ 7× =Ô =˜ØŸ=™=›?¨d¯m©m«oÓ=Ù$ä)¨$¯)©)Ô5F×GÑGÐGÐGØ'+§y¡y×'<Ñ'<Ö'>˜GØ)0×)9Ñ)9Ó);˜Já)/°
Ó);˜Jð (0°7×3FÑ3FÓ3HÑ'H˜HØ ×-Ñ-Ü 'Ø$.Ø14·±³Ø08¬Lñ!"ôñ % Z°¸tÔDó% (?ô !>ô !4ñ *ôB Ÿ7™7×9Ñ9¸$¿-¹-»/ÔJ�Ù˜ $°Ò5ð ×!Ñ!¤'¨'°4·=±=³?ÈDÑ"QÖRñ	 Kô Ÿ7™7×7Ñ7¸¿¹»ÔH�Ù˜ $°Ò6Ø×!Ñ!¤'¨'Ó"2Ö3ñ Ið
 ×(Ñ(×.Ô.�Ü! $¬×0Ó0Ù˜TŸY™Y¨×.>Ñ.>¸tÓ.DÖEñ /ð ×%Ñ% d×&;Ñ&;Ô<ð ×'Ñ'Ö)�Ø #× 1Ñ 1Ö 3�HØ>A¿l¹l»n�D×)Ñ)©&°Ó*:Ñ;Ø69·l±l³n�D×)Ñ)¨(Ñ3à×/Ñ/×3Ñ3°H¸hÓGð ×+Ñ+¨C¯L©L«NÓ;ó !4ô *ña ôr Ÿ™×0Ñ0Ö2ˆHÜ�I‰IÐ,¨hÔ7Ù�Xœz¬'°(Ó*;Ó<Ö=ñ 3ö
 'Ü—w‘w×,Ô,�Ø×1Ñ1ÀÐ1ÓE�AØÓ>ð Ø˜#˜XÐ&D×&IÑ&IÓ&KÐ%LÐMóÐ>ð ;Ñ=Ð=�q×=Ø(,×(9Ñ(9¸!Ñ(<×(MÑ(MÖ(O˜HÜŸI™IØ MØ (Ø !ôñ
 % X¬z¼'À(Ó:KÓ/LÖMó )Pó Fñ -ð ×)Ô)ˆDØ”q—w‘w×+Ñ+Ó+Ù˜œz¬'°$«-Ó8Ô9Ü—‘×&Ñ&×*Ñ*¨4Ö0ØœŸ™×*Ñ*Õ*á˜œz¬'°$«-Ó8Ö9ñ *ô ,5´Q·W±W×5IÑ5I×5NÑ5NÓ5PÔ+Qô
Ú+Q™K˜E 4ˆD�%ŠKÑ+Qð 	ñ 
ô )*¯©×(>Ò(>ó&
Ú(> ˆI�dŒOÑ(>ñ&
Œ�‰Ô"ð
 —J”JˆDØ×'Ñ'Ö)�Ø—‘˜m¨C¯L©L«NÑ;×AÑAÖBó *ñ ð ×/Ô/ˆDØ×'Ñ'¨Ñ-×7Ñ7¸ÀdÑ8K×8QÑ8QÖRñ 0ô  Ó!ˆØ�‰�cÔØ'×-Ñ-Ö/‰JˆC�Ø—‘•Ø/4¯{ª{Ó;ª{¨!˜Ÿ™ž©{�Ð;Ø—‘  #  c¨%¨°Ð2Ô3÷ !‘ñ 0ð 	�‰�cÔØ× Ñ Ó"×)Ñ)Ó+ˆÜ ×&Ñ&Ð';Ô<Ü ×&Ñ&Ð'IÈ3ÕOùòK TùóX
ùò&
ùò" <÷ !–ús6   Ç"#lÈ	lä2l
å!lélé*lêlìlì
l)	c           
     ó2  ^ ^• SSK JnJnJnJn  [        [        R                  R                  R                  5       5      nU" T R                  U5      n[        R                  R                  R                  (       d  U" T R                  T R                  5        [        [        R                  R!                  5       5      nU" T R                  UU5      u  n  n	[#        [%        T R                  5      5       V	s/ s H  n	/ / 4PM	     sn	mU H�  n
U
R&                  S:X  a  U
R(                  S:X  a  M%  U
R*                  R-                  5       nTU
R.                     S   R1                  U5        TU
R2                     S   R1                  U5        Mƒ     SSKJn  U" 5               SU U4S jjn/ n[9        T R                  5       HE  u  nnUR1                  U5        UR1                  U" Xÿ[%        T R                  5      S-
  :H  S95        MG     UT l
        g s  sn	f )Nr   )rù  Úcompute_memory_timelineÚFreeableInputBufferÚget_freeable_input_bufr   )Úregister_check_mem_opc                óN  >• TU    S   nTU    S   nX#U/n[         R                  " [        [        R                  " S5      S9[        R
                  R                  R                  R                  / US S9nSTR                  U    R                  5        3Ul        [        TU5      $ )Nr   r   rY  )r[  c                ó$   • U US   US   US   S.4$ )Nr   r   r±   )ÚaliveÚdeadÚis_final_steprw   )Útensor_argsrY  s     rj   r‘  ÚWScheduler.insert_memory_check_nodes.<locals>.construct_mem_check_node.<locals>.<lambda>²  s(   € Øà!.¨qÑ!1Ø -¨aÑ 0Ø)6°qÑ)9ññCrm   )r=  rU  r³  Únontensor_argsÚunflatten_argsÚ
mem_check_)r)   ÚMemoryCheckKernelr=   r¿  r[  r`  Ú_inductor_debugÚcheck_memory_stepÚdefaultr5  r0  r®  rë  )Ústep_idxr²  Úexpected_newly_aliveÚexpected_newly_deadrµ  r•   ri   Ústep_allocs_deallocss         €€rj   Úconstruct_mem_check_nodeÚEScheduler.insert_memory_check_nodes.<locals>.construct_mem_check_node¥  s¥   ø€ ð $8¸Ñ#AÀ!Ñ#DÐ Ø"6°xÑ"@ÀÑ"CÐà2ÈÐWˆNä×'Ò'Ü!¬¯ª°eÓ)<Ñ=Ü—y‘y×0Ñ0×BÑB×JÑJØØ-ñ ñˆDð %/¨t¯z©z¸(Ñ/C×/LÑ/LÓ/NÐ.OÐ"PˆDÔÜ,¨T°4Ó8Ð8rm   )r²  )r¼  r!  r²  rx   r‹   rë  )r.  rù  rª  r«  r¬  r   rW   r¤   rò  r  r5  r¿  rÀ  r&   rø  rX  r/  rî  r²   Ú
size_allocÚ	size_freer­  r0  Ú
start_steprË   Úend_stepÚ#torch._inductor.runtime.debug_utilsr­  r4  )ri   rù  rª  r«  r¬  rò  Úname_to_freeable_input_bufr�  Úbuf_info_listrŽ  Úbuf_inforR  r­  rÀ  Ú	new_nodesr1  r•   r¿  s   `                @rj   r>  Ú#Scheduler.insert_memory_check_nodes{  sÝ  ù€ ÷	
ó 	
ô )3´1·7±7×3GÑ3G×3LÑ3LÓ3NÓ(Oˆá" 4§:¡:¨|Ó<ð 	#ô �‰×%Ñ%×=×=Ù=Ø—
‘
˜D×,Ñ,ôô *4´A·G±G×4LÑ4LÓ4NÓ)OˆÙ5Ø�J‰JØ&Øó
Ñˆ�q˜!ô $¤C¨¯
©
£OÔ4óC
Ú4˜ˆR�‹HÑ4ñC
Ðó &ˆHà×"Ñ" aÓ'¨H×,>Ñ,>À!Ó,CÙà—‘×/Ñ/Ó1ˆHà  ×!4Ñ!4Ñ5°aÑ8×?Ñ?ÀÔIØ  ×!2Ñ!2Ñ3°AÑ6×=Ñ=¸hÖGñ &õ 	NáÔð	9Øð	9Ø*.ð	9à&÷	9ð 	9ð2 ˆ	ä  §¡Ö,‰GˆAˆtØ×Ñ˜TÔ"Ø×ÑÙ(¨ÄÀDÇJÁJÃÐRSÑ@SÑ;SÑUöñ -ð ˆ�
ùòeC
s   Ã8Hc                óÚ  ^	• [         R                  (       d  g/ n[        U R                  5       GH÷  nSS jm	SnUR	                  5        Hˆ  n[        U	4S jUR                   5       5      nU(       a]  [        R                  SUR                  5       5        [        R                  R                  R                  UR                  5       5        M†  SnMŠ     UR                  5       (       + =(       a    U(       + nU(       d  UR                  U5        Mä  [        R                  SUR                  5       5        [        R                  R                   R                  UR                  5       5        UR"                  R$                   Hž  nUR&                  U R(                  ;   d  M  U R(                  UR&                     R                  nU Vs/ s H2  oˆR*                  R                  5       UR                  5       :w  d  M0  UPM4     snU R(                  UR&                     l        M      GMú     [-        [        U5      5      U l        U R                   H  nUR/                  5         M     gs  snf )	z 
Remove any nodes without users
Nc                ó~   • U R                   =(       d+    U R                  5       [        R                  R                  ;   $ ry   )rÄ  r0  rW   r¤   r  )rD  s    rj   Úcan_eliminate_userÚ;Scheduler.dead_node_elimination.<locals>.can_eliminate_userÕ  s&   € Ø—|‘|×T t§}¡}£¼!¿'¹'×:TÑ:TÑ'TÐTrm   Fc              3  ó4   >#   • U  H  nT" U5      v •  M     g 7fry   rw   )r˜   ÚurÎ  s     €rj   rš   Ú2Scheduler.dead_node_elimination.<locals>.<genexpr>Ú  s   øé € Ð#MÂ9¸aÑ$6°q×$9Ð$9Â9ùó   ƒzremoved dead buffer: %sTzremoved dead operation: %s)rD  rÂ  r‹   rx   )r&   Úuse_dcer´   r5  r—  rœ   r-  r°  r„  r0  rW   r¤   r�  r  rx  rË   r  rº   r»   r¼   rX  r•   r  r%  )
ri   Úupdated_nodesr•   Úactive_buffersrÄ   Úcan_eliminater—  r-  rÑ  rÎ  s
            @rj   r  ÚScheduler.dead_node_eliminationÈ  s°  ø€ ô �~�~Øð
 ˆÜ˜TŸZ™Z×(ˆDôUð #ˆNØ×'Ñ'Ö)�Ü #Ô#MÀ3Ç9Â9Ó#MÓ M�Þ Ü—I‘IÐ7¸¿¹»ÔHÜ—G‘G×+Ñ+×/Ñ/°·±³Ö?à%)’Nñ *ð !%× 5Ñ 5Ó 7Ô7×NÀÔ<NˆMæ Ø×$Ñ$ TÖ*ô —	‘	Ð6¸¿¹»ÔHÜ—‘×*Ñ*×.Ñ.¨t¯}©}«Ô?Ø ×,Ñ,×2Ô2�DØ—y‘y D×$4Ñ$4Õ4Ø $× 0Ñ 0°·±Ñ ;× AÑ A˜á',ó=Ú', !·±·±Ó0AÀTÇ]Á]Ã_Ñ0TŸA¡uñ=˜×(Ñ(¨¯©Ñ3Ö9ô 3ñ- )ô8 œ( =Ó1Ó2ˆŒ
ð —J”JˆDØ× Ñ Ö"ò ùò=s   Ç
/I(Ç=I(c                ó
   • USL$ )z:Check if store mode requires cross-thread synchronization.Nrw   )ri   rL  s     rj   Úmode_requires_synchronizationÚ'Scheduler.mode_requires_synchronizationõ  s   € à˜4ÐÐrm   c                óÌ   ^^^^• [         [           " 5       m[        5       m/ mSUUUU4S jjmU H  nUR                  5        H  nUTU'   M
     M!     U H  nT" U5        M     T$ )z/
Ensure nodes is in topologically sorted order
c                óÞ   >• U T;  af  TR                  U 5        [        U R                  S S9 H*  nUR                  T;  a  M  T" TUR                     5        M,     TR	                  U 5        g g )Nc                ó   • U R                   $ ry   r×  )Úds    rj   r‘  ÚDScheduler.topological_sort_schedule.<locals>.visit.<locals>.<lambda>  s   € ÀaÇfÂfrm   rŒ  )r  r‘  rŒ  r¼   rË   )rD  rÆ   r  rC  ÚseenÚvisits     €€€€rj   râ  Ú2Scheduler.topological_sort_schedule.<locals>.visit  sa   ø€ Ø˜‹}Ø—‘˜”Ü! !×"6Ñ"6Ñ<LÔM�Cà—x‘x |Ó3Ù Ù˜, s§x¡xÑ0Ö1ñ	 Nð
 —‘˜aÕ ð rm   )rD  r\   r‹   rs  )r   r\   r(  r=  )ri   r5  r•   r¼   r  rC  rá  râ  s       @@@@rj   r  Ú#Scheduler.topological_sort_scheduleù  sj   û€ ô Ô+Ò,Ó.ˆÜ59³VˆØ*,ˆ÷	!ò 	!ó ˆDØ×-Ñ-Ö/�Ø%)�˜TÓ"ó 0ñ ó ˆDÙ�$ŽKñ àˆrm   c                óN  ^ • [        5       n[        U[        [        [        [
        [        45      (       a/  UR                   H  nUR                  UR                  5        M      O[        S[        U5       S35      eU 4S jU 5       n[        [        U 4S jU 5       5      5      $ )Nz+get_unmet_dep_nodes is not implemented for Ú.c              3  ó^   >#   • U  H"  nTR                   U   R                  5       v •  M$     g 7fry   )rX  r2  r  s     €rj   rš   Ú1Scheduler._get_unmet_dep_nodes.<locals>.<genexpr>&  s(   øé € ÐXÊZÀc˜×)Ñ)¨#Ñ.×?Ñ?×AÐAÊZùr  c              3  óB   >#   • U  H  nTR                   U   v •  M     g 7fry   ©r)  )r˜   rD  ri   s     €rj   rš   rè  '  s   øé € ÐQÂ=¸a˜t×6Ñ6°qÖ9Â=ùs   ƒ)r   r’   r“   rë  r‘  r¿   rm  rŒ  r  r¼   ÚRuntimeErrorrÀ   r  )ri   r\  Ú
unmet_depsrÆ   Úunmet_dep_opss   `    rj   Ú_get_unmet_dep_nodesÚScheduler._get_unmet_dep_nodes  s’   ø€ Ü&0£lˆ
ÜØäÜ)Ü&Ü"Ü$ð÷	
ñ 	
ð ×/Ô/�Ø—‘˜sŸx™xÖ(ò 0ô Ø=¼dÀ5»k¸]È!ÐLóð ô YÉZÓXˆÜ”JÔQÁ=ÓQÓQÓRÐRrm   c                ó´  • / n[         R                  U R                  S5      n0 nU R                   HQ  nU R                  U5      n[	        U5      X$'   U H*  nUR                  U/ 5      nUR                  U5        XsU'   M,     MS     UR                  5        VV	s/ s H  u  p‰U	S:X  d  M  UPM     n
nn	U
(       a…  UR                  U
5        U
 H9  nUR                  U/ 5       H  nX+==   S-  ss'   M     UR                  U5        M;     UR                  5        VV	s/ s H  u  p‰U	S:X  d  M  UPM     n
nn	U
(       a  M…  U(       a   S5       eU$ s  sn	nf s  sn	nf )zE
Sort nodes by their topological order, return a list of node lists.
r   r   zTopological sort failed!)	r(  Úfromkeysr5  rî  r²   rñ  rË   r/  r  )ri   r©  r5  Úchildrenr•   r  rÆ   ÚcrD  r4  Úzero_deg_nodesrD  s               rj   rC  Ú!Scheduler._topological_sort_nodes)  s,  € ð ˆÜ—‘˜dŸj™j¨!Ó,ˆØ#%ˆØ—J”JˆDØ×,Ñ,¨TÓ2ˆDÜ˜d›)ˆE‰KÛ�Ø—L‘L  bÓ)�Ø—‘˜”Ø !˜“ó ñ ð ).¯©¬Ô@ª¡ ¸¸a¹Ÿ!©ˆÑ@ÞØ�L‰L˜Ô(Û#�Ø$ŸL™L¨¨BÖ/�DØ“K 1Ñ$•Kñ 0à—	‘	˜!–ñ $ð -2¯K©K¬MÔDªM¡D A¸QÀ!¹VŸa©MˆNÑD÷ ˆnö Ð4Ð4Ó4ˆyØˆùó Aùó Es   ÂEÂ)EÄEÄ,Ec                ój  • 0 nU R                    Hw  n[        5       nUR                   HB  nU R                  UR                     R                  5       nUR                  U5        X1U   -  nMD     X1UR                  5       '   X2l        My     [        U R                   5       H  u  pbXbl
        Xbl        M     g)z
Populate each node.ancestors
N)r5  r   rŒ  rX  r¼   r2  r  r0  rï   r4  r  r€  )ri   Úname_to_ancestorsr•   rï   rÆ   Údep_node_namer©  s          rj   r  ÚScheduler.compute_ancestorsC  s›   € ð
 9;ÐØ—J”JˆDÜ)3«ˆIØ×.Ô.�Ø $× 0Ñ 0°·±Ñ :× KÑ KÓ M�Ø—‘˜mÔ,Ø¨}Ñ=Ñ=’	ñ /ð 2;˜dŸm™m›oÑ.Ø&ŽNñ ô % T§Z¡ZÖ0‰KˆEØ"ŒNØ"ŽNò 1rm   c                óˆ  • [         R                  (       d  g U R                   Hœ  n[        U[        [
        45      (       a)  UR                  5       (       d  [         R                  S:w  a  MI  UR                  5        H?  n[        U[        5      (       a  UR                  5       (       a  M/  UR                  5         MA     Mž     g )NÚhalide)r&   rÎ  r5  r’   r“   r¿   rR   Úcpu_backendr�   rj  r  )ri   r•   r\  s      rj   r  ÚScheduler.merge_loopsV  s‡   € Ü×0×0Øà—J”JˆDô ˜d¤]Ô4FÐ$G×HÑHØ—K‘K—M‘M¤f×&8Ñ&8¸HÓ&DáØŸ™Ö)�ä! %¬×7Ñ7¸5×;LÑ;L×;NÑ;NÙà×!Ñ!Ö#ó *ò rm   c                óì  • [        SSSS9   [        S5       H„  n[        U5      n[        R	                  SUS-   U5        U R                  USS9n[        U5      n[        R	                  S	US-   UU5        XC:X  d  US:X  d  Mk  [        R	                  S
US-   5          O   [        R                  (       d  [        R                  (       a  U R                  USS9nUsSSS5        $ ! , (       d  f       g= f)z2
Combine eligible nodes into FusedSchedulerNodes.
zScheduler.fused_nodesTrô  rn  z/===== attempting fusion (%d/10): %d nodes =====r   F)Úis_reorder_roundz=completed fusion round (%d/10): fused %d nodes into %d nodes
z+===== fusion complete (%d iterations) =====N)	r   rî  r²   rƒ  r„  Úfuse_nodes_oncer&   rÎ  Úloop_index_inversion_in_fusion)ri   r5  r1  Úold_lenÚnew_lens        rj   rw  ÚScheduler.fuse_nodesq  sì   € ô Ø#¸4ÐQUó
ô ˜2–Y�Ü˜e›*�Ü× Ñ ØEØ˜‘EØôð
 ×,Ñ,¨UÀUÐ,ÐK�Ü˜e›*�Ü× Ñ ØTØ˜‘EØØô	ð Ó%¨°A­Ü×$Ñ$ØEÀqÈ1Áuôñ ñ' ô, ×1×1Ü×8×8à×,Ñ,¨UÀTÐ,ÐJ�Ø÷;
÷ 
÷ 
ús   ŒA3C%ÂAC%Ã%
C3c                ó¨   • / nU R                    H:  nUR                  [        U[        5      (       a  UR	                  5       OU/5        M<     Xl         g)z1
Unpack GroupedSchedulerNode into regular nodes.
N)r5  r  r’   rm  rx  )ri   rÊ  r•   s      rj   r6  ÚScheduler.process_grouped_nodes”  sF   € ð .0ˆ	Ø—J”JˆDØ×ÑÜ!+¨DÔ2F×!GÑ!G�—‘”ÈdÈVöñ ð �
rm   c                óæ   • [        U5      S:”  d   eUS   R                  5       nX l        U R                  U5      n[	        SSSS9   UR                  U5      sSSS5        $ ! , (       d  f       g= f)úk
Benchmark fused list of nodes and return the execution time
in milliseconds on randomly generated inputs.
r   Úbenchmark_fused_nodesTÚcompile_time_autotune_time_us)rõ  Údynamo_compile_column_usN)r²   rî   rN  rÌ  r   r	  )ri   r5  r[  r  s       rj   r	  ÚScheduler.benchmark_fused_nodesŸ  sm   € ô �5‹z˜A‹~Ðˆ~Ø�q‘×$Ñ$Ó&ˆØ$ÔØ×"Ñ" 6Ó*ˆÜØ#Ø"&Ø%Dó
ð
 ×0Ñ0°Ó7÷
÷ 
÷ 
ús   ÁA"Á"
A0c                óä   • [        U5      S:”  d   eUS   R                  5       nX@l        U R                  U5      n[	        S5         UR                  XUS9sSSS5        $ ! , (       d  f       g= f)r  r   Úgenerate_kernel_code_from_nodes©Úhint_overrideN)r²   rî   rN  rÌ  r   r  )ri   r5  Úbenchmark_kernelr  r[  r  s         rj   r  Ú)Scheduler.generate_kernel_code_from_nodes±  si   € ô �5‹z˜A‹~Ðˆ~Ø�q‘×$Ñ$Ó&ˆØ$ÔØ×"Ñ" 6Ó*ˆÜÐ;Õ<Ø×:Ñ:Ø°}ð ;ð ÷ =×<×<ús   ÁA!Á!
A/c                óž   • X l         U R                  U5      n[        S5         UR                  U5      sSSS5        $ ! , (       d  f       g= f)r  Úbenchmark_codegened_moduleN)rN  rÌ  r   r  )ri   Úmoduler[  r  s       rj   r  Ú$Scheduler.benchmark_codegened_moduleÄ  s=   € ð %ÔØ×"Ñ" 6Ó*ˆÜÐ6Õ7Ø×5Ñ5°fÓ=÷ 8×7×7ús	   £>¾
Ac                ó  • [         R                  R                  nU(       d  g[        R	                  SX5        UR
                   HÂ  nUR                  5       n[        USS5      (       a  XB;  a  M,  UR                  nX$   n[        U[        R                  5      (       a'  UR                  UR                  5        UR                  n[        U[        R                  5      (       d  M£  Xe:w  d  Mª  [        R                  SUUU5          g   g)zˆ
Check if selecting a Triton template would cause layout conflicts.
Returns True if there's a conflict and we should fall back to ATen.
FzNode %s has constraints %sr=  NzOLayout conflict detected for %s: template expects %s but layout is frozen to %sT)rW   r¤   Úbuffer_layout_constraintsr°  r„  rW  r0  r¬  r=  r’   r)   ÚFlexibleLayoutÚ freeze_layout_with_exact_stridesrÔ  ÚFixedLayoutr±  )ri   Ú
multi_nodeÚconstraintsÚinpÚinp_namer=  Úexpected_layouts          rj   Ú!_has_layout_conflict_for_templateÚ+Scheduler._has_layout_conflict_for_templateÐ  sÕ   € ô —g‘g×7Ñ7ˆÞØä�	‰	Ð.°
ÔHØ×$Ô$ˆCà—|‘|“~ˆHÜ˜3 ¨$×/Ñ/°8Ó3NÙà—Z‘ZˆFØ)Ñ3ˆOÜ˜&¤"×"3Ñ"3×4Ñ4ð ×4Ñ4°_×5KÑ5KÔLØŸ™�ä˜&¤"§.¡.×1Ó1°oÕ6Oä—‘ØeØØ#Øô	ñ ñ- %ð0 rm   c           
     ó0  • [        U R                  5       GHe  u  p[        U[        5      (       d  M  [        UR                  [
        R                  5      (       d  MH  UR                  n[        R                  R                  (       d  UR                  5       u  pEO [        S UR                  5        5       5      n[        U[        R                  R
                  R                  5      (       až  U R!                  U5      (       aˆ  UR                  5        H:  n[        U[        R                  R"                  R$                  5      (       d  M8  Un  O   [        W[        R                  R"                  R$                  5      (       d   S5       e[        U[        R                  R
                  R                  5      (       aÖ  [        R&                  (       a£  0 nXGS'   [        R&                   Hm  nUR                  US9n	U	R)                  5        V
Vs0 s H  u  p«[        U
[        5      (       d  M  X«_M      nn
n[+        UR)                  5       S S9S   nXgU'   Mo     UR                  R-                  U5        OUR                  R/                  U5        GM€  [
        R0                  R3                  UR4                  5         UR7                  5       nSSS5        WR8                  n[        U[
        R:                  5      (       d   eUR8                  n[        U[
        R<                  5      (       d   eUR>                  (       a  [A        XÓR>                  5        URB                  Ul!        U RE                  XóX5        GMh     gs  snn
f ! , (       d  f       N½= f)aP  
Finalize a backing choice for MultiTemplateBuffers which did not already have a
choice finalized through fusion. In the case of an extern choice, this will result
in replacing the SchedulerNode.

If a MultiTemplateBuffer did not have any fusion opportunities, finalizing a choice
will force completion of compilation and benchmarking.
c              3  ó�   #   • U  H<  n[        U[        R                  R                  R                  5      (       d  M8  Uv •  M>     g 7fry   )r’   r¿  rÀ  r)  ÚExternKernelCaller)r˜   Útimings     rj   rš   Ú<Scheduler.finalize_multi_template_buffers.<locals>.<genexpr>	  s7   é € ð â*E Ü)Ø &Ü %§¡× @Ñ @× SÑ S÷ ÷ #™FÚ*Eùs
   ‚7A½	AzZNo extern kernel detected to fallback to when layout constraints fail for Triton templatesNr  c                ó   • U S   $ r  rw   rQ  s    rj   r‘  Ú;Scheduler.finalize_multi_template_buffers.<locals>.<lambda>9  s	   € ÈqÐQRÊtrm   rŒ  r   )#r4  r5  r’   r“   r•   r)   ÚMultiTemplateBufferr&   r<  Ú%force_extern_kernel_in_multi_templateÚget_min_choicer3  Úchoice_timingsr¿  rÀ  r   r!  r)  r%  Úmulti_kernel_hintsr/  rä  Úfinalize_as_triton_callersÚfinalize_as_triton_callerr	  Úcurrent_originsr¯  Úoutput_noderã   Ú
StorageBoxÚOperationBufferÚorigin_noder8   r=  Ú_replace_node)ri   r1  r•   r  Úmin_node_unfusedrŽ  ÚchoiceÚcallersÚhintÚtimingsrò  r4  Útriton_timingsÚout_tensorboxÚout_storageÚ
out_buffers                   rj   r&  Ú)Scheduler.finalize_multi_template_buffersö  sã  € ô ! §¡×,‰GˆAÜ˜$¤×.Ó.´:Ø—	‘	œ2×1Ñ1÷4ó 4ð "ŸY™Y�
Ü×*Ñ*×P×PØ*4×*CÑ*CÓ*EÑ'Ð$ aä'+ñà*4×*CÑ*CÔ*Eóó	(Ð$ô Ø$Ü—O‘O×&Ñ&×?Ñ?÷ñ ð
 ×=Ñ=¸j×IÑIà&0×&?Ñ&?Ö&A˜FÜ)Ø &Ü %§¡× @Ñ @× SÑ S÷ ó  ð 4:Ð 0Ù %ñ 'Bô  *Ø"¤E§O¡O×$DÑ$D×$WÑ$W÷ ñ  ð ð yóð  ô Ø$Ü—O‘O×&Ñ&×?Ñ?÷ñ ô
 ×0×0ØQS˜Ø(8 ™ô %+×$=Ô$=˜DØ&0×&?Ñ&?ÈdÐ&?Ð&S˜Gð -4¯M©M¬Oô.â,;¡D AÜ#-¨aÔ1I×#Jó !% ¢Ù,;ð +ñ .ô
 &)¨×)=Ñ)=Ó)?Á^Ñ%TÐUVÑ%W˜FØ,2 D›Mñ %>ð Ÿ	™	×<Ñ<¸WÕEàŸ	™	×;Ñ;Ð<LÔMÚä—Y‘Y×.Ñ.¨z×/AÑ/AÕBØ$4×$@Ñ$@Ó$B�M÷ Cà+×0Ñ0�Ü! +¬r¯}©}×=Ñ=Ð=Ð=Ø(×-Ñ-�
Ü! *¬b×.@Ñ.@×AÑAÐAÐAà×)×)Ü& }×6LÑ6LÔMà$.×$5Ñ$5�
Ô!Ø×"Ñ" :¸1×CòY -ùóh.÷ CÕBús   ÈN
È/N
Ê?NÎ
N	c                óš  ^• [        X!5        U R                  U5      nXPR                  U'   XPR                  UR	                  5       '   XPR
                  UR	                  5       '   0 m[        R                  " UR                  R                  UR                  5       HA  nU R                  R                  UR                  S 5      =n(       d  M2  UR                  TU'   MC     SU4S jjnU" UR                  5      Ul
        U" UR                  R                  5      UR                  l	        [        UR                  5       UR                  5       5       H2  u  pšX�R                   U
R	                  5       '   U
R"                  U	l        M4     UR$                  Ul        UR&                  Ul        UR(                  Ul        UR*                  Ul        g )Nc                ó.   >• [        U4S jU  5       5      $ )Nc              3  óD   >#   • U  H  oR                  T5      v •  M     g 7fry   )rÝ  )r˜   rÆ   rƒ  s     €rj   rš   Ú?Scheduler._replace_node.<locals>.rename_deps.<locals>.<genexpr>c  s   øé € ÐKÂd¸sŸj™jÐ)9×:Ð:Âdùs   ƒ r   )r  rƒ  s    €rj   Úrename_depsÚ,Scheduler._replace_node.<locals>.rename_depsb  s   ø€ ÜÔKÁdÓKÓKÐKrm   )r  r‹  r‹   r‹  )r¸  r  r5  r  r0  r)  r  r  rº   r»   rŒ  ró  rñ  r¼   r)  r—  rX  r-  r  r€  rï   r~  )ri   r?  r  r1  r•   Únew_scheduler_noderÆ   Ú	real_namerE  Únew_outÚold_outrƒ  s              @rj   r6  ÚScheduler._replace_nodeN  s{  ø€ ô 	" *Ô9Ø!×7Ñ7¸
ÓCÐà*�
‰
�1‰Ø-?×Ñ˜$Ÿ-™-›/Ñ*Ø3E×Ñ §¡£Ñ0ð ÐÜ—?’? 4×#3Ñ#3×#9Ñ#9¸4×;RÑ;RÖSˆCØ ×3Ñ3×7Ñ7¸¿¹À$ÓGÐGˆy×GØ.1¯h©hÐ  Ó+ñ T÷	Lñ 1<Ø×1Ñ1ó1
ÐÔ-ñ 0;Ø×*Ñ*×0Ñ0ó0
Ð×&Ñ&Ô,ô !$Ø×*Ñ*Ó,¨d×.>Ñ.>Ó.@ö!
ÑˆGð 4;×Ñ˜W×-Ñ-Ó/Ñ0Ø#ŸM™MˆGŽMñ	!
ð (,§~¡~ÐÔ$Ø'+§~¡~ÐÔ$Ø'+§~¡~ÐÔ$Ø(,¯©ÐÕ%rm   c                ó&   • [        S U 5       5      $ )Nc              3  ó  #   • U  H�  n[        UR                  S 5      =(       a_    UR                  SL=(       aJ    [        UR                  R                  S5      =(       a#    UR                  R                  R                  S:H  v •  Mƒ     g7f)rã   NÚscatter_moderM  )rT  r•   rã   rN  rC  s     rj   rš   Ú,Scheduler._any_atomic_add.<locals>.<genexpr>x  sp   é € ð 
ò
 �ô	 �A—F‘F˜FÓ#÷ 9Ø—‘˜dÐ"÷9ä˜Ÿ™Ÿ™ ^Ó4÷9ð —‘—‘×(Ñ(¨LÑ8ô9ò ùs   ‚B	B)rö   )ri   Ú	node_lists     rj   Ú_any_atomic_addÚScheduler._any_atomic_addw  s   € Üñ 
ñ
 ó
ó 
ð 	
rm   c                ó(  • U R                  USUS9n[        R                  " U5      n[        R                  R
                  R                  5       nUR                  5       (       d  S nXd4$ UR                  SUS9n[        U[        5      (       d   eXd4$ )NT)r  r  Útriton_)Úkernel_nameÚsource_code)r  r   Úloadr¿  rÀ  Úasync_compileÚAsyncCompileÚuse_process_poolrá   r’   r   )ri   r5  r  Úsrc_codeÚmodrX  Úfuts          rj   Úcompile_kernelÚScheduler.compile_kernel€  sš   € ð ×7Ñ7Ø D¸ð 8ð 
ˆô ×Ò˜xÓ(ˆÜŸ™×5Ñ5×BÑBÓDˆØ×-Ñ-×/Ñ/ØˆCð
 ˆzÐð  ×&Ñ&°9È(Ð&ÐSˆCÜ˜c¤<×0Ñ0Ð0Ð0àˆzÐrm   c                ó˜  ^ ^^^^^^^^^^ ^!^"^#^$^%^&^'^(^)^*• [        S TT4 5       5      n[        R                  (       d  U(       d  [        R	                  S5      $ TR                  5       (       a-  [        TR                  5       [        R                  5      (       a*  TR                  5       (       d  TR                  5       (       a  [        R	                  S5      $ TR                  5       nUS   R                  5       mT(       d   eTR                  S:X  a)  [        R                  S:w  a  [        R	                  S5      $ TR                  5       n[        [         R"                  " XE5      5      nT R%                  U5      (       a  [        R	                  S5      $ SSKJm  [+        TT5      m*US   R                  5       mTc   eSUU4S jjm$U(       Gau  [        S	 TT4 5       5      (       Ga[  TR                  5       SLmT(       a  TR                  5       OTR                  5       m)[        T)[        R,                  5      (       d   eT R/                  T)5      (       a  [        R	                  S
5      $ 0 m#/ m![        R0                   GHI  nT)R3                  U5      m[5        TR7                  5       S S9 H€  u  p‰[        U[8        R:                  R<                  R>                  5      (       d  M:  T)RA                  U5         T!RC                  U/T RE                  XhRF                  S9Q75        SSS5        M‚     [I        S5      n
Sn0 nT! HW  u  p�n Ub  URK                  5         T)RA                  U5         T R[                  UT5      u  nnUXÈ'   UU
:  a  Un
UnSSS5        MY     UT)R\                  U'   [        U[^        5      (       d   eUT#U'   GML     [        R`                  m[c        S T)Rd                   5       5      n[g        5       =(       a!    T(       + =(       a    U[        Rh                  :*  m"[I        S5      [I        S5      sm&m'Sm%T"(       dP  T)R3                  5       mT)Rk                  5       u  m%m&[5        TR7                  5       [l        Rn                  " S5      S9nOT)Rd                   Vs/ s H  nUS4PM	     nnT(       a-  T(       a  T Rq                  U5      OT Rq                  U5      u  m'nO9T(       d  [        R	                  S
5      $ TRs                  5       m'[u        TTT'5      m(/ m!SnU H¼  u  nn[        U[^        5      (       d  M  T(       d-  [w        US5      (       a  URx                  T)Rx                  :w  a  MQ  T(       a  UT&T'-   :¼  a    O]US-  nU[        Rh                  :”  a    OBT)RA                  U5         T!RC                  U/T RE                  U5      Q75        SSS5        M¾     [{        T!5      S:X  a  [        R	                  S
5      $ SUUUUU!U"U#U$U%U&U'U(U)U 4S jjn[        R}                  UT!S   S   5      $ T RE                  U5      mT RE                  U5      m T RE                  U5      mSUUUUU U$U U*4S jjn[        R}                  UTS   S9$ ! , (       d  f       GMý  = f! [L         a]  n[N        RQ                  [R        RT                  5      (       a)  [N        RW                  ST(       d  SOS[Y        U5      5         SnAGMÍ  SnAff = f! , (       d  f       GMå  = fs  snf ! , (       d  f       GM  = f)úo
If config.benchmark_fusion is False, always return True.
Otherwise, return True if fusion can brings speedup.
c              3  ó    #   • U  HD  nUR                  5       =(       a(    [        UR                  5       [        R                  5      v •  MF     g 7fry   )rj  r’   r&  r)   r*  rC  s     rj   rš   Ú.Scheduler.speedup_by_fusion.<locals>.<genexpr>˜  sD   é € ð  
ò $�ð �M‰M‹O÷ JÜ˜1×.Ñ.Ó0´"×2HÑ2HÓIôJâ#ùs   ‚AATr   rY  rá   ©ÚCompilationErrorNc           
     óz  >• [         R                  [        R                  5      (       a’  XU-   :  aE  [         R	                  STR                  5       TR                  5       [        X-   U -  S 5      5        g [         R	                  STR                  5       TR                  5       [        XU-   -  S 5      5        g g )Nz9can fuse (benchmark): fusing %s with %s cause %sx speedupú.3fz=cannot fuse (benchmark): fusing %s with %s cause %sx slowdown)rƒ  rZ  r[  ÚDEBUGr„  r=  rB   rC   )Úms_fusedÚms1Úms2r…   r†   s      €€rj   Ú
log_fusionÚ/Scheduler.speedup_by_fusion.<locals>.log_fusionÁ  s£   ø€ Ü×&Ñ&¤w§}¡}×5Ñ5Ø C™iÓ'Ü×$Ñ$ØSØ×.Ñ.Ó0Ø×.Ñ.Ó0Ü" s¡y°HÑ&<¸SÐ%AÓCõ	ô ×$Ñ$ØWØ×.Ñ.Ó0Ø×.Ñ.Ó0Ü  H°c±	Ñ$:¸3Ð#?ÓAõ	ð 6rm   c              3  óD   #   • U  H  oR                  5       S Lv •  M     g 7fry   r*  rC  s     rj   rš   rc  Ò  s   é € ð %
Ú7E°!×ÑÓ!¨Õ-²~ùs   ‚ Fc                ó   • U S   $ r  rw   rQ  s    rj   r‘  Ú-Scheduler.speedup_by_fusion.<locals>.<lambda>æ  s	   € ÈaÐPQÊdrm   rŒ  r  ÚinfúException in compiling %s: %sr7  r9  c              3  óB   #   • U  H  n[        U[        5      v •  M     g 7fry   )r’   r   )r˜   ró  s     rj   rš   rc    s   é € ð %ÚAS¸A”
˜1Ô6×7Ð7ÒASùó   ‚r   Úallowed_prologue_inpsc            	     ó¨  >• [        S5      n S n0 nT(       aY  T(       a  [        T[        R                  5      (       d   eTR	                  5       mTR                  5       u  mm[        TU4S jS9mT Hî  u  p4n Ub  UR                  5       nO'T(       d  UR                  nUR                  5         OS n T(       a=  TR#                  U5         TR%                  UT5      u  p‰X‚U'   X€:  a  Un UnS S S 5        M†  TU:H  =(       d    TT-   TU   T-   :„  n
U(       d  M©  ['        UR(                  5      S:X  d  MÄ  UR(                  S   R*                  S	::  d  Mã  U
(       d  Mì  Un  O   T(       a
  T" U TT5        T(       a	  U TT-   :  aP  UbM  [,        R.                  (       a  UTS '   TR1                  T5        OTR3                  U5        UTR4                  S '   g
g! [         a]  n[        R                  [        R                  5      (       a)  [        R                  ST(       d  SOS[!        U5      5         S nAGMÆ  S nAff = f! , (       d  f       GMÞ  = f)Nrq  c                ó   >• TU S      $ rÑ   rw   )r™  r-  s    €rj   r‘  ÚKScheduler.speedup_by_fusion.<locals>.benchmark_when_ready.<locals>.<lambda>f  s   ø€  n°Q°q±TÒ&:rm   rŒ  rr  r7  r9  r   r   rA  TF)r  r’   r)   r*  r-  r,  r‘  rC  rT  Ú
precompiler¯  rƒ  rZ  r[  rh  r„  r  Úswap_as_triton_callerr  r²   Ú	launchersÚn_spillsr&   r.  r/  r0  Ú_choice_timings)Úmin_ms_fusedÚms_fused_choiceÚnew_timingsr8  rf   Ú	mod_fusedÚresr  ri  ÚpathÚfusible_choiceÚbench_epiloguer-  r[  rá  Úfuture_choicesÚget_choice_timings_asyncÚ hint_override_best_fusion_choicerl  Ú
min_choicerj  rk  Ú	ms2_fusedr  ri   s              €€€€€€€€€€€€€€rj   Úbenchmark_when_readyÚ9Scheduler.speedup_by_fusion.<locals>.benchmark_when_readyY  s,  ø€ ä$ U›|�Ø"&�Ø �æ+Þ%¬*°ZÄ×AWÑAW×*XÑ*XÐXÐXØ%/×%>Ñ%>Ó%@�NØ&0×&?Ñ&?Ó&A‘O�J ä%+Ø&Ü:ñ&�Nó
 2@Ñ-�F Ið!Ø!Ñ-Ø"(§-¡-£/™CÞ!/Ø"+×"3Ñ"3˜CØŸN™NÕ,à"&™Cö &à'×=Ñ=¸fÕEØ-1×-LÑ-LØ )à &ó.™N˜Hð
 3;¨Ñ/Ø'Ó6Ø/7 Ø28 ÷ FÑEð '¨&Ñ0÷ NØ" S™y¨>¸&Ñ+AÀIÑ+MÑMð '÷  ˜Cä # C§M¡MÓ 2°aÕ 7à #§¡¨aÑ 0× 9Ñ 9¸QÕ >ß . à.4˜OÙ!ña 2@öd "Ù˜|¨S°#Ô6ö '¨,¸#À¹)Ó*DØ%Ñ1Ü×0×0ØAPÐ8¸Ñ>à"×=Ñ=Ø<õð
 #×<Ñ<¸_ÔMð 8C�J×.Ñ.¨tÑ4Øà øôu %ó !Ü%×2Ñ2´7·=±=×AÑAÜ&×,Ñ,Ø ?Þ2A¡
ÀzÜ # A£ôö
 !ûð!ú÷ F×Eús1   Á:GÂ#GÂ2GÃ"IÇ
H>Ç!AH9È9H>É
I	c                 ó(  >^^^^^^• SSK Jn    TS   TS   TS   4 H  nUc  M  UR                  5         M     TR                  TS   T
5      u  mm[        R
                  " T5      (       a	  T" S5        gTR                  TS   T
5      u  mm[        R
                  " T5      (       a	  T" S5        gTR                  TS   T
5      u  mm[        R
                  " T5      (       a	  T" S5        gT" TTT5        [        S5      (       a[  TTT-   :¼  aR  TT4TR                  ;  a@  TR                  R                  TT45        [        S5      R                  UUUUUU4S	 j5        TTT-   :  $ ! U  a     gT	 a  nS
[        U5      ;   a   S nAge S nAff = f)Nr   )ÚNoTritonConfigsErrorr   z%register spilling of the first kernelFz&register spilling of the second kernelz%register spilling of the fused kernelÚslow_fusionc            	     ó$   >• TT TTTTTT T-   -  S.$ )N)Úkernel1_pathÚkernel1_latencyÚkernel2_pathÚkernel2_latencyÚfused_kernel_pathÚfused_kernel_latencyÚslow_down_ratiorw   )rj  rk  ri  Úpath1Úpath2Ú
path_fuseds   €€€€€€rj   r‘  rx  î  s&   ø€ Ø05Ø36Ø05Ø36Ø5?Ø8@Ø3;¸sÀS¹yÑ3Iò%rm   úLoop-carried variableT)Ú)torch._inductor.runtime.triton_heuristicsrŽ  rC  r  ÚmathÚisinfr   r!  r  r   rC  r  )rŽ  r]  r  rj  rk  ri  r˜  r™  rš  re  r[  Úfuture_and_mod_l1Úfuture_and_mod_l1_fusedÚfuture_and_mod_l2rl  ri   r  s      @@@@@@€€€€€€€€rj   r‹  rŒ  »  s¡  þ€ õðAð *¨!Ñ,Ø)¨!Ñ,Ø/°Ñ2ó ˜ð
 ›?ØŸJ™JžLñ ð "&×!@Ñ!@Ø)¨!Ñ,àó"‘J�C˜ô
 —z’z #—‘ÙÐCÔDØ$à!%×!@Ñ!@Ø)¨!Ñ,àó"‘J�C˜ô
 —z’z #—‘ÙÐDÔEØ$à+/×+JÑ+JØ/°Ñ2àó,Ñ(�H˜jô
 —z’z (×+Ñ+ÙÐCÔDØ$á˜x¨¨cÔ2ô 0°×>Ñ>Ø$¨¨c©	Ó1Ø" E˜N°$×2IÑ2IÓIà×/Ñ/×3Ñ3°U¸E°NÔCÜ(¨Ó7×?Ñ?÷ñ ô
ð $ c¨C¡iÑ/Ð/øà+ó !Ù à'ó Ø.´#°a³&Ó8Ü#Øûðús<   �E* ¥AE* Á5;E* Â1;E* Ã-A<E* Å*FÅ2FÅ7FÆFÆFrt   )ri  r  rj  r  rk  r  r‹   rs  rt  )?rö   r&   Úbenchmark_fusionra   rq   rj  r’   r&  r)   ÚTritonTemplateBufferrp  r�   rî   rÀ   rü  r  r  r  rQ  Útriton.compiler.errorsre  r{  r*  r!  r.  r-  r‘  r/  r¿  rÀ  r)  ÚTritonTemplateCallerrz  rË   r^  r  r  rC  r¯  rƒ  rZ  r[  rh  r„  r  r  r}  r   Úbenchmark_epilogue_fusionré   Úchoicesr   Ú max_epilogue_benchmarked_choicesr,  ÚoperatorÚ
itemgetterr	  r  rÀ  rT  ru  r²   ru   )+ri   r…   r†   Úis_multi_templateÚnode_list_1Únode_list_2Únode_list_fusedr  r8  rŽ  r~  r  r€  rf   r�  r  ri  rƒ  Únum_triton_callersÚchoice_timings_iterró  r™  Útriton_choicesÚunfused_timer‹  re  r…  r-  r[  rá  rŸ  r   r¡  r†  r‡  rˆ  rl  r‰  rj  rk  rŠ  r  r  s+   ```                      @@@@@@@@@@@@@@@@@@rj   Úspeedup_by_fusionÚScheduler.speedup_by_fusion�  s°  ÿÿü€ ô  ñ  
ð ˜U‘^ó 
ó 
Ðô
 ×&×&Ö/@Ü×$Ñ$ TÓ*Ð*ð ×Ñ×ÑÜ˜u×6Ñ6Ó8¼"×:QÑ:Q×RÑRØ×Ñ×!Ñ!Ø×Ñ×!Ñ!ô  ×$Ñ$ TÓ*Ð*à—o‘oÓ'ˆØ˜Q‘×*Ñ*Ó,ˆÞˆˆvð �;‰;˜%Ó¤F×$6Ñ$6¸(Ó$BÜ×$Ñ$ TÓ*Ð*à—o‘oÓ'ˆÜœyŸš¨{ÓHÓIˆð
 ×Ñ ×0Ñ0Ü×$Ñ$ TÓ*Ð*å;ä˜˜uÓ%ˆà  Ñ#×.Ñ.Ó0ˆØÑ!Ð!Ð!÷	ð 	÷" ¤ñ %
Ø8=¸u±~ó%
÷ "
ò "
ð $×5Ñ5Ó7¸tÐCˆOö #ð ×'Ñ'Ô)à×,Ñ,Ó.ð ô
 ˜j¬"×*@Ñ*@×AÑAÐAÐAà×5Ñ5°j×AÑAÜ#×(Ñ(¨Ó/Ð/ð ð -ð TVˆNÜ!'×!:Õ!:�Ø!+×!:Ñ!:¸=Ó!I�Ü!'¨×(<Ñ(<Ó(>ÁNÔ!S‘I�FÜ%Ø¤§¡× @Ñ @× UÑ U÷ñ ñ !Ø#×9Ñ9¸&ÕAØ&×-Ñ-à &ðà!%×!4Ñ!4Ø$3×CWÑCWð "5ð ""ñô÷ BÑAñ "Tô  % U›|�ØFJ�Ø �Û1?Ñ-�F Ið
!Ø!Ñ-Ø"ŸM™MœOð $×9Ñ9¸&ÕAØ)-×)HÑ)HØ% vó*™˜ $ð /7˜Ñ+Ø# lÓ2Ø+3˜LØ.4˜O÷ BÑAñ 2@ð( =H�
×*Ñ*¨=Ñ9Ü! /Ô3K×LÑLÐLÐLØBQÐ0°Ô?ñU ";ôX $×=Ñ=ˆNÜ!$ñ %ØAK×ASÒASó%ó "Ðô
 )Ó*÷ RØ&Ô&÷Rà&¬&×*QÑ*QÑQð %ô ˜U“|¤U¨5£\ˆHˆC�Ø15ˆJÞ+à!+×!:Ñ!:Ó!<�Ø",×";Ñ";Ó"=‘�
˜CÜ&,Ø"×(Ñ(Ó*´×0CÒ0CÀAÓ0Fñ'Ñ#ð 8B×7IÒ7IÓ&JÒ7I°!¨¨1£vÑ7IÐ#Ð&Jæö 'ð ×.Ñ.¨{Ô;à×3Ñ3°KÓ@ñ �‘Uö 'Ü'×,Ñ,¨UÓ3Ð3à×2Ñ2Ó4�Ü<¸UÀEÈ3ÓO�	ð TVˆNØˆNÛ(;Ñ$�˜Ü! &Ô*B×CÑCÙö (Ü Ð(?×@Ñ@Ø×4Ñ4¸
×8XÑ8XÓXáæ! l°c¸C±iÓ&?Ùà !Ñ#�Ø!¤F×$KÑ$KÓKÙà×5Ñ5°fÕ=Ø"×)Ñ)ØÐG $×"5Ñ"5°oÓ"FÑGô÷ >Ñ=ñ/ )<ô8 �>Ó" aÓ'Ü#×(Ñ(¨Ó/Ð/÷V!÷ V!ô V!ôp  ×-Ñ-Ø$ n°QÑ&7¸Ñ&:óð ð !%× 3Ñ 3°KÓ @ÐØ $× 3Ñ 3°KÓ @ÐØ&*×&9Ñ&9¸/Ó&JÐ#÷Fö FôP  ×-Ñ-Ø0Ð9PÐQRÑ9Sð .ð ð ÷q B×Aûô" %ó !Ü%×2Ñ2´7·=±=×AÑAÜ&×,Ñ,Ø ?Þ2A¡
ÀzÜ # A£ôö
 !ûð!ú÷ B×AüòF 'K÷T >×=úsC   Ì-Z$ÍZ7Í7$\!Ò3\4×%\9Ú$
Z4Ú7
\ÛA\Ü\Ü!
\1Ü9
]		c                ó<   • U R                   UR                  5          $ )z0Look up the node in Scheduler name_to_fused_node)r)  r1  rÄ  s     rj   r�  ÚScheduler.get_fused_node  s   € à×&Ñ& t×':Ñ':Ó'<Ñ=Ð=rm   c                óø  • [         R                  SUR                  5       UR                  5       5        UR                  5       nUR                  5       U:X  d   eU R	                  U5      R                  X5      nUR                  U5        UR                  U5        UR                  U5        U R                  R                  UR                  5        Vs0 s H  ofR                  5       U_M     sn5        U$ s  snf )Nzfusing %s with %s)rƒ  r„  r0  rî   rÌ  rq   r°  r  r)  r¨  r�   )ri   r…   r†   r(  r[  Únode3rD  s          rj   Úfuse_two_nodesÚScheduler.fuse_two_nodes  sÍ   € ô 	×ÑÐ,¨e¯n©nÓ.>ÀÇÁÓ@PÔQà×!Ñ!Ó#ˆØ×ÑÓ! VÓ+Ð+Ð+Ø× Ñ  Ó(×-Ñ-¨eÓ;ˆØ×Ñ˜5Ô!Ø×Ñ˜5Ô!Ø�‰˜ÔØ×Ñ×&Ñ&ÀUÇ_Á_ÔEVÓ'WÒEVÀ¯
©
«°eÒ(;ÑEVÑ'WÔXØˆùò (Xs   ÃC7c                óš   • U R                  X5      (       a5  U R                  X5      (       d  U" 5       (       a  U R                  XU5        gg©NTF)rþ   Úwill_fusion_create_cycler¹  )ri   r…   r†   Ú
speedup_fnr(  s        rj   Úfuse_if_speedupÚScheduler.fuse_if_speedup  sA   € ð �M‰M˜%×'Ñ'Ø×1Ñ1°%×?Ñ?Ù—‘à×Ñ ¨kÔ:Øàrm   c                óØ  • U(       Gaâ  / n0 n[        5       nU GH(  nXa;   a  [        X   5      S:¼  d   eX   R                  S5      n[        X   5      S:X  a  UR                  U5        UR	                  5       u  p‰X–:X  a  [        X‰5      (       d   eUn
OX†:X  d   e[        X‰5      (       d   eU	n
U R                  U
5      U
La  M®  UR                  (       a3  UR                  R                  nUc   eUR                  U5        Xv4XK'   Mò  U R                  X‰UR                  U5      (       d  GM  UR                  U5        GM+     [        U5       Hq  nXK   u  p|U R                  U R                  UR                  5      U R                  UR                  5      UR                  U5      (       d  M`  UR                  U5        Ms     U H  nUR                  U5        M     U(       a  GMá  gg)z¡
Evaluate pending template fusions for a set of fusion candidate nodes.
The fusion candidate nodes are pointwise nodes as potential epilogue
or prologue fusions
r   r   N)r   r²   r  r  r‰   râ  ræ  r�  rf   rË   r¿  rd   r   r…   r†   )ri   Útemplate_fusion_candidatesr(  Útemplate_futuresÚfuture_to_pending_fusionÚfusions_to_removeÚ	candidateÚpending_fusionr…   r†   r8  ÚfÚcands                rj   Ú"_evaluate_pending_template_fusionsÚ,Scheduler._evaluate_pending_template_fusions-  sò  € ÷ )Ø-/Ðð ð %ô @J»|ÐÜ7�	àÓ;ÜÐ6ÑAÓBÀaÓGððHð "<Ñ!F×!JÑ!JÈ1Ó!M�äÐ1Ñ<Ó=ÀÓBØ%×)Ñ)¨)Ô4à-×>Ñ>Ó@‘�àÓ%Ü-¨e×;Ñ;Ð;Ð;Ø$)‘Mà Ó-Ð-Ð-Ü-¨e×;Ñ;Ð;Ð;Ø$)�Mð ×&Ñ& }Ó5¸]ÒJÙà!×(×(Ø&×-Ñ-×4Ñ4�AØ™=Ð(˜=Ø$×+Ñ+¨AÔ.Ø3AÐ2MÐ,Ó/ð ×+Ñ+Ø n×&@Ñ&@À+÷ô ð *×-Ñ-¨i×8ñK 8ôP "Ð"2Ö3�Ø'?Ñ'BÑ$�Ø×'Ñ'Ø×'Ñ'¨×(<Ñ(<Ó=Ø×'Ñ'¨×(<Ñ(<Ó=Ø"×.Ñ.Ø÷	ó ð &×)Ñ)¨$Ö/ñ 4ó '�Ø*×.Ñ.¨qÖ1ñ '÷q )Ó(rm   c                óð  ^ ^^•       SUUU 4S jjnU GH\  u  pxU" Xx5        T R                  U5      nT R                  U5      n[        Xx5      (       a  Xx4T R                  ;   a  MS  T R                  XxU5      (       d  Ml  T R	                  Xx5      (       a  M„  T R                  Xx5      n	U	R                  b”  [        U	R                  UUU	R                  S9n
[        Xx5      (       aW  Xx4T R                  ;  d   eT R                  R                  Xx45        [        Xx5      nX³;  a  / X;'   X;   R                  U
5        O
U
TU'   U
TU'   GM6  U	R                  (       d  GMJ  T R                  XxT5        GM_     g )Nc                ó�  >• TR                  U 5      T;   d  TR                  U5      T;   Ga  TR                  TR                  U 5      TR                  TR                  U5      5      5      nUc   eUR                  5       u  p4UR                  nTR	                  US 5        TR	                  US 5        TR                  U5      UL d   eTR                  U5      UL d   eU" 5       (       a  TR                  X5      (       a  GM  TR                  X4T5        TR                  U 5      T;   a  GM  TR                  U5      T;   a  GM  g g ry   )r�  rñ  r‰   rd   r  r½  r¹  )	r…   r†   rÇ  Ú	node_key1Ú	node_key2Ú
is_speedupr(  Úpending_fusionsri   s	         €€€rj   Úresolve_pending_fusionsÚ<Scheduler._try_fusion_pairs.<locals>.resolve_pending_fusions{  s3  ø€ ð
 ×#Ñ# EÓ*¨oÓ=Ø×&Ñ& uÓ-°Ô@à!0×!4Ñ!4Ø×'Ñ'¨Ó.Ø#×'Ñ'¨×(;Ñ(;¸EÓ(BÓCó"�ð &Ñ1Ð1Ð1à'5×'FÑ'FÓ'HÑ$�	Ø+×7Ñ7�
à×#Ñ# I¨tÔ4Ø×#Ñ# I¨tÔ4à×*Ñ*¨9Ó5¸ÒBÐBÐBØ×*Ñ*¨9Ó5¸ÒBÐBÐBá!—|‘| t×'DÑ'DÀU×'RÑ'RÚà×#Ñ# I¸+ÔFð+ ×#Ñ# EÓ*¨oÖ=Ø×&Ñ& uÓ-°×@Ð@rm   )rd   r…   r†   rf   rŠ  )r�  rè  r  rþ   r½  r³  rd   rƒ   rf   r  rê  rË   rc   r¹  )ri   Úpossible_fusion_pairsrÑ  Útemplate_fusion_nodesr(  rÿ  rÒ  r…   r†   Ú
fusion_resrÇ  Útemplate_pw_nodes   ` ` `       rj   Ú_try_fusion_pairsÚScheduler._try_fusion_pairss  s‚  ú€ ð	GØ$ð	Gà$ð	Gð ÷	Gñ 	Gô8 2‰LˆEñ $ EÔ1Ø×'Ñ'¨Ó.ˆEØ×'Ñ'¨Ó.ˆEô # 5×0Ñ0Ø�N d×&@Ñ&@Ó@áà�}‰}ØÐ.÷ó à×3Ñ3°E×AÓAØ!×3Ñ3°EÓA�
Ø×)Ñ)Ñ5Ü%2Ø$.×$:Ñ$:Ø#Ø#Ø)×0Ñ0ñ	&�Nô *¨%×7Ñ7Ø %˜~°T×5OÑ5OÓOÐOÐOØ×2Ñ2×6Ñ6¸°~ÔFä+BÀ5Ó+PÐ(Ø+ÓHØFHÐ1ÑCØ-Ñ?×FÑFÀ~ÕVà1?˜¨Ñ.Ø1?˜¨Ñ.âà!×-×-Úà×#Ñ# E°+×>òW 2rm   c                óN  • [        5       nUR                  5        H‡  nUR                  5       u  pVUR                  nXs;   d  [	        XV5      (       a  M8  UR                  U5        U R                  U5      UL d   eU R                  U5      UL d   eU R                  XVXq5        M‰     g ry   )r   rÃ   r‰   rd   rè  r  r�  r¿  )ri   r(  rÑ  Úseen_pair_speedup_fnrÇ  rÎ  rÏ  Úis_speedup_fns           rj   Ú_finish_pending_fusionsÚ!Scheduler._finish_pending_fusionsÄ  sª   € ô
 @J»|Ðð .×4Ñ4Ö6ˆNØ#1×#BÑ#BÓ#DÑ ˆIØ*×6Ñ6ˆMàÓ4Ô8JØ÷9ñ 9ñ à ×$Ñ$ ]Ô3à×&Ñ& yÓ1°YÒ>Ð>Ð>Ø×&Ñ& yÓ1°YÒ>Ð>Ð>à× Ñ  °}ÖRò 7rm   c           
     ó  • [        U VVs/ s H  u  p4[        X45      (       d  M  UPM     snn5      n/ nU H@  u  p4[        X45      (       a  X5;   a  UR                  X445        M.  UR                  X445        MB     Ung s  snnf ry   )r   râ  ræ  rË   )ri   Úpossible_fusionsÚdeferred_prologue_fusionsÚn1Ún2Úepilogue_template_nodesÚnew_possible_fusionss          rj   Ú_handle_template_overlapÚ"Scheduler._handle_template_overlapÜ  s   € ô #-Ù.ÔMÒ.‘F�BÔ2DÀR×2L�RÑ.ÒMó#
Ðð  "ÐÛ&‰FˆBÜ! "×)Ñ)¨bÓ.KØ)×0Ñ0°"°Ö:à$×+Ñ+¨R¨HÖ5ñ	 'ð 0Ñùó Ns
   ‹A>
¥A>
c                ó,  • U R                  U5        [        U5      n[        R                  [        R
                  5      (       aB  [        R                  S5        U H'  n[        R                  SUR                  5       5        M)     0 n0 n/ nU R                  UU5      n[        R                  (       d  [        R                  (       a;  [        R                  (       a&  [        R                  (       a  U R                  X‡5        U R                  UUUUU5        U R!                  X55        U R#                  Xc5        UR%                  5         U(       a&  U R                  UUUUU5        U R#                  Xc5        ['        US S9nU R)                  U5      nU$ )zÛ
Combine eligible nodes into FusedSchedulerNodes.

This relies on two key functions to control the logic:
    - self.can_fuse(): checks if a fusion is legal
    - self.score_fusion(): assigns priority to a given fusion
zfuse_nodes_once, candidates:z  %sc                ó   • U R                   $ ry   rh  rQ  s    rj   r‘  Ú+Scheduler.fuse_nodes_once.<locals>.<lambda>3  s   € °!·+²+rm   rŒ  )r*  r   rƒ  rZ  r[  rh  r„  rÈ  Úget_possible_fusionsr&   r'  r(  rå  rá  ræ  rØ  rÝ  rÊ  Úclearr‘  r  )	ri   r5  rÿ  r(  r•   rÑ  rÕ  rá  rà  s	            rj   r   ÚScheduler.fuse_nodes_onceð  si  € ð 	×!Ñ! %Ô(Ü  Ó'ˆÜ×"Ñ"¤7§=¡=×1Ñ1Ü×ÑÐ;Ô<Û#�Ü× Ñ  ¨×)=Ñ)=Ó)?Ö@ñ $ð ð 	ð
 OQÐð ð 	"ð  ×4Ñ4ØØó
Ðô ×%×%¬×)<×)<Ü×&×&Ü×&×&à×)Ñ)Ð*:ÔVà×ÑØØØ!ØØô	
ð 	×$Ñ$ [ÔBà×/Ñ/Ð0EÔSØ×#Ñ#Ô%æ$Ø×"Ñ"Ø)ØØ%ØØ ôð ×3Ñ3Ð4IÔWä�{Ñ(=Ñ>ˆØ×.Ñ.¨uÓ5ˆØˆrm   c                ó  • [        U R                  5      nSn[        U R                  5      n[        R	                  SU5        [        [        R                  U 5      5       GH(  u  pV[        R                  U5      n[        U5      S:  a  M,  Ub  X1:”  a    O÷U R                  U5      (       d  [        R	                  SU5        Md  US-  n[        R                  S:„  n[        US   R                  USUS9n[        R                  S	[        U5      U5        U H  n	UR                  U	5        M     UR                  U5        U R                   R#                  UR%                  5        V
s0 s H  oªR'                  5       U_M     sn
5        GM+     [)        US
 S9U l        U R+                  U R                  5      U l        [        R                  SUU[        U R                  5      5        U R-                  U R                  5        gs  sn
f )z
Groups parallel nodes
r   z2ComboKernels: Generating with num_ck_nodes = %s...r±   Nz)ComboKernels: Not speeding up %d-th groupr   Trd  z0ComboKernels: Combining %d nodes for %d-th groupc                ó   • U R                   $ ry   rh  rQ  s    rj   r‘  Ú5Scheduler.create_combo_kernel_nodes.<locals>.<lambda>]  s   € °q·{²{rm   rŒ  zDGenerated ComboKernel nodes: %d ComboKernels, totally %d -> %d nodes)r   r5  r²   r°  r„  r4  r	  rU  r>  Úspeedup_by_combo_kernelr&   rf  r(  rË  r°  r  r)  r¨  r�   r0  r‘  r  r*  )ri   r÷  r(  r  Únum_nodes_origÚnumrP  r'  r_  r•   rD  s              rj   r-  Ú#Scheduler.create_combo_kernel_nodes7  s¹  € ô ! §¡Ó,ˆØˆÜ˜TŸZ™Z›ˆÜ�	‰	ÐFÈÔUÜ'Ü&×DÑDÀTÓJ÷
‰NˆCô 3×CÑCÀIÓNˆIÜ�9‹~ Ó!ÙØÑ'¨EÓ,@ÙØ×/Ñ/°	×:Ñ:Ü—	‘	ÐEÀsÔKÙØ�Q‰JˆEÜ$×;Ñ;¸aÑ?ˆOÜ4Ø˜!‘×&Ñ&ØØ*.Ø /ñ	ˆKô �H‰HØBÜ�I“Øôó
 "�Ø×"Ñ" 4Ö(ñ "à�O‰O˜KÔ(Ø×#Ñ#×*Ñ*Ø4?×4IÑ4IÔ4KÓLÒ4K¨q—‘“˜{Ò*Ñ4KÑL÷ñ7
ô< ˜KÑ-BÑCˆŒ
Ø×3Ñ3°D·J±JÓ?ˆŒ
Ü�‰ØRØØÜ�—
‘
‹Oô		
ð 	×!Ñ! $§*¡*Õ-ùò Ms   Å(H
c                óL   • U H  nUR                  U R                  5        M      g ry   )r*  r)  )ri   r5  r•   s      rj   r*  ÚScheduler.prune_redundant_depsg  s    € ÛˆDØ×%Ñ% d×&=Ñ&=Ö>ò rm   c                ó  ^ ^^
^• / m
[         [        [        [        4      " 5       mSUU
UU 4S jjn[        R                  " [
        5      nU HE  nT R                  U5      (       a  M  UR                  5        H  nXF   R                  U5        M     MG     UR                  5        H  nU" U5        M     [        R                  (       ak  [        R                  " [
        5      nU H,  n[        USS5      n	U	(       d  M  X‰   R                  U5        M.     UR                  5        H  nU" U5        M     T R                  T
5      m
T
R                  T R                  SS9  [         R#                  S[%        T
5      5        T
$ )zN
Helper to find all legal fusion opportunities, sorted by self.score_fusion()
c                ó®  >• [        U 5       HÅ  u  pU US-   US-   [        R                  -     H   nX#4nUT;   a  M  TR                  U5        TR	                  X#T5      (       a  TR                  U5        MI  UR                  5       (       d  UR                  5       (       d  Mu  TR	                  X2T5      (       d  MŽ  TR                  X245        M¢     MÇ     g r  )r4  r&   Ú)max_fusion_buffer_group_pairwise_attemptsr  rþ   rË   rj  rp  )	r5  Únode1_indexr…   r†   r�  rÿ  rà  rá  ri   s	        €€€€rj   Úcheck_all_pairsÚ7Scheduler.get_possible_fusions.<locals>.check_all_pairsv  sÉ   ø€ Ü&/°Ö&6Ñ"�Ø"Ø !‘O kØñ'ä×FÑFñ'Gó�Eð
 !˜.�CØ˜d“{Ù Ø—H‘H˜S”Mà—}‘} UÐ3C×DÑDØ(×/Ñ/°Ö4Ø×+Ñ+×-Ñ-°×1AÑ1A×1CÓ1CÈÏÉØÐ&6÷Jó Jð )×/Ñ/°°Ö?ó!ò '7rm   r©   NT)r�  Úreversezfound %d possible fusions©r5  rI  r‹   rs  )r   r³   r\   rñ  r   r  Úunfusable_noderÊ   rË   rÃ   r&   Úaggressive_fusionr¬  Ú*get_possible_fusions_with_highest_priorityr§  Úscore_fusion_keyrƒ  r„  r²   )ri   r5  rÿ  rû  Úbuffer_names_groupingr•   rÄ   Únode_groupingÚgroup_groupingr©   rà  rá  s   ` `       @@rj   rë  ÚScheduler.get_possible_fusionsk  sV  û€ ð ÐÜœ%Ô 1Ô3DÐ DÑEÒFÓHˆ÷	@ò 	@ô( !,× 7Ò 7¼Ó =ÐÛˆDØ×"Ñ" 4×(Ñ(ÙØ×-Ñ-Ö/�Ø%Ñ*×1Ñ1°$Ö7ó 0ñ ð
 3×9Ñ9Ö;ˆMÙ˜MÖ*ñ <ô ×#×#Ü(×4Ò4´TÓ:ˆNÛ�Ü  g¨tÓ4�ß�5Ø"Ñ)×0Ñ0°Ö6ñ ð "0×!6Ñ!6Ö!8�Ù Ö.ñ "9ð  ×JÑJØó
Ðð 	×Ñ $×"7Ñ"7ÀÐÑFÜ×ÑÐ4´cÐ:JÓ6KÔLØÐrm   c                óâ  ^ ^^^^• [         [           " 5       mSUUUU U4S jjmUR                  5       R                  R	                  5       UR                  5       R                  R	                  5       -  mUR
                  R                  R	                  5       UR
                  R                  R	                  5       -  T-
  m[        UU 4S jT 5       5      nU(       a  [        X5      " S5        U$ )zf
Finds whether there's a path from node1 to node2 (or vice-versa)
caused indirectly by other fusions.
c                ó,  >• [        U [        5      (       a~  U T;  ax  TR                  U 5        U R                  5       R	                  T5      (       a  g[        TU R                  -  5      =(       d#    [        UU4S jU R                  T-
   5       5      $ g)NFc              3  óN   >#   • U  H  nT" TR                   U   5      v •  M     g 7fry   rê  ©r˜   rD  Ú
found_pathri   s     €€rj   rš   ÚIScheduler.will_fusion_create_cycle.<locals>.found_path.<locals>.<genexpr>¾  s,   øé € ð Hâ!D˜Añ # 4×#:Ñ#:¸1Ñ#=×>Ð>Ú!Dùó   ƒ"%)r’   r¿   r  rð   Úissubsetrx   rï   rö   )r•   Úcombined_ancestorsÚcombined_namesr  ri   Úvisiteds    €€€€€rj   r  Ú6Scheduler.will_fusion_create_cycle.<locals>.found_path­  s‡   ø€ ä˜$Ô 2×3Ñ3¸ÀGÓ8KØ—‘˜DÔ!Ø×+Ñ+Ó-×6Ñ6Ð7I×JÑJð !ô   °·±Ñ ?Ó@÷ ÄCõ Hà!%§¡Ð2DÒ!DóHó Eð ð rm   c              3  óN   >#   • U  H  nT" TR                   U   5      v •  M     g 7fry   rê  r
  s     €€rj   rš   Ú5Scheduler.will_fusion_create_cycle.<locals>.<genexpr>Ì  s&   øé € ÐWÒDV¸q‘J˜t×6Ñ6°qÑ9×:Ð:ÒDVùr  zwill create cycler  )r   r¿   rð   Ú_dictr  rï   rö   r{  )ri   r…   r†   Úcycler  r  r  r  s   `   @@@@rj   r½  Ú"Scheduler.will_fusion_create_cycle£  sÃ   ü€ ô Ô/Ò0Ó2ˆ÷	ó 	ð2 ×%Ñ%Ó'×-Ñ-×2Ñ2Ó4Ø×'Ñ'Ó)×/Ñ/×4Ñ4Ó6ñ7ð 	ð
 �O‰O×!Ñ!×&Ñ&Ó(¨5¯?©?×+@Ñ+@×+EÑ+EÓ+GÑGØñÐô ÕWÑDVÓWÓWˆÞÜ�eÔ#Ð$7Ô8Øˆrm   c                ó¦  ^ ^• SSK Jm      SU 4S jjnU" U5      nU" U5      n[        U4S jU 5       5      n[        U4S jU 5       5      nUR                  U5      nSn	U H  n
 U	[	        U
S   5      -  n	M     T R                  X5      n[        R                  R                  R                  U	S	U-  5      (       a  g
g! [
         a       gf = f)a‹  
Return true if fusing the two nodes can potentially increasing peak memory.

The implementation is more like a heuristic since we don't really know if we are at peak
or not when trying to fuse these two nodes. The order of nodes may change later which makes the
peak memory estimation hard.

Here is how we decide the LOWER BOUND of extra memory allocation if we fuse these 2 nodes:
1. find all buffers read by each node with a single user. These buffers are supposed to
   be reused if we don't fuses these 2 nodes
2. find the intersection of these buffers for the two node and sum the total buffer size.
   If we don't fuse these two nodes, we can at lease avoid this much memory allocation.
   Note that the extra memory allocation is not necessarily causing peak memory increase.
   This is just a heuristic.

We return true only if the saving for fusion can not trade off the extra memory allocation.
r   )Úbuffer_reuse_keyc                óP  >• / nU R                   R                   Hˆ  nTR                  R                  UR                  5      nU(       d  M1  [        UR                  5      S:X  d  ML  UR                  R                  5       (       d  Mm  UR                  UR                  5        MŠ     U$ r  )
rº   r»   rX  rñ  r¼   r²   r-  r•   Úhas_tensor_outputrË   )r•   r˜  r  rÄ   ri   s       €rj   Ú_find_single_user_inputsÚKScheduler.can_fusion_increase_peak_memory.<locals>._find_single_user_inputsè  sw   ø€ ð ˆFØ×&Ñ&×,Ô,�Ø×&Ñ&×*Ñ*¨2¯7©7Ó3�ß�3œ3˜sŸy™y›>¨QÕ.°3·8±8×3MÑ3M×3OÓ3OØ—M‘M #§(¡(Ö+ñ -ð ˆMrm   c              3  ó4   >#   • U  H  nT" U5      v •  M     g 7fry   rw   ©r˜   rÄ   r  s     €rj   rš   Ú<Scheduler.can_fusion_increase_peak_memory.<locals>.<genexpr>ö  ó   øé € Ð#SÂ]¸cÑ$4°S×$9Ð$9Â]ùrÓ  c              3  ó4   >#   • U  H  nT" U5      v •  M     g 7fry   rw   r  s     €rj   rš   r   ÷  r!  rÓ  r   r±   Fé    T)r•   r\   r‹   zlist[ir.Buffer])r‡  r  r   Úintersectionr!  r  rù  rW   r¤   r¥   Ústatically_known_gt)ri   r…   r†   r  Úlhs_dep_nodesÚrhs_dep_nodesÚlhs_reuse_keysÚrhs_reuse_keysÚcommon_reuse_keysÚmemory_overheadr�  Ú	bw_savingr  s   `           @rj   Úcan_fusion_increase_peak_memoryÚ)Scheduler.can_fusion_increase_peak_memoryÑ  sÙ   ù€ õ* 	6ð	Ø#ð	à÷	ñ 1°Ó7ˆÙ0°Ó7ˆä#Ô#SÁ]Ó#SÓSˆÜ#Ô#SÁ]Ó#SÓSˆà*×7Ñ7¸ÓGÐàˆÛ$ˆCðØ¤3 s¨1¡v£;Ñ.’ñ %ð ×,Ñ,¨UÓ:ˆ	ô �7‰7×Ñ×/Ñ/°ÀÀiÁ×PÑPØØøô ó âðús   Á(CÃ
CÃCc                ó´  • [        UR                  5        Vs/ s H  oDR                  5       PM     snUR                  5        Vs/ s H  oDR                  5       PM     sn-   5      n[        S UR                  R                   5       5      n[        S UR                  R
                   5       5      nXv-  n[        5       n	UR                  R                   HA  n
U R                  U
R                  U5      (       d  M&  U	R                  U
R                  5        MC     [        S UR                  R
                   5       5      [        S UR                  R
                   5       5      -  n[        S UR                  R                   5       5      [        S UR                  R                   5       5      -  nX¸-
  nXÉ-
  nXÞ-  n[        U5      U:„  $ s  snf s  snf )Nc              3  ó8   #   • U  H  oR                   v •  M     g 7fry   r×  rØ  s     rj   rš   ÚEScheduler.fusion_prevent_too_many_reads_and_writes.<locals>.<genexpr>  s   é € Ð&TÒ;S°C§x¦xÒ;SùrÚ  c              3  ó8   #   • U  H  oR                   v •  M     g 7fry   r×  rØ  s     rj   rš   r1    s   é € Ð%RÒ:Q°3§h¦hÒ:QùrÚ  c              3  ó8   #   • U  H  oR                   v •  M     g 7fry   r×  rØ  s     rj   rš   r1  &  s   é € ð $
Ú 7˜�HŽHÒ 7ùrÚ  c              3  ó8   #   • U  H  oR                   v •  M     g 7fry   r×  rØ  s     rj   rš   r1  (  rÐ  rÚ  c              3  ó8   #   • U  H  oR                   v •  M     g 7fry   r×  rØ  s     rj   rš   r1  +  s   é € ð %
Ú 8˜�HŽHÒ 8ùrÚ  c              3  ó8   #   • U  H  oR                   v •  M     g 7fry   r×  rØ  s     rj   rš   r1  -  s   é € ÐDÒ+C C—x–xÒ+CùrÚ  )
r   r�   r0  rº   r­  r»   Ú$can_buffer_be_removed_through_fusionr¼   r  r²   )ri   r…   r†   Ú	thresholdr•   Úfused_node_namesÚnode1_write_namesÚnode2_read_namesÚreads_removed_through_fusionÚwrites_removed_through_fusionrG  Úall_read_namesÚall_write_namesÚunique_readsÚunique_writesÚunique_io_bufferss                   rj   Ú(fusion_prevent_too_many_reads_and_writesÚ2Scheduler.fusion_prevent_too_many_reads_and_writes
  s¬  € ô &Ø).¯©Ô):Ó;Ò): �]‰]Ž_Ñ):Ñ;Ø+0¯?©?Ô+<Ó=Ò+< 4�}‰}ŽÑ+<Ñ=ñ>ó
Ðô 'Ñ&T¸5×;LÑ;L×;SÒ;SÓ&TÓTÐÜ%Ñ%R¸%×:KÑ:K×:QÒ:QÓ%RÓRÐØ'7Ñ'KÐ$ô :D»Ð%Ø×*Ñ*×1Ô1ˆIØ×8Ñ8Ø—‘Ð 0÷ó ð .×1Ñ1°)·.±.ÖAñ	 2ô $ñ $
Ø %× 1Ñ 1× 7Ò 7ó$
ó 
äÑC¨5×+<Ñ+<×+BÒ+BÓCÓCñDˆô
 %ñ %
Ø %× 1Ñ 1× 8Ò 8ó%
ó 
äÑD¨5×+<Ñ+<×+CÒ+CÓDÓDñEˆð
 &ÑDˆð (ÑGˆð )Ñ8ÐäÐ$Ó%¨	Ñ1Ð1ùòM <ùÚ=s   ˜GÁG
c                ó¤   • [        [        UR                  UR                  -
  5      [        UR                  UR                  -
  5      5      nUS:„  $ )aÉ  
This function prevents fusion for nodes that can increase memory
footprint. This problem is more common in horizontal fusion, where nodes
that are far apart in the original order get fused, lengthening the live
intervals of tensors. This is very evident in models with activation
checkpointing, where the recomputed nodes from different checkpointed
regions get fused and significantly increase the memory footprint.

The current attempt is a quick, possibly hacky, heuristic to prevent the
fusion of nodes that are far away in the original order.

A better but difficult to implement heuristic would be to use live
intervals of the buffers, find region of peak pressure in the original
program and prevent fusion that crosses that peak region. We might need
special care or good approximation in this implementation, as fusion of
node changes live intervals, and re-computing live intervals and peak
memory after each fusion can introduce large compilation overhead.
é@   )r  rš  r  r€  )ri   r…   r†   Úproximity_scores       rj   Úare_long_distant_nodesÚ Scheduler.are_long_distant_nodes:  sE   € ô* Ü�—‘ %§/¡/Ñ1Ó2Ü�—‘ %§/¡/Ñ1Ó2ó
ˆð  Ñ#Ð#rm   c                ó(  • 0 nUR                   R                  5        Vs0 s H  oUR                  U_M     nnUR                   R                  5        Vs0 s H  oUR                  U_M     nnU GH�  n[        R                  R                  U5      n	Xh   n
Xx   n[        U
[        5      (       a  [        U[        5      (       d  S[        U
5       S[        U5       3XH'   Ms  U
R                  5       UR                  5       :w  a(  SU
R                  5        SUR                  5        3XH'   M½  [        U
R                  5      [        UR                  5      :w  a  SXH'   Mï  U
R                  5       nUR                  5       nXÍ:w  a  SU SU 3XH'   GM!  U
R                  5       UR                  5       :X  a  SU
 SU 3XH'   GMP  Sn[        U	[        R                  5      (       d  SU	R                    3nS	U
 SU S
U 3XH'   GM�     [#        U5      $ s  snf s  snf )ze
Try to decide reasons why fusion fail due to no shared memory even though
there are common buffers.
znot MemoryDep: r¢   zdifferent numel: Ú	broadcastzdifferent offset: zMismatch loop orders: rµ  zLayout: zUnknown reason: z. )rº   rÛ  r¼   rW   r¤   rÝ  r’   r2   rÀ   rÙ   rV   rÂ   Ú
get_offsetÚnormalize_with_stride_orderr)   râ  r=  r  )ri   r…   r†   Úcommon_buf_namesÚreasonsrÆ   Únode1_name2depÚnode2_name2deprR  rÄ   Úlhs_depÚrhs_depÚlhs_offÚrhs_offÚ
layout_strs                  rj   Údecide_fusion_fail_reasonÚ#Scheduler.decide_fusion_fail_reasonU  s  € ð ˆØ38×3DÑ3D×3UÑ3UÔ3WÓXÒ3W¨CŸ(™( Cš-Ñ3WˆÐXØ38×3DÑ3D×3UÑ3UÔ3WÓXÒ3W¨CŸ(™( Cš-Ñ3WˆÐXä(ˆHÜ—'‘'×$Ñ$ XÓ.ˆCØ$Ñ.ˆGØ$Ñ.ˆGä˜g¤y×1Ñ1¼ÀGÌY×9WÑ9Wà%¤d¨7£m _°F¼4À»=¸/ÐJð Ñ!ñ à× Ñ Ó" g×&7Ñ&7Ó&9Ó9à'¨×(9Ñ(9Ó(;Ð'<¸FÀ7×CTÑCTÓCVÐBWÐXð Ñ!ñ ô ˜WŸ\™\Ó*¬m¸G¿L¹LÓ.IÓIØ$/�Ñ!Ùà×(Ñ(Ó*ˆGØ×(Ñ(Ó*ˆGØÓ!ð '9¸¸	ÀÈÀyÐ$Q�Ñ!Úð ×3Ñ3Ó5Ø×6Ñ6Ó8ó9ð '=¸W¸IÀVÈGÈ9Ð$U�Ñ!Úð ˆJÜ˜c¤2×#5Ñ#5×6Ñ6Ø'¨¯
©
 |Ð4�
à" 7 )¨6°'°¸"¸Z¸LÐIð ÔñU )ô\ �7‹|Ðùòc YùÚXs   ŸH
ÁHc                ó.	  • [         R                  (       d  g[        S X4 5       5      (       a  gUR                  R	                  5       nUR                  R	                  5       nX4-  nU(       d  g[        S UR                   5       5      nXc-
  (       a  g[        U5      S:”  a  g[        UR                  R                  5      S:”  d#  [        UR                  R                  5      S:”  a  g[        [        UR                  R                  5      5      n[        [        UR                  R                  5      5      n[        U[        5      (       a  [        U[        5      (       d  gUR                  R                   V	s0 s H  o™R                  U	_M     n
n	UR                  U
;  a  gX§R                     n[        U[        5      (       d  gUR                  5       nUR                   UR                   :w  a  UR"                  UR"                  :w  a  gUR"                  UR"                  :w  d  [        UR$                  5      S:w  a  g[        UR&                  R(                  5      S:w  a  gUR&                  R*                  (       a  gSUR&                  R(                  ;   a  SUR&                  R(                  ;   d   e[        S UR&                  R-                  5        5       5      n[        U5      S:w  a  g[        [        U5      5      nXÒR&                  R(                  S   :X  a  SnSnO"XÒR&                  R(                  S   :X  d   eSnSnS	S
KJn  UR&                  R2                  S	   n[        U5      S:w  a  g/ n[4        R6                  R9                  U5       H;  nUR;                  [<        R>                  R@                  RC                  U5      5        M=     [E        U5      nU" UUS	   5      nUc  gUR&                  R(                  U   UR&                  R(                  U'   UUR&                  R(                  U'   URG                  SS5        U RI                  X5      n[        U[J        5      (       d   e[L        RO                  SU5        U$ s  sn	f )aÿ  
Attempts to enable fusion between two nodes by inverting indexing patterns.

This optimization targets cases where node1 has a contiguous write and
node2 has a contiguous write but discontiguous read. By inverting the
indexing in node2's read and write operations, we can make them compatible
with node1 for potential fusion.

Args:
    node1: First scheduler node (source)
    node2: Second scheduler node (target for inversion)

Returns:
    int: Fusion score if successful, 0 if optimization not applicable
r
  c              3  ó@   #   • U  H  oR                  5       v •  M     g 7fry   ©r\  rC  s     rj   rš   ÚAScheduler.shared_data_after_inverting_indexing.<locals>.<genexpr>©  s   é € Ð2¢>˜a�x‰x�zˆz¢>ùr7  c              3  ó8   #   • U  H  oR                   v •  M     g 7fry   r×  rØ  s     rj   rš   r\  µ  s   é € ð .
Ú 8˜�HŽHÒ 8ùrÚ  r   r±   Úindex0Úindex1c              3  ó$   #   • U  H  ov •  M     g 7fry   rw   )r˜   rü  s     rj   rš   r\  ð  s   é € Ð%TÒ7S¨t¤dÒ7Sùs   ‚r   )Úgenerate_inverse_formulaTFz!Shared memory after inversion: %d)(r&   r  rö   rº   Úbuffer_namesr   rŒ  r²   r»   r­  r3  rF  r’   r2   r¼   rÈ  r½   rÂ   rq  r  r  Ú	subblocksÚget_read_exprsÚ$torch._inductor.invert_expr_analysisra  Úvarsrô   ÚAddÚ	make_argsrË   rW   r¤   r¥   Úcombine_modular_indexing_pairsré   râ  rù  r!  rƒ  rË  )ri   r…   r†   Únode1_buffer_namesÚnode2_buffer_namesÚcommon_buffer_namesÚnode2_unmet_dependenciesÚ
node2_readÚnode2_writerÆ   Únode1_writesÚnode1_writeÚnode2_read_exprsÚ	read_exprÚread_expr_indexÚwrite_expr_indexra  r#  Úsimplified_termsÚtermÚsimplified_read_exprÚinverse_formulaÚscores                          rj   Ú$shared_data_after_inverting_indexingÚ.Scheduler.shared_data_after_inverting_indexing“  sð  € ô& ×4×4ØäÑ2 E¡>Ó2×2Ñ2Øð #×.Ñ.×;Ñ;Ó=ÐØ"×.Ñ.×;Ñ;Ó=ÐØ0ÑEÐæ"Øô $.ñ .
Ø %× 8Ò 8ó.
ó $
Ð ð $×8ØäÐ'Ó(¨1Ó,Øô ˆu× Ñ ×&Ñ&Ó'¨!Ó+¬s°5×3DÑ3D×3KÑ3KÓ/LÈqÓ/PØäœ$˜u×0Ñ0×6Ñ6Ó7Ó8ˆ
Üœ4 × 1Ñ 1× 8Ñ 8Ó9Ó:ˆä˜*¤i×0Ñ0¼
Øœ÷9
ñ 9
ð à16×1BÑ1B×1IÒ1IÓJÒ1I¨#Ÿ™ #šÑ1IˆÐJØ�?‰? ,Ó.Øà"§?¡?Ñ3ˆä˜+¤y×1Ñ1Øð "×+Ñ+Ó-ˆð ×Ñ ×!2Ñ!2Ó2Ø× Ñ  K×$4Ñ$4Ó4àà�?‰?˜k×.Ñ.Ó.´#°j×6JÑ6JÓ2KÈqÓ2PØô ˆu�{‰{×)Ñ)Ó*¨aÓ/Øð �;‰;× × Øð ˜Ÿ™×2Ñ2Ó2Ø˜EŸK™K×6Ñ6Ó6ð	
ð7ô
 &Ñ%T°u·{±{×7QÑ7QÔ7SÓ%TÓTÐÜÐÓ  AÓ%ØäœÐ.Ó/Ó0ˆ	ð Ÿ™×2Ñ2°8Ñ<Ó<Ø&ˆOØ'Ñà§¡× :Ñ :¸8Ñ DÓDÐDÐDØ&ˆOØ'ÐåQà—[‘[×%Ñ% aÑ(ˆ
Üˆz‹?˜aÓØàÐÜ—I‘I×'Ñ'¨	Ö2ˆDØ×#Ñ#Ü—‘× Ñ ×?Ñ?ÀÓEöñ 3ô  #Ð#3Ó4Ðá2Ð3GÈÐTUÉÓWˆð Ñ"Øð
 7<·k±k×6PÑ6PØñ7
ˆ�‰×"Ñ" ?Ñ3ð 8Gˆ�‰×"Ñ"Ð#3Ñ4ð 	×"Ñ" 4¨Ô/Ø×(Ñ(¨Ó6ˆÜ˜%¤×%Ñ%Ð%Ð%ä�‰Ð;¸UÔCØˆùòm Ks   Æ Rc                óÖ  • [         R                  (       a  [        S X4 5       5      (       a  gUR                  5       (       d  UR                  5       (       a  gUR                  R                  5       nUR                  R                  5       nX4-  nU(       d  gUR                  R                  5        Vs0 s H  ofR                  U_M     nnUR                  R                  5        Vs0 s H  ofR                  U_M     nn/ n	U Hw  n
Xz   nXŠ   nUR                  5       UR                  5       :X  d  M/  U	R                  [        R                  R                  R                  UR                  5       SS9UU45        My     [        U	5      S:X  a  g[!        U	["        R$                  " S5      S9u  pÛn['        U[(        5      (       a  ['        U[(        5      (       d  gUR*                  UR*                  :w  a4  UR-                  5       UR-                  5       :X  a  U R/                  U5      $ gSnUR1                  5       (       d  UR3                  X¼5      nOZUR1                  5       (       d  UR3                  XË5      nO3[4        R7                  SUR9                  5       UR9                  5       5        U(       a*  [:        R<                  " [>        U RA                  X5      5      $ S$ s  snf s  snf )as  
Right now just greedily reorder the loop of node1 to be compatible with node2,
but ideally we should have some heuristics to reorder the loop for node2
to be compatible with node1 if that's more efficient.

Return the amount of shared data re-computed in this method.
If no such recomputation happens, return -1 (not return 0 since 0 is a valid
amount of shared data).

c              3  ó@   #   • U  H  oR                  5       v •  M     g 7fry   r[  rC  s     rj   rš   Ú>Scheduler.shared_data_after_reordering_loop.<locals>.<genexpr>2  s   é € ð 8
Ú .˜1�H‰H�JˆJ¢ùr7  r
  r   rÖ   rŒ  Fz?Don't reorder loops since both nodes are reductions: %s v.s. %s)!r&   rÎ  rö   rj  rº   rb  rÛ  r¼   rM  rË   rW   r¤   r¥   Ú	size_hintrÙ   r²   r  r©  rª  r’   r2   r  rÈ  Údep_size_hintr”   rÒ  r  r„  r0  r÷  rø  r!  rù  )ri   r…   r†   rj  rk  rl  rÆ   rP  rQ  Ú
candidatesr  rR  rS  Ú_numelÚ	reordereds                  rj   Ú!shared_data_after_reordering_loopÚ+Scheduler.shared_data_after_reordering_loop"  sŽ  € ô  ×0×0´Cñ 8
Ø!&¡ó8
÷ 5
ñ 5
ð ð
 ×Ñ×Ñ %×"3Ñ"3×"5Ñ"5Øà"×.Ñ.×;Ñ;Ó=ÐØ"×.Ñ.×;Ñ;Ó=Ðà0ÑEÐÞ"Øà38×3DÑ3D×3UÑ3UÔ3WÓXÒ3W¨CŸ(™( Cš-Ñ3WˆÐXØ38×3DÑ3D×3UÑ3UÔ3WÓXÒ3W¨CŸ(™( Cš-Ñ3WˆÐXð ˆ
Û.ˆKØ$Ñ1ˆGØ$Ñ1ˆGà×3Ñ3Ó5Ø×6Ñ6Ó8õ9ð ×!Ñ!äŸ™×(Ñ(×2Ñ2°7×3DÑ3DÓ3FÐQRÐ2ÐSØØðöñ /ô ˆz‹?˜aÓØô $' z´x×7JÒ7JÈ1Ó7MÑ#NÑ ˆ˜ä˜'¤9×-Ñ-´ZÀÌ×5SÑ5SØà×Ñ˜w×/Ñ/Ó/ð
 × Ñ Ó" g×&7Ñ&7Ó&9Ó9Ø×)Ñ)¨'Ó2Ð2Øàˆ	à×!Ñ!×#Ñ#Ø×7Ñ7¸ÓI‰IØ×#Ñ#×%Ñ%Ø×7Ñ7¸ÓI‰Iä×#Ñ#ØQØ—‘Ó Ø—‘Ó ôö ô �KŠKœ˜T×5Ñ5°eÓCÓDð	
ð ð	
ùòg YùÚXs   Â6K!Ã*K&c                ó¨   • [        U[        [        45      =(       a6    UR                  5       (       + =(       a    [	        UR
                  5      (       + $ )z.
Is this node unfusable under any conditions.
)r’   rë  r‘  rj  rT   r•   rÄ  s     rj   rÿ  ÚScheduler.unfusable_node}  sD   € ô
 �tÔ7Ô9OÐPÓQ÷ CØ×$Ñ$Ó&Ô&÷Cä7¸¿	¹	ÓBÔBð	
rm   c                ó  • UR                  5       [        R                  R                  ::  a  gUR	                  5       nUR                  5       nSnXEU-  :”  a	  U" S5        g[        S UR                  5        5       5      nU[        R                  R                  R                  R                  4:X  a	  U" S5        gS	S jnU" UR                  5       R                  5      (       a  UR                  5       (       d	  U" S5        gg)
zD
Heuristics to avoid benchmarking predictably slow prologue fusions
Tçš™™™™™ñ?z@prologue fusion will not increase amount of bytes read in kernelFc              3  óÀ   #   • U  HT  nUR                   c  M  UR                   R                  5         H#  nUR                  S:X  d  M  UR                  v •  M%     MV     g 7f)NÚcall_function)r•   r§  r1  r¨  )r˜   rD  r  s      rj   rš   ÚEScheduler.check_prologue_fusion_heuristics_fusable.<locals>.<genexpr>§  sS   é € ð 
â.�Ø�v‰vó ð —V‘V×'Ñ'×)�Ø�t‰t�Ñ&ó	 ˆA�HŽHñ *ñ Ú.ùs   ‚A—,AÁAz\prologue fusion will not increase attempt to fuse in padding bc it increases unaligned readsc                óF   • U R                   S:*  =(       a    U R                  $ )Nr±   )ÚitemsizeÚis_floating_point)r  s    rj   Úlow_prec_fpÚGScheduler.check_prologue_fusion_heuristics_fusable.<locals>.low_prec_fp´  s   € Ø—>‘> QÑ&×B¨5×+BÑ+BÐBrm   zVprologue fusion that must be upcast to fp32 not profitable for low precision templates)r  ztorch.dtyper‹   rx   )rð   rW   r¤   Úinvoke_quant_opsr¾  rÁ  r³   r�   r¿  r`  ra  Úconstant_pad_ndr»  r,  r  rG  )	ri   Úprologue_noder8  r  Ú
read_bytesÚwrite_bytesÚBYTES_THRESHOLD_MULTIPLIERr¯  r‘  s	            rj   Ú(check_prologue_fusion_heuristics_fusableÚ2Scheduler.check_prologue_fusion_heuristics_fusable‡  sõ   € ð ×,Ñ,Ó.´!·'±'×2JÑ2JÓJØà"×8Ñ8Ó:ˆ
Ø#×:Ñ:Ó<ˆð &)Ð"ØÐ'AÑAÓBÙÐRÔSØô ñ 
à"×,Ñ,Ô.ó
ó 
ˆð ”u—y‘y—~‘~×5Ñ5×=Ñ=Ð?Ó?ÙØnôð ô	Cñ ˜×@Ñ@ÓB×HÑH×IÑIØ!×>Ñ>×@Ñ@áØhôð àrm   c                ó¾  ^ • [        U[        5      (       a  [        U[        5      (       d  g[        UR                  [        R                  5      (       a)  [        UR                  [        R                  5      (       d  gUR                  5       (       d  UR                  5       (       a  g[        R                  S:X  a  gUR                  UR                  pCUu  pVUu  pxUR                  5       (       d2  UR                  5       (       d  Xh:w  d  [        U5      [        U5      :w  a  g[        UR                  R                  5      S:”  d#  [        UR                  R                  5      S:”  a  gT R                  [        [        UR                  R                  5      5      5      n	T R                  [        [        UR                  R                  5      5      5      n
[!        Xš5      [        R"                  :”  a  gSU 4S jjnU" U5      (       d  U" U5      (       a  g/ n[%        ['        XW5      5       H   u  nu  pïXï:w  d  M  UR)                  U5        M"     [        U5      S:w  a  gUS   nUU   UU   nn[*        R,                  R.                  R1                  UU5      (       a  UUU4$ [*        R,                  R.                  R1                  UU5      (       a  UUU4$ g)a?  
Fusing two small pointwise nodes significantly reduces kernel overhead
and launch overhead. However, slightly different sizes would prevent fusion.
Here, we decide if expanding sizes of one node is profitible by allowing
fusion, and returns the dimension to expand, node with smaller sizes,
and new size after expand.
Nrû  r   c                ó¦  >• U R                   R                   H¶  nUR                  TR                  ;   a  TR                  UR                     nO%TR                  R                  UR                  5      nU(       d  Me  [        R                  R                  R                  X 5      (       d  M•  [        UR                  [        5      (       a  M¶    g   gr¼  )rº   r»   r¼   rW  rX  rñ  rW   r¤   rR  r�  r’   r*  r‘  )r•   r—  r˜  ri   s      €rj   Úhas_reusable_bufferÚIScheduler.get_expand_dim_for_pointwise_nodes.<locals>.has_reusable_bufferü  s—   ø€ Ø×(Ñ(×.Ô.�à—9‘9 × ;Ñ ;Ó;Ø $× ;Ñ ;¸D¿I¹IÑ F‘Ià $× 0Ñ 0× 4Ñ 4°T·Y±YÓ ?�I÷ �IÜŸ™×,Ñ,×6Ñ6°y×GÓGÜ& y×'<Ñ'<Ô>T×UÓUáñ /ð rm   r   r  )r’   r“   r•   r)   r   ré  r&   rü  rÀ  r”   r²   rº   r­  r�  r3  rF  r  Úsmall_memory_access_thresholdr4  r)  rË   rW   r¤   r¥   Ústatically_known_lt)ri   r…   r†   Ún1_sizesÚn2_sizesÚn1_iter_sizesÚn1_reduce_sizesÚn2_iter_sizesÚn2_reduce_sizesÚnode1_write_memoryÚnode2_write_memoryr�  Úmismatch_dimensionsÚidxÚn1_sizeÚn2_sizeÚmismatch_dimÚmismatch_size1Úmismatch_size2s   `                  rj   Ú"get_expand_dim_for_pointwise_nodesÚ,Scheduler.get_expand_dim_for_pointwise_nodesÂ  sl  ø€ ô ˜%¤×/Ñ/´zÀ%Ì×7WÑ7WØô �u—z‘z¤2×#4Ñ#4×5Ñ5Ü˜5Ÿ:™:¤r×'8Ñ'8×9Ñ9àð ×)Ñ)×+Ñ+¨u×/MÑ/M×/OÑ/OØô ×Ñ Ó)Øð #Ÿ\™\¨5¯<©<�(Ø)1Ñ&ˆØ)1Ñ&ˆà×Ñ× Ñ Ø×!Ñ!×#Ñ#ØÓ1Ü�=Ó!¤S¨Ó%7Ó7àô ˆu× Ñ ×'Ñ'Ó(¨1Ó,´°E×4EÑ4E×4LÑ4LÓ0MÐPQÓ0QØð "×/Ñ/´´T¸%×:KÑ:K×:RÑ:RÓ5SÓ0TÓUÐØ!×/Ñ/´´T¸%×:KÑ:K×:RÑ:RÓ5SÓ0TÓUÐäÐ"Ó7Ü×2Ñ2ó3ð ÷	ñ  ˜u×%Ñ%Ñ)<¸U×)CÑ)CØð !ÐÜ'0´°]Ó1RÖ'SÑ#ˆCÑ#�'ØÕ!Ø#×*Ñ*¨3Ö/ñ (Tô Ð"Ó# qÓ(Øà*¨1Ñ-ˆà˜,Ñ'Ø˜,Ñ'ð 'ˆô �7‰7×Ñ×/Ñ/°À×OÑOØ ¨Ð6Ð6Ü�W‰W×Ñ×1Ñ1°.À.×QÑQØ ¨Ð6Ð6àrm   c                ó’  ^• XL a  g[        U[        5      (       a  UR                  U5      $ [        U[        5      (       a  g[        X5      nUR	                  5       (       a4  U R                  UR                  5       5      R                  X5      (       a  g[        U[        5      (       d  [        U[        5      (       a	  U" S5        g[        U[        [        45      (       a  UR	                  5       (       d	  U" S5        g[        U[        [        45      (       a  UR	                  5       (       d	  U" S5        gUR                  5       UR                  -  (       a	  U" S5        gUR	                  5       (       Gac  [        R                  (       d	  U" S5        gUR                  5       (       d  UR	                  5       (       a	  U" S5        gUR!                  5       n[        U["        R$                  5      (       d	  U" S	5        gUR'                  5       n[)        S
 UR*                   5       5      U-
  nUR-                  5       U-  (       a	  U" S5        gUR/                  5       (       d  UR/                  5       (       a	  U" S5        gUR1                  5       mTSS  HK  n	U	R3                  5       n
U
 H2  n[5        U4S jUR6                   5       5      (       a  M)  U" S5            g   MM     [        U[8        5      (       d  U/O2UR:                   Vs/ s H  oÌR	                  5       (       d  M  UPM     snn[=        U5      S:X  d   eUS   n[=        TS   R>                  5      S:X  aU  [=        TS   R>                  S   R6                  5      S:X  a,  TS   R>                  S   R6                  S   R@                  UL d	  U" S5        gU RC                  XU5      (       d  gUR	                  5       (       aH  UR/                  5       (       d*  UR                  5       (       d  [        RD                  (       d	  U" S5        gUR-                  5       [F        RH                  RJ                  -  (       d0  UR-                  5       [F        RH                  RJ                  -  (       a	  U" S5        gUR                  5       nUR                  5       nUU:w  a  U" SUU5        gAU RM                  XUS9n[        U[N        5      (       d   eU(       aB  U[        RP                  :  a.  [        RR                  (       a  U RU                  X5      nUS:¼  a  Un[        RV                  (       aX  U RY                  X5      =n(       a@  Uu  nnnUR[                  UU5        U RM                  X5      n[        U[N        5      (       d   e[        R\                  (       a-  U[        RP                  :  a  U R_                  X5      nUS:¼  a  Un[`        Rc                  [d        Rf                  5      (       a4  [`        Ri                  SURk                  5       URk                  5       U5        [F        Rl                  Ro                  XUU5      (       d  gUR                  5       UR                  -  (       a`  U Rq                  X5      =(       aH    [F        Rl                  Rq                  XUU5      =(       a     U R                  U5      Rq                  X5      $ [F        Rl                  Rs                  XUU5      =(       a     U R                  U5      Rs                  X5      $ s  snf )zR
Determine if it is possible to combine node1 and node2 into a
single fused node.
FTz/grouped node must not be fused with other nodesznode1 is extern or nopznode2 is extern or nopznode1 must go before node2zprologue fusion turned offz2prologue fusion only supported for pointwise nodesz2prologue fusion only supported for TritonTemplatesc              3  ó@   #   • U  H  oR                  5       v •  M     g 7fry   r0  )r˜   r  s     rj   rš   Ú%Scheduler.can_fuse.<locals>.<genexpr>g  s   é € ÐE²_¨cŸ<™<Ÿ>˜>²_ùr7  z;prologue fusion not implemented for kernel for these inputsz:template prologue can only fuse functional pointwise nodesNr
  c              3  ó@   >#   • U  H  oR                   T;   v •  M     g 7fry   rž   )r˜   rD  Úprologue_nodess     €rj   rš   r´  w  s   øé € ÐQÂy¸tŸy™y¨NÖ:Âyùs   ƒz7template prologue can only fuse nodes with a single user   r   zEtemplate prologue can only fuse nodes with a single use into templateztemplate epilogue not satisfiedz#fusion for buffer explicit disabledzdevice mismatch (%s vs %s)rç  z%s and %s has %s shared data):r’   râ  r   r{  rj  rÌ  rî   Úcan_fuse_multi_outputs_templaterm  rë  r‘  rð   rï   r&   rå  r”   r,  r)   r£  Úget_allowed_prologue_inpsr   rW  r=  ré  r�   r—  rœ   r-  r¿   rÁ   r²   r…  r•   r™  rá  rW   r¤   Úno_fuse_buffer_namesrù  r!  Úscore_fusion_memory_thresholdrÎ  r…  Ú$expand_dimension_for_pointwise_nodesr°  rý  r  r{  r  rZ  r[  rh  r„  r0  r§  rþ   Úcan_fuse_verticalÚcan_fuse_horizontal)ri   r…   r†   Úcan_reorderrè  r  r+  ru  Úunsupported_prologue_argsr•   Ú	node_outsrÌ   rD  Útemplate_snodesÚtemplate_snoder[  Údevice2Úshared_data_scoreÚnew_shared_data_scoreÚexpand_analysisÚ
expand_dimÚsmaller_nodeÚexpand_sizer¶  s                          @rj   rþ   ÚScheduler.can_fuse$  s.  ø€ ð Š>Øä�eÔ4×5Ñ5Ø×&Ñ& uÓ-Ð-Ü�eÔ4×5Ñ5ð ä˜Ó%ˆà×Ñ×Ñ 4×#3Ñ#3Ø×ÑÓó$
ç
)Ñ
)¨%Ó
7õ$8ð ä�eÔ1×2Ñ2´jØÔ'÷7
ñ 7
ñ ÐAÔBØä�uÔ8Ô:PÐQ×RÑRØ×%Ñ%×'Ñ'áÐ(Ô)Øä�uÔ8Ô:PÐQ×RÑRØ×%Ñ%×'Ñ'áÐ(Ô)Øà×$Ñ$Ó&¨¯©×8ÙÐ,Ô-Øà×Ñ×ÒÜ×)×)ÙÐ0Ô1Øà×!Ñ!×#Ñ# u×'8Ñ'8×':Ñ':ÙÐHÔIØà×7Ñ7Ó9ˆHÜ˜h¬×(?Ñ(?×@Ñ@ÙÐHÔIØà$,×$FÑ$FÓ$HÐ!ô ÑE°X·_²_ÓEÓEØ'ñ(ð &ð
 ×%Ñ%Ó'Ð*C×CÙÐQÔRØà×-Ñ-×/Ñ/°5×3QÑ3Q×3SÑ3SÙÐPÔQØà"Ÿ_™_Ó.ˆNØ& s¨Ó+�Ø ×,Ñ,Ó.�	Û$�CÜÔQÀsÇyÂyÓQ×QÓQÙÐUÔVÚ$ó %ñ ,ô " %Ô);×<Ñ<ð ‘à!&§¢ÓA¢˜A·±·—a¡ÑAð ô
 �Ó'¨1Ó,Ð,Ð,Ø,¨QÑ/ˆNô �N 2Ñ&×.Ñ.Ó/°1Ó4Ü˜ rÑ*×2Ñ2°1Ñ5×;Ñ;Ó<ÀÓAØ" 2Ñ&×.Ñ.¨qÑ1×7Ñ7¸Ñ:×?Ñ?À>ÒQáØ[ôð à×@Ñ@ÀÈs×SÑSØà×Ñ×ÑØ×*Ñ*×,Ñ,Ø×!Ñ!×#Ñ#Ü×)×)áÐ1Ô2Øà×"Ñ"Ó$¤q§w¡w×'CÑ'C×CØ×"Ñ"Ó$¤q§w¡w×'CÑ'C×CáÐ5Ô6ØØ×!Ñ!Ó#ˆØ×"Ñ"Ó$ˆØ�WÓÙÐ,¨f°gÔ>ØØà ×4Ñ4ØÐ4Mð 5ð 
Ðô Ð+¬S×1Ñ1Ð1Ð1ö Ø!¤F×$HÑ$HÓHÜ×1×1à$(×$JÑ$JÈ5Ó$XÐ!Ø$¨Ó)Ø$9Ð!ä×6×6Ø#×FÑFÀuÓTÐTˆOÕTà6EÑ3ˆZ˜ {Ø×<Ñ<¸ZÈÔUØ $× 8Ñ 8¸Ó FÐÜÐ/´×5Ñ5Ð5Ð5ô ×1×1Ø!¤F×$HÑ$HÓHà$(×$MÑ$MØó%Ð!ð %¨Ó)Ø$9Ð!ä×)Ñ)¬'¯-©-×8Ñ8Ü×#Ñ#Ø.Ø—‘Ó Ø—‘Ó Ø!ô	ô �y‰y×!Ñ! $¨uÐ6G×HÑHØà×$Ñ$Ó&¨¯©×8ð ×&Ñ& uÓ4÷ MÜ—I‘I×/Ñ/°¸UÐDUÓV÷Mà×$Ñ$ VÓ,×>Ñ>¸uÓLðô —9‘9×0Ñ0Ø˜UÐ$5ó÷ Mà×"Ñ" 6Ó*×>Ñ>¸uÓLðMùòs Bs   Ì]Ì/]c                ó  • UR                  5       n[        X5      n[        [        5      nUR                   Ht  nU R
                  R                  UR                  UR                  5      n[        U[        5      (       a  U R                  XaU5      (       a  Ma  XW   R                  U5        Mv     UR                  R                   H”  n[        U[        5      (       d  M  UR                  U R
                  R                  UR                  UR                  5      5      n	U	(       d  Mb  U	 H,  n
U R                  X¨5      (       d  M  U	R!                  U
5        M.     M–     [#        S [$        R&                  R)                  UR+                  5       5       5       5      nX³-  (       a	  U" S5        gUR-                  5       nU HJ  nU R.                  U   R1                  5       nXÀR2                  U   R4                  -  (       d  MB  U" S5          g   g)zö
Check if it is legal to fuse a consumer (node2) into a producer (node1).

We can fuse them if all the reads of node2 either match
corresponding writes in node1, or are written by nodes that can
be scheduled before the fusion of node1 and node2.
c              3  ó:   #   • U  H  nUR                   v •  M     g 7fry   r×  rØ  s     rj   rš   Ú.Scheduler.can_fuse_vertical.<locals>.<genexpr>ú  s   é € ð $
âU�ð �HŽHÚUùr  zmemory deps did not matchFz(intermediate nodes between node1 & node2T)r=  r{  r   r  rŒ  rƒ  rñ  r¼   r’   r4   r¡  rË   rº   r­  r2   Úfusable_read_and_writer°  r   r  r  r*  rÃ   rð   rX  r2  r)  rï   )ri   r…   r†   Únode1_buf_namesr  Úremaining_deps_by_namerÆ   r¼   ÚcdÚ	remainingr  Úremaining_depsÚnode1_op_namesr  s                 rj   r¼  ÚScheduler.can_fuse_verticalÛ  s´  € ð  ×0Ñ0Ó2ˆÜ˜Ó%ˆÜ7BÄ4Ó7HÐà×+Ô+ˆCØ×(Ñ(×,Ñ,¨S¯X©X°s·x±xÓ@ˆDÜ˜#œw×'Ñ'¨D×,AÑ,AÀ#Èe×,TÑ,TÙØ"Ñ(×/Ñ/°Ö4ñ	 ,ð ×#Ñ#×*Ô*ˆBÜ˜b¤)×,Ñ,ÙØ.×2Ñ2Ø×%Ñ%×)Ñ)¨"¯'©'°2·7±7Ó;óˆI÷ ˆyÛ#�BØ×2Ñ2°2×:Ó:Ø!×(Ñ(¨Ö,ó $ñ +ô $ñ $
ä —‘×4Ñ4Ð5K×5RÑ5RÓ5TÔUó$
ó 
ˆð
 ×+ñ
 Ð+Ô,Øà×2Ñ2Ó4ˆÛ"ˆDØ×&Ñ& tÑ,×=Ñ=Ó?ˆGØ× 7Ñ 7¸Ñ @× JÑ J×JÑJÙÐ>Ô?Ùñ	 #ð rm   c                ó  ^• UR                   UR                  5       ;  a  gUR                  R                   Vs/ s H!  nUR                   UR                  :X  d  M  UPM#     nn[        U5      S:w  a  gUS   m[        T[        5      (       a  g[        T[        5      (       d   e[        TR                  [        R                  5      (       a  gU R                  UR                     nU/n[        U[        5      (       a  UR                  nSnU He  n	U	R                  R                    V
s/ s H  n
U
R                   U:X  d  M  U
PM     nn
U(       d  MD  US-  n[#        U4S jU 5       5      (       a  Me    g   US:*  $ s  snf s  sn
f )NFr   r   c              3  ó$  >#   • U  H…  n[        U[        5      =(       ai    [        UR                  [        R
                  5      (       + =(       a9    UR                  TR                  :H  =(       a    UR                  TR                  :H  v •  M‡     g 7fry   )r’   r2   r!   r½   r#   ÚTMPrÂ   )r˜   r—  rs  s     €rj   rš   Ú-Scheduler.fusable_weak_dep.<locals>.<genexpr>5  sn   øé € ð ò
 +�Dô	 ˜4¤Ó+÷ ,Ü+¨D¯J©J¼¿¹ÓAÔA÷,à—J‘J %§+¡+Ñ-÷,ð —I‘I §¡Ñ+ô,ò +ùs   ƒBB)r¼   r=  rº   r­  rˆ  r²   r’   r3   r2   r!   r½   r#   rØ  ró  r	  rÁ   r»   rœ   )ri   Úweak_depr…   r†   rs  Úmutating_writesrH  Úrelevant_reading_nodesÚnum_concurrent_readsÚreading_noder—  Úrelevant_readss       `       rj   r¡  ÚScheduler.fusable_weak_dep  s€  ø€ ð �=‰= × 6Ñ 6Ó 8Ó8Øð ×*Ñ*×1Ò1ó
â1�Ø�z‰z˜X×2Ñ2Ñ2÷ Ù1ð 	ð 
ô
 ˆÓ 1Ó$ØØ Ñ"ˆÜ�eœW×%Ñ%ØÜ˜%¤×+Ñ+Ð+Ð+ä˜uŸ{™{¬D¯H©H×5Ñ5Øà×+Ñ+¨H×,AÑ,AÑBˆ	Ø"' ÐÜ�eÔ7×8Ñ8Ø%*§\¡\Ð"Ø ÐÛ2ˆLð )×4Ñ4×:Ò:óâ:�DØ—9‘9 	Ñ)÷ Ù:ð ð ö
 "ÙØ  AÑ%Ð Üô ñ
 +ó÷ ó ñ ñ! 3ð" $ qÑ(Ð(ùòK
ùò*s   ¹E>ÁE>Ä+FÅFc                óz  • [        U[        5      (       Gaƒ  U R                  R                  UR                  UR                  5      nX2R                  :w  dR  [        UR                  [        R                  5      (       d)  [        UR                  [        R                  5      (       a  g[        R                  (       a:  UR                  UR                  :w  a   UR                  5       nUR                  5       nU R                  UR                  5      (       a  gUR                  UR                  :H  =(       aa    [        UR                   5      [        UR                   5      :¬  =(       a/    UR                   S [        UR                   5       UR                   :H  $ [        U["        5      (       a�  U R                  R                  UR                  UR                  5      nU R                  R                  UR                  UR                  5      nUR                  UR                  :X  a  UR                  b  X4:X  a  ggr_  )r’   r2   rƒ  rñ  r¼   r!   r½   r#   rØ  r&   rÎ  r  rÈ  rÚ  rL  r²   rÂ   r3   )ri   r—  rs  Ú	read_nameÚ
write_names        rj   rÎ  Ú Scheduler.fusable_read_and_writeC  s‚  € Ü�dœI×&Ò&Ø×-Ñ-×1Ñ1°$·)±)¸T¿Y¹YÓGˆIð ŸZ™ZÓ'Ü& t§z¡z´4·8±8×<Ñ<Ü& u§{¡{´D·H±H×=Ñ=àä×0×0°T·]±]ÀeÇnÁnÓ5Tð —~‘~Ó'�ØŸ™Ó)�ð ×1Ñ1°%·*±*×=Ñ=Øð —
‘
˜eŸk™kÑ)÷ ?Ü˜Ÿ	™	“N¤c¨%¯*©*£oÑ5÷?à—I‘IÐ/¤ E§J¡J£Ð0°E·J±JÑ>ðô
 ˜œg×&Ñ&Ø×-Ñ-×1Ñ1°$·)±)¸T¿Y¹YÓGˆIØ×.Ñ.×2Ñ2°5·:±:¸u¿z¹zÓJˆJà—	‘	˜UŸZ™ZÓ'Ø—J‘JÑ*ØÓ+àØrm   c                ó@   • [         R                  R                  X5      $ ry   )rW   r¤   Úget_dep_size_hint)ri   rÆ   rõ  s      rj   r�  ÚScheduler.dep_size_hintj  s   € Ü�w‰w×(Ñ(¨Ó:Ð:rm   c                óæ  ^ ^^• U4S jnU(       a8  [         R                  X5      (       a  [         R                  X5      nU" US5      $ [        UR                  R
                  5      [        UR                  R                  5      -   n[        UR                  R
                  5      [        UR                  R                  5      -   n	[        X‰5      S-  [        X‰5      :  a•  X‰:”  a  X!p!UR                  R
                  UR                  R                  -   V
s/ s H9  n
X¢R                  R
                  ;   d  X¢R                  R                  ;   d  M7  U
PM;     nn
U" [        UU 4S jU 5       5      S5      $ UR                  R
                  UR                  R                  -  UR                  R
                  UR                  R                  -  -  nU" [        U 4S jU 5       5      S5      $ s  sn
f )zV
The first term in our fusion score that estimates number of saved
memory operations.
c                ó   >• T(       a  X4$ U $ ry   rw   )rz  Úis_mix_order_reductionÚreturn_is_mix_order_reductions     €rj   Ú_construct_return_valueÚ>Scheduler.score_fusion_memory.<locals>._construct_return_valuez  s   ø€ ö 1ð Ð/ðð ðrm   TrŽ  c              3  óH   >#   • U  H  nTR                  UT5      v •  M     g 7fry   ©r�  )r˜   rÆ   rõ  ri   s     €€rj   rš   Ú0Scheduler.score_fusion_memory.<locals>.<genexpr>˜  s!   øé € ÐIÂD¸S�D×&Ñ& s¨K×8Ð8ÂDùó   ƒ"Fc              3  óF   >#   • U  H  nTR                  U5      v •  M     g 7fry   rï  r  s     €rj   rš   rð  Ÿ  s!   øé € ÐFÒ3E¨C�×"Ñ" 3×'Ð'Ò3Eùrõ  )
rŽ   rþ   rÜ   r²   rº   r»   r­  rä  r  ré   )ri   r…   r†   rõ  rë  rè  rì  rz  Únode1_dep_lenÚnode2_dep_lenrÆ   r  Úcommon_memory_depss   `  ``        rj   rù  ÚScheduler.score_fusion_memorym  s©  ú€ õ	ö %Ô):×)CÑ)CÀE×)QÑ)Qô
 &×6Ñ6°uÓDˆEÙ*¨5°$Ó7Ð7ä˜E×-Ñ-×3Ñ3Ó4´s¸5×;LÑ;L×;SÑ;SÓ7TÑTˆÜ˜E×-Ñ-×3Ñ3Ó4´s¸5×;LÑ;L×;SÑ;SÓ7TÑTˆô ˆ}Ó,¨qÑ0´3°}Ó3TÓTØÓ,Ø$�uð !×,Ñ,×2Ñ2°U×5FÑ5F×5MÑ5MÒMóâM�CØ×+Ñ+×1Ñ1Ó1°S×<MÑ<M×<TÑ<TÑ5T÷ ÙMð ð ñ +ÜÕIÁDÓIÓIÈ5óð ð $×/Ñ/×5Ñ5¸×8IÑ8I×8PÑ8PÑPØ×Ñ×#Ñ# e×&7Ñ&7×&>Ñ&>Ñ>ñ
Ðñ 'ÜÔFÑ3EÓFÓFÈó
ð 	
ùòs   Ä6G.ÅG.c                ó¾  • [        U5      S:X  a  U$ 0 nU Hƒ  u  p4UR                  5       UR                  5       :X  d   eUR                  5       n[        U R                  U5      R	                  X45      5      nXb;  a  X44/X&'   Mo  X&   R                  X445        M…     [        UR                  5       [        R                  " S5      S9S   n[        U5      S:”  d   eU$ )Nr   rŒ  r   )
r²   rî   r!  rÌ  Úget_fusion_pair_priorityrË   rä  r/  r©  rª  )ri   rà  Ú"possible_fusions_group_by_priorityr…   r†   r[  Úfusion_pair_priorityÚ&possible_fusions_with_highest_prioritys           rj   r  Ú4Scheduler.get_possible_fusions_with_highest_priority¢  sþ   € ô
 ÐÓ  AÓ%Ø#Ð#ð ð 	+ó -‰LˆEØ×#Ñ#Ó%¨×)9Ñ)9Ó);Ó;Ð;Ð;Ø×%Ñ%Ó'ˆFÜ#&Ø× Ñ  Ó(×AÑAÀ%ÓOó$Ð ð $ÓMà�NðLÐ2ÓHð 3ÑH×OÑOØ�Nöñ -ô 25Ø.×4Ñ4Ó6¼H×<OÒ<OÐPQÓ<Rñ2
à
ñ2Ð.ô Ð9Ó:¸QÓ>Ð>Ð>Ø5Ð5rm   c                óD   • [         R                  R                  " U /UQ76 $ )z
Shim for list.sort(key=...)
)rW   r§  Úscore_fusionrî  s     rj   r  ÚScheduler.score_fusion_keyÂ  s   € ô �y‰y×%Ò% dÐ3¨UÒ3Ð3rm   c                óö   • [        [        R                  R                  5       5      n[	        U R
                  5       H9  nUR                  XR                  5        UR                  UR                  5        M;     g)zW
Populate node.last_usage recursively (also for the nodes within a FusedSchedulerNode)
N)
r   rW   r¤   r/  r´   r5  rù  ró  r¨  r~  )ri   r÷  r•   s      rj   r;  ÚScheduler.compute_last_usageÊ  sV   € ô
 )¬¯©×)AÑ)AÓ)CÓDÐä˜TŸZ™ZÖ(ˆDØ×ÑÐ 3×5LÑ5LÔMØ×&Ñ& t§¡Ö7ò )rm   c                ó  • [        U R                  [        R                  R                  -
  [        R                  R
                  R                  -
  5       GHŒ  nXR                  ;   a[  U R                  U   nUR                  5       (       a5  [        R                  R
                  R                  UR                  5        Ml  Mn  U[        R                  R                  ;   d  MŽ  [        R                  R                  U   n[        U[        R                  5      (       a+  [        R                  R
                  R                  U5        Mõ  [        U[        R                  5      (       a  GM  UR                   n[        U[        R"                  5      (       a  UR%                  5       (       d   e[        R                  R
                  R                  UR                   5        GM�     U R                  R'                  5         g)z*Free any buffers that are no longer neededN)r‘  rA  rW   r¤   r�  rR  ÚfreedrX  rb  Úcodegen_freer•   rò  r’   r)   râ  rP  rã   r3  Úis_input_bufferrì  )ri   r¼   rÄ   r  Ústorages        rj   Úfree_buffersÚScheduler.free_buffersÕ  sU  € äØ×%Ñ%Ü�g‰g×%Ñ%ñ&ä�g‰g×"Ñ"×(Ñ(ñ)÷
ˆDð
 ×'Ñ'Ó'Ø×&Ñ& tÑ,�Ø—<‘<—>‘>Ü—G‘G×(Ñ(×5Ñ5°c·h±hÖ?ñ "àœŸ™×-Ñ-Õ-Ü—g‘g×*Ñ*¨4Ñ0�Ü˜c¤2×#5Ñ#5×6Ñ6Ü—G‘G×(Ñ(×5Ñ5°cÖ:Ü ¤R×%6Ñ%6×7Ñ7Úà!Ÿh™h�Gä" 7¬B¯M©M×:Ñ:¸w×?VÑ?V×?XÑ?XðØXä—G‘G×(Ñ(×5Ñ5°g·l±l×Cñ)
ð, 	×!Ñ!×'Ñ'Õ)rm   c                ó†   • U R                   R                  5        H  nUR                  5         M     U R                  5         g ry   )r  rÃ   Úflushr	  )ri   r  s     rj   r
	  ÚScheduler.flushï  s.   € Ø—}‘}×+Ñ+Ö-ˆGØ�M‰MŽOñ .à×ÑÕrm   c                óø  • [        U[        5      (       d   e[        S   S==   S-  ss'   [        R                  " [        SS95         UR                  5         UR                  5         S S S 5        UR                  n[        U[        R                  5      (       d   S[        U5      < 35       eUR                  [        R                  R                  5        U R                  5         g ! , (       d  f       N‡= f)Nrø  Úextern_callsr   F)Úincrease_kernel_countztype(node)=)r’   rë  r   rW   Úset_kernel_handlerr.   r›  rü  r•   r)   re  rÀ   r‹  r¤   rR  r	  )ri   Úscheduler_noder•   s      rj   Úcodegen_extern_callÚScheduler.codegen_extern_callô  s¾   € Ü˜.Ô*C×DÑDÐDÐDô
 	�Ñ˜^Ó,°Ñ1Ó,Ü×!Ò!¤&¸uÑ"EÕFØ×0Ñ0Ô2Ø×#Ñ#Ô%÷ Gð ×"Ñ"ˆÜ˜$¤§¡×0Ñ0ÐB°[´T¸$³Z±MÐ2BÓBÐ0Ø�‰”Q—W‘W×)Ñ)Ô*Ø×ÑÕ÷ GÕFús   Á	!C+Ã+
C9c                ó|  • [        UR                  5      (       a  UR                  c
   U S35       e[        R                  R                  U5        [        UR                  5      nUc  [        SUR                   35      e[        5       (       d¦  UR                  S:X  aN  [        R                  R                  U5      =nR                  S:  a  [        U[        R                  " 5       5      e[        UR                  5      (       a.  UR                  S:X  d  [!        [        R                  " 5       5      eU" U 5      $ )Nz( should have been normalized in loweringzUnsupported device type: rß   é   rB  )rR   rÀ   r½   rW   r¤   Úadd_device_infor-   rë  r$   r¿  rß   Úget_device_propertiesÚmajorr5   ÚinspectÚcurrentframer6   )ri   r[  Údevice_schedulingÚdevice_propss       rj   Úcreate_backendÚScheduler.create_backend  s÷   € Ü˜&Ÿ+™+×&Ñ&¨&¯,©,Ñ*Bð 	
ØˆhÐ>Ð?ó	
ÐBô 	
�‰×Ñ Ô'ä5°f·k±kÓBÐØÑ$ÜÐ!:¸6¿;¹;¸-ÐHÓIÐIä�|‰|à—‘˜vÓ%Ü%*§Z¡Z×%EÑ%EÀfÓ%MÐM�\×TÑTÐWXÓXä(¨´w×7KÒ7KÓ7MÓNÐNÜ˜Ÿ™×$Ñ$¨V¯[©[¸EÓ-AÜ#¤G×$8Ò$8Ó$:Ó;Ð;á  Ó&Ð&rm   c                ó„   • Uc   eXR                   ;  a  U R                  U5      U R                   U'   U R                   U   $ ry   )r  r	  rZ  s     rj   rÌ  ÚScheduler.get_backend  s@   € ØÑ!Ð!Ð!ØŸ™Ó&Ø$(×$7Ñ$7¸Ó$?ˆD�M‰M˜&Ñ!Ø�}‰}˜VÑ$Ð$rm   c                ó®  ^ • SU 4S jjnUR                  5        VVs0 s H?  nUR                  c  M  UR                  R                  5         H  nU" U5      U4S _M     MA     nnn[        UR	                  5       5      nU(       aJ  [        U[        R                  " S5      S9u  pg[        R                  R                  R                  U5        g g s  snnf )Nc                óè   >• U TR                   ;  aM  TR                   R                  [        U R                  R                  5       VV s0 s H  u  pX_M	     sn n5        TR                   W    $ s  sn nf ry   )rB  r¨  r4  r¤   r5  )rD  r1  ri   s     €rj   Ú	get_orderÚ*Scheduler.enter_context.<locals>.get_order  s^   ø€ Ø˜×,Ñ,Ó,Ø×$Ñ$×+Ñ+¼iÈÏÉÏÉÔ>VÔ,WÒ>V±d°a¨QªTÑ>VÒ,WÔXØ×'Ñ'¨Ñ*Ð*ùó -Xs   Á	A.
r   rŒ  )rD  ztorch.fx.Noder‹   r!  )r�   r•   r§  r  r  r  r©  rª  rW   r¤   rR  Úenter_context)ri   r•   r"	  rD  r  r¯  rŽ  Úlasts   `       rj   r$	  ÚScheduler.enter_context  s¹   ø€ ÷	+ð —^‘^Ô%ô
â%�Ø�v‰vó ð —V‘V×'Ñ'×)�ñ �q‹\˜1Ð˜tÒ#ñ *ñ Ù%ð 	ñ 
ô �w—|‘|“~Ó&ˆÞÜ˜'¤x×':Ò':¸1Ó'=Ñ>‰GˆAÜ�G‰G× Ñ ×.Ñ.¨tÕ4ð ùó
s
   �C²1Cc                óÖ   ^•  U R                   U   R                  n[        U4S jU 5       5      =(       a#    XR                  ;  =(       a    XR
                  ;  $ ! [         a     gf = f)NFc              3  ón   >#   • U  H*  oR                   =(       d    UR                  5       T;   v •  M,     g 7fry   )rÄ  r0  )r˜   rD  r9  s     €rj   rš   ÚAScheduler.can_buffer_be_removed_through_fusion.<locals>.<genexpr>8  s)   øé € ÐVÒPUÈ—‘×C §¡£Ð3CÑ CÔCÒPUùrá  )rX  r-  ÚKeyErrorrœ   rƒ  ró  )ri   r¼   r9  r-  s     ` rj   r7  Ú.Scheduler.can_buffer_be_removed_through_fusion0  sj   ø€ ð	Ø×$Ñ$ TÑ*×0Ñ0ˆEô ÔVÑPUÓVÓV÷ 4Ø×1Ñ1Ñ1÷4à×3Ñ3Ñ3ð	
øô ó 	Ùð	ús   ƒA Á
A(Á'A(c                ó   • UR                   n[        U[        R                  R                  R
                  5      (       ax  UR                  =n(       ae  [        U5      u  pEU[        R                  ;   d  U[        R                  ;   a0  [        U[        R                  R                  5      (       d   eSU 3$ [        R                  R                  R                  R                  (       d  [        R                  c  g[        U[         5      (       a0  UR"                   H  nU R%                  U5      nU(       d  M  Us  $    gUR                   c   eUR'                  5       (       d  UR)                  5        S3$ [        UR                   [        R*                  5      (       a  g[        UR                   [        R,                  5      (       a  g[/        UR                   SS5      (       a  g[1        UR                   5      (       a  g	U R3                  U5      =n(       a  U$ [        R                  R4                  (       a  [7        U5      (       a  g
g)zr
Return the reason why we should partition the inductor graph on this node,
or None if the node is cudagraphable.
zcustom partition op: Nz6partition includes all ops when cudagraphs is disabledz opszDeviceCopy opszConditional opsÚunbacked_bindingszunbacked binding opszCUDAGraph-unsafe custom opszdynamic shape ops)r•   r’   r¿  rÀ  r)   r“  rì  rM   r&   Úcustom_should_partition_opsÚ_opsÚ
OpOverloadrá   r[   rE   Úwrapperr¿   rÁ   Úshould_partitionrR   rî   Ú
DeviceCopyÚConditionalr¬  rQ   Ú&_uses_cudagraph_unsafe_unbacked_symintÚcudagraph_skip_dynamic_graphsrÛ  )ri   r•   rÞ  r1  Úop_overload_packet_nameÚop_overload_namer\  r~  s           rj   r2	  ÚScheduler.should_partition=  sº  € ð —)‘)ˆÜ�gœuŸ™×1Ñ1×@Ñ@×AÑAØ×%Ñ%Ð%ˆBÕ%ä8DÀRÓ8HÑ5Ð#à'¬6×+MÑ+MÓMØ#¤v×'IÑ'IÓIä! "¤e§j¡j×&;Ñ&;×<Ñ<Ð<Ð<Ø.Ð/?Ð.@ÐAÐAô —‘×&Ñ&×-Ñ-×8×8Ü6×>Ñ>ÑFàKä�dÔ.×/Ñ/ØŸœ�Ø×.Ñ.¨uÓ5�ß�6Ø!’Mñ %ð à�y‰yÑ$Ð$Ð$à�{‰{�}‰}Ø—o‘oÓ'Ð(¨Ð-Ð-ä�d—i‘i¤§¡×/Ñ/Ø#ä�d—i‘i¤§¡×0Ñ0Ø$ä�4—9‘9Ð1°4×8Ñ8Ø)ä! $§)¡)×,Ñ,Ø0à×@Ñ@ÀÓFÐFˆ6ÕFØˆMô �=‰=×6×6Ü-¨d×3Ñ3Ø*àrm   c                ó’  • [        5       n[        R                  (       d  U$ U R                   GH  nUR                  nUc  M  [        U[        R                  R                  R                  5      (       d  MJ  UR                  nUc  M[  [        U5      u  pVU[        R                  ;  a  U[        R                  ;  a  M’  UR                  5        Hn  n[        R                  R                  R!                  U5      n[#        U[$        R&                  [$        R(                  45      (       d  M]  UR+                  U5        Mp     GM     U$ )zS
Collect output unbacked symints from ops in config.cudagraph_unsafe_unbacked_ops.
)r   r&   Úcudagraph_unsafe_unbacked_opsr5  r•   r’   r¿  rÀ  r)   r“  rì  rM   r‹  rW   r¤   r¥   r¦   r"   r#   ÚUNBACKED_INTÚUNBACKED_FLOATr  )ri   Úunsafe_symintsr•   rÞ  r1  r7	  r8	  Úsyms           rj   Ú&_get_cudagraph_unsafe_unbacked_symintsÚ0Scheduler._get_cudagraph_unsafe_unbacked_symints|  sú   € ô
 4>³<ˆä×3×3Ø!Ð!à—J•JˆDØ—i‘iˆGØ‰Ùä˜g¤u§¡×'9Ñ'9×'HÑ'H×IÑIÙà×$Ñ$ˆBØ‰zÙä8DÀRÓ8HÑ5Ð#à'¬v×/SÑ/SÓSØ$¬F×,PÑ,PÓPáà×7Ñ7Ö9�Ü—g‘g×&Ñ&×/Ñ/°Ó4�Ü! #¬×(9Ñ(9¼4×;NÑ;NÐ'O×PÓPØ"×&Ñ& sÖ+ô :ñ' ð0 Ðrm   c                óð   • U R                  5       nU(       d  g [        U5      nU HM  n[        R                  R                  R                  U5      nUR                   H  nXb;   d  M
  SU 3s  s  $    MO     g )Nz'uses cudagraph-unsafe unbacked symint: )r@	  rÛ  rW   r¤   r¥   r¦   r    )ri   r•   r>	  Únode_symbolsr?	  Úsimplified_symÚfree_syms          rj   r5	  Ú0Scheduler._uses_cudagraph_unsafe_unbacked_symint   sn   € ð ×DÑDÓFˆÞØä5°dÓ;ˆãˆCÜŸW™W×-Ñ-×6Ñ6°sÓ;ˆNØ*×7Ô7�ØÕ-ØDÀXÀJÐOÔOó 8ñ  ð rm   c                óä   • 0 nUR                  [        R                  R                  5        U R                   H4  nUR
                  R                  5        H  u  p4UR                  X'   M     M6     U$ )zf
Return a mapping from name strings to the corresponding graph inputs or
base scheduler node outputs.
)r¨  rW   r¤   rò  r5  r‡  r/  r•   )ri   r  r•   r¼   Úscheduler_buffers        rj   Úget_name_to_nodesÚScheduler.get_name_to_nodes±  sd   € ð UWˆØ×ÑœAŸG™G×0Ñ0Ô1à—J”JˆDØ*.×*>Ñ*>×*DÑ*DÖ*FÑ&�Ø%5×%:Ñ%:�Ó"ó +Gñ ð Ðrm   c           	     óæ  • [        [        R                  R                  5       VVs0 s H  u  p#X2_M	     nnn[        [        R                  R	                  5       5       VVs0 s H  u  p#X2_M	     nnn/ [        R                  l        [        U5       HÏ  u  pgUR                  (       a  M  / nUR                   H#  nUR                  UR                  U5      5        M%     / n	UR                   H1  n
U	R                  UR                  U
R                  5       5      5        M3     [        R                  R
                  R                  [        UUU	UR                  5      5        MÑ     gs  snnf s  snnf )zj
computes a mapping from partition input/output indices to graph input/output
indices for each partition.
N)r4  rW   r¤   rò  r/  Úpartition_mapsÚskip_cudagraphÚinput_nodesrË   rñ  Úoutput_nodesr0  rN   Úconstant_names)ri   Ú
signaturesrª  r¼   Úname_to_graph_input_indexÚname_to_graph_output_indexÚpartition_idÚ	signatureÚinput_mappingÚoutput_mappingr•   s              rj   Úcompute_graph_partition_mapsÚ&Scheduler.compute_graph_partition_mapsÁ  s;  € ô (1´·±×1EÑ1EÔ'Fô%
Ú'F™)˜#ˆDŠIÑ'Fð 	"ñ %
ô (1´·±×1IÑ1IÓ1KÔ'Lô&
Ú'L™)˜#ˆDŠIÑ'Lð 	#ñ &
ð "$Œ�‰ÔÜ'0°Ö'<Ñ#ˆLØ×'×'ñ
 àˆMØ!×-Ô-�Ø×$Ñ$Ð%>×%BÑ%BÀ4Ó%HÖIñ .ð  ˆNØ!×.Ô.�Ø×%Ñ%Ð&@×&DÑ&DÀTÇ]Á]Ã_Ó&UÖVñ /ô �G‰G×"Ñ"×)Ñ)Ü!Ø Ø!Ø"Ø×,Ñ,ó	öò! (=ùó%
ùó&
s   §E'Á"E-c                ó¾  ^•     SS jm    SS jn[        5       R                  " S U 5       6 nUR                  " U4S jUR                  5        5       6   U" U5      n[        5       nU HG  n[        R
                  R                  R                  U5      nUR                  UR                  5        MI     [        [        U[        R                  " S5      S95      $ )	a9  
Returns all symbol inputs which are required to be in scope to successfully
perform codegen for this graph partition, including:
- free symbols used in partition nodes
- free symbols in partition input/node shapes, strides, and offsets. This is needed
  for recording cudagraphs for tensors with dynamic shapes.
c                óÖ   • [        U [        R                  5      (       a
  [        5       $ [        U [        R                  5      (       a  [        U 5      $ [        S[        U 5       35      e)z?
Gets symbols used in input node shapes, strides, and offsets.
zUnsupported input node type: )r’   r)   râ  r   r	  rÖ  rÎ  rÀ   rž   s    rj   Úget_input_node_symbolsÚKScheduler.get_graph_partition_symbol_inputs.<locals>.get_input_node_symbols÷  sT   € ô ˜$¤× 2Ñ 2×3Ñ3ä!“|Ð#Ü˜D¤"§)¡)×,Ñ,Ü)¨$Ó/Ð/ô *Ð,IÌ$ÈtË*ÈÐ*VÓWÐWrm   c                ó&   • [        S U  5       5      $ )zœ
Filters a set of symbols that are required for codegen. Skip symbols
that are always internal to kernels, such as SymT.TMP, SymT.INDEX,
and SymT.R0_INDEX.
c              3  óÄ   #   • U  HV  n[        U[        R                  [        R                  [        R                  [        R
                  45      (       d  MR  Uv •  MX     g 7fry   )r"   r#   ÚSIZEÚFLOATr<	  r=	  ©r˜   rÉ  s     rj   rš   ÚVScheduler.get_graph_partition_symbol_inputs.<locals>.filter_symbols.<locals>.<genexpr>  sI   é € ð â �AÜ!ØäŸ	™	ÜŸ
™
Ü×)Ñ)Ü×+Ñ+ð	÷÷ ‘Ú ùs   ‚AA Á	A r   )Úsymbolss    rj   Úfilter_symbolsÚCScheduler.get_graph_partition_symbol_inputs.<locals>.filter_symbols  s   € ô ñ á óó ð rm   c              3  ó8   #   • U  H  n[        U5      v •  M     g 7fry   rÚ  r5  s     rj   rš   Ú>Scheduler.get_graph_partition_symbol_inputs.<locals>.<genexpr>  s   é € ÐIºy°tÔ,¨T×2Ð2ºyùrÚ  c              3  ó8   >#   • U  H  u  pT" U5      v •  M     g 7fry   rw   )r˜   rŽ  r•   r\	  s      €rj   rš   rh	  !  s   øé € ÐNÒ:M©w¨qÑ$ T×*Ð*Ò:Mùs   ƒr¼   rŒ  )r•   z0Union[ir.IRNode, sympy.Expr, ir.TorchBindObject]r‹   úOrderedSet[sympy.Symbol])rd	  rj	  r‹   rj	  )r   rd  r¨  r/  rW   r¤   r¥   r¦   r    r‘  r©  Ú
attrgetter)	ri   Ú	partitionrN	  re	  Úcandidate_symbolsr‚  rÉ  Úsymplified_sr\	  s	           @rj   Ú!get_graph_partition_symbol_inputsÚ+Scheduler.get_graph_partition_symbol_inputsê  sÙ   ø€ ð	XØBð	Xà%ô	Xð 	Ø-ð	à%ô	ô, 7A³l×6HÒ6HÙI¹yÓIð7
Ðð 	× Ò ÜN¸+×:KÑ:KÔ:MÓNñ	
ñ +Ð+<Ó=Ðä(2«ˆÛ"ˆAÜŸ7™7×+Ñ+×4Ñ4°QÓ7ˆLà�J‰J�|×0Ñ0Ö1ñ #ô
 œ& ¬(×*=Ò*=¸fÓ*EÑFÓGÐGrm   c           
     ó  ^ ^• / n[        [        R                  R                  5       5      nT R	                  5       nSUU 4S jjm[        [        U5      [        U5      5       GHj  u  pg[        5       nU H,  n	UR                  U	R                  R                  5       5        M.     UR                  U5      n
[        R                  R                  U V	s/ s H  o™R                  PM     sn	5      n[        UR                  UR                   -   Vs/ s H&  n[#        U[$        5      (       a  M  UR&                  PM(     sn5      U-
  n[        U 4S jU 5       5      n[        5       nU H  n	UR                  U	R(                  5        M      Xè-
   Vs/ s H  nXõ;   d  M
  UPM     nnUR                  U5        U Vs0 s H  nXõ;   d  M
  XõU   _M     nnU Vs0 s H  nXõ;   d  M
  XÿU;   _M     nnU Vs/ s H  nXõ;   d  M
  Xþ;  d  M  UPM     nnU
R                  U5        [        U 4S jU
 5       5      n
U
 Vs/ s H  nT" U5      (       a  M  X_   PM     nnU Vs/ s H$  oÿ[        R                  R*                  ;   d  M"  UPM&     nnT R-                  UU5      n[/        UUUUUU5      nUR1                  U5        UR3                  XJ-
  5      nGMm     USSS2   $ s  sn	f s  snf s  snf s  snf s  snf s  snf s  snf s  snf )z‰
Gets signature for each graph partition, including input nodes, output nodes, and
whether deallocating an input within graph partition.
c                óð   >• TR                   R                  U S5      nUc  g[        UR                  R                  [
        5      (       a,  TR                  R                  U S5      =n(       a  T" U5      $ gg)z¼
Checks if buf_name resolves to a NoneLayout buffer (following mutation_real_name).
Buffers with NoneLayout are not allocated so graph partition should not
take them as inputs or outputs.
NFT)rX  rñ  r’   r•   r=  r=   ró  )rR  rÄ   rH  Úis_unallocated_bufferri   s      €€rj   rs	  ÚFScheduler.get_graph_partition_signature.<locals>.is_unallocated_buffer:  sk   ø€ ð ×"Ñ"×&Ñ& x°Ó6ˆCà‰{Øä˜#Ÿ(™(Ÿ/™/¬:×6Ñ6ð !%× 7Ñ 7× ;Ñ ;¸HÀdÓ KÐK�9ÕKÙ0°Ó;Ð;ààrm   c              3  óZ   >#   • U  H   nTR                   R                  X5      v •  M"     g 7fry   ©ró  rñ  ©r˜   r¼   ri   s     €rj   rš   Ú:Scheduler.get_graph_partition_signature.<locals>.<genexpr>m  ó,   øé € ð /â1�Dð ×'Ñ'×+Ñ+¨D×7Ð7Ú1ùó   ƒ(+c              3  óZ   >#   • U  H   nTR                   R                  X5      v •  M"     g 7fry   rv	  rw	  s     €rj   rš   rx	  —  ry	  rz	  Nr
  )rR  r  r‹   rx   )r   rW   r¤   r/  rI	  r)  r´   r¨  r‡  r  r$  r(   rb  rc  rº   r»   r­  r’   r4   r¼   r~  r  ro	  r:   rË   rd  )ri   Ú
partitionsÚskip_cudagraphsrQ	  Úunmet_output_namesr  rl	  rM	  Úoutput_namesr•   Úreturned_output_namesrº   r™  Úpartition_input_namesrA  r¼   Úextra_input_namesrN	  Úinput_deallocationÚextra_output_namesrO	  rP	  Úsymbol_inputsÚpartition_signaturers	  s   `                       @rj   Úget_graph_partition_signatureÚ'Scheduler.get_graph_partition_signature.  sZ  ù€ ð ˆ
ä'¬¯©×(@Ñ(@Ó(BÓCÐØ×-Ñ-Ó/ˆ÷	ð 	ô, *-Ü�ZÓ ¤(¨?Ó";÷*
Ñ%ˆIô -7«LˆLã!�Ø×#Ñ# D×$8Ñ$8×$=Ñ$=Ó$?Ö@ñ "ð %1×$=Ñ$=Ð>PÓ$QÐ!ô '×1Ñ1×<Ñ<Ù.7Ó8ªi d×!Ô!©iÑ8óˆKô ð "-×!2Ñ!2°[×5GÑ5GÒ!Góâ!G˜AÜ)¨!¬W×5ó ˜ŸœÙ!Gñóð ñð "ô %/ô /á1ó/ó %Ð!ô
 5?³LÐ Û!�Ø$×+Ñ+¨D¯O©OÖ<ñ "ð 2Ò@ó!â@�DØÑ'÷ Ù@ð ð !ð
 "×(Ñ(Ð):Ô;ñ 2óâ1�DØÑ'ó )� 4Ñ(Ò(Ù1ð ð ñ 2ó"â1�DØÑ'ó 3�Ð2Ñ2Ò2Ù1ð ð "ñ 2ó"â1�DØÑ'ó à,0Ñ,L÷ Ù1ð ð "ð "×(Ñ(Ð);Ô<ä$.ô /á1ó/ó %Ð!ñ 2óâ1�DÙ,¨T×2ó #�Ô"Ù1ð ð ñ "7óÚ!6˜Ä!Ç'Á'×BSÑBSÑ:S—Ñ!6ð ð ð !×BÑBØ˜;óˆMô #:ØØØØ"ØØó#Ðð ×ÑÐ1Ô2à!6×!<Ñ!<Ø"Ñ:ó"ÓñK*
ðR ™$˜B˜$ÑÐùòy 9ùòùò*!ùòùò
"ùò"ùòùòs`   ÃK
ÄK
Ä,K
Æ	K$ÆK$Æ9	K)Ç	K)Ç	K.Ç"	K.Ç1	K3Ç>K3ÈK3È7K8ÉK8É!K=É?K=c                óº  • UR                   R                  5        VVs0 s H'  u  p#U[        R                  R                  ;  d  M%  X#_M)     nnnUR
                  R                  5        VVs0 s H'  u  p%U[        R                  R                  ;  d  M%  X%_M)     nnnUR                   Vs/ s H3  nUR                  5       [        R                  R                  ;  d  M1  UPM5     nnUR                   Vs/ s H%  nU[        R                  R                  ;  d  M#  UPM'     n	n[        UR                  UUUUR                  U	5      $ s  snnf s  snnf s  snf s  snf )z‰
Updates the partition signature by removing buffers specified in
V.graph.removed_buffers. See [Note: Removed Graph Partition Arguments]
)rN	  r/  rW   r¤   r�  rƒ	  rO	  Úmaybe_get_namerP	  r:   r…	  rM	  )
ri   rU	  r¼   r­  rN	  rš  rƒ	  r•   rO	  rP	  s
             rj   Ú.clean_removed_buffer_from_partition_signaturesÚ8Scheduler.clean_removed_buffer_from_partition_signatures»  sR  € ð !*× 5Ñ 5× ;Ñ ;Ô =ô
â =‘�Øœ1Ÿ7™7×2Ñ2Ñ2ó ˆDŠLÙ =ð 	ñ 
ð '×9Ñ9×?Ñ?ÔAô
âA‘	�Øœ1Ÿ7™7×2Ñ2Ñ2ó ˆDŠIÙAð 	ñ 
ð "×.Ò.ó
â.�Ø×"Ñ"Ó$¬A¯G©G×,CÑ,CÑC÷ Ù.ð 	ð 
ð "×0Ò0ó
â0�Øœ1Ÿ7™7×2Ñ2Ñ2÷ Ù0ð 	ð 
ô
 'Ø×#Ñ#ØØØØ×$Ñ$Øó
ð 	
ùó)
ùó

ùò

ùò

s/   ž$EÁEÁ,$EÂEÂ+0EÃEÃ5"EÄEc                óÜ  ^ ^^	^
^^^• SSK m	[        5       m/ m/ m[        U5       VVs0 s H  u  p#X2_M	     snnmSUU	UUU 4S jjm
SU
U4S jjnU H8  n[        UR                  R
                  5      TU'   TU   S:X  d  M0  T
" U5        M:     / nSnU[        U5      :  a¬  T(       d  T(       až  T(       a5  T	R                  T5      u  psUR                  U5        U" U5        T(       a  M5  T(       a5  T	R                  T5      u  psUR                  U5        U" U5        T(       a  M5  US-  nU[        U5      :  a  T(       a  M•  T(       a  Mž  U[        U5      :”  a  [        S5      eU$ s  snnf )ad  
Reorder nodes to minimize the number of partitions via a bfs
topological sort. This is the optimal reordering such that the
number of partitions cannot be reduced further. This may be
sub-optimal for other metrics such as peak memory. This does not
change relative orders of two cudagraphable nodes, nor the
relative order of two non_cudagraphable nodes.
r   Nc                óŠ   >• TU    U 4nTR                  U 5      (       a  TR                  TU5        g TR                  TU5        g ry   )r2	  Úheappush)r•   Únode_with_indexÚcudagraphable_nodesÚheapqÚnode_to_indexÚnon_cudagraphable_nodesri   s     €€€€€rj   Úinsert_pending_nodesÚHScheduler.reorder_for_minimizing_partition.<locals>.insert_pending_nodesò  sA   ø€ Ø,¨TÑ2°DÐ9ˆOØ×$Ñ$ T×*Ñ*Ø—‘Ð6¸ÕHà—‘Ð2°OÕDrm   c                ó–   >• U R                   R                   H.  nTU   S:”  d   eTU==   S-  ss'   TU   S:X  d  M&  T" U5        M0     g )Nr   r   )r�  Ú
succ_nodes)r•   Ú	succ_noder•	  Únode_to_indegrees     €€rj   Úupdate_indegreeÚCScheduler.reorder_for_minimizing_partition.<locals>.update_indegreeù  sO   ø€ Ø!Ÿ]™]×5Ô5�	Ø'¨	Ñ2°QÓ6Ð6Ð6Ø  Ó+¨qÑ0Ó+Ø# IÑ.°!Õ3Ù(¨Ö3ò	 6rm   r   z’
                Failed to schedule, while loop ran too long when
                reordering for minimizing the num of partitions
                ©r•   r\   r‹   rs  )	r’	  r(  r4  r²   r�  Ú
pred_nodesÚheappoprË   rë  )ri   r5  rª  r•   r›	  r$  Ú	num_itersrŽ  r‘	  r’	  r•	  rš	  r“	  r”	  s   `       @@@@@@rj   Ú reorder_for_minimizing_partitionÚ*Scheduler.reorder_for_minimizing_partitionß  s_  þ€ ó 	ä9=»ÐØCEÐØGIÐÜ4=¸eÔ4DÔEÒ4D¡y s˜šÑ4DÒEˆ÷	Eó 	E÷	4ð 	4ó ˆDÜ%(¨¯©×)AÑ)AÓ%BÐ˜TÑ"Ø Ñ%¨Õ*Ù$ TÖ*ñ ð
 -/ˆØˆ	Øœ#˜e›*Ó$Þ#Ö':æ)ØŸ-™-Ð(?Ó@‘�Ø—‘ Ô%Ù Ô%÷ *Ð)ö
 &ØŸ-™-Ð(;Ó<‘�Ø—‘ Ô%Ù Ô%÷ &Ð%ð
 ˜‰NˆIð œ#˜e›*Ó$ß#Ð#×':Ð':ð ”s˜5“zÓ!Üðóð ð ˆùó] Fs   ¨E(c           	     óR  • SSK JnJn  [        [        R
                  R                  5       5      nU" UU R                  U R                  [        [        R
                  R                  R                  5       5      U5      u  pVU R                  U5      nU" XvU5      u  p‰X…S-  :  a  U$ U$ )z`
Reorder nodes to minimize the number of partitions if this only slightly
increase peak memory.
r   )Úestimate_peak_memoryÚprepare_planning_inforŠ  )r.  r¤	  r¥	  r   rW   r¤   r/  rX  r)  rò  r  r¡	  )
ri   r5  r¤	  r¥	  r�  Údefault_peak_memoryrÇ  Úreordered_nodesÚreorder_peak_memoryrŽ  s
             rj   r9  Ú0Scheduler.maybe_reorder_for_minimizing_partition   s�   € ÷ 	Hä"¤1§7¡7×#;Ñ#;Ó#=Ó>ˆá:OØØ×ÑØ×#Ñ#Ü”q—w‘w×+Ñ+×0Ñ0Ó2Ó3Øó;
Ñ7Ðð ×?Ñ?ÀÓFˆÙ!5Ø¸ó"
ÑÐð
 °sÑ!:Ó:Ø"Ð"àˆrm   c                ó4  • / n/ n/ nSS jnU H�  nU R                  U5      SLnU(       a,  [        UR                  5      S:X  a  UR                  U5        MI  U(       a   U" U5      (       a  UR                  U5        Mp  UR                  U5        Mƒ     X#-   U-   $ )zë
Reorder a node if it should be partitioned and has simple dependency:
1. move a partitioned node to the front if it has no dependency
2. move a partitioned node to the back if it is only used by OutputNode
3. otherwise do not reorder
c                óœ   • U R                  5        H8  nUR                   H%  n[        UR                  [        5      (       a  M$      g   M:     gr_  )r—  r-  r’   r•   r`  )r•   rÄ   ra  s      rj   Úonly_output_userÚPScheduler.reorder_for_partition_with_simple_dependency.<locals>.only_output_userM  s<   € Ø×'Ñ'Ö)�ØŸ9œ9�CÜ% c§h¡h´
×;Ó;Ú$ó %ñ *ð rm   Nr   r  )r2	  r²   rŒ  rË   )ri   r5  ÚfrontÚmiddleÚbackr¬	  r•   r2	  s           rj   r:  Ú6Scheduler.reorder_for_partition_with_simple_dependency?  s�   € ð *,ˆØ*,ˆØ(*ˆô	ó ˆDØ#×4Ñ4°TÓ:À$ÐFÐÞ¤C¨×(?Ñ(?Ó$@ÀAÓ$EØ—‘˜TÖ"Þ!Ñ&6°t×&<Ñ&<Ø—‘˜DÖ!à—‘˜dÖ#ñ ð ‰~ Ñ$Ð$rm   c                óž  • / nSn/ n/ nU R                    HY  nU R                  U5      SLnU(       a)  X&:w  a$  UR                  U5        UR                  U5        / nUnUR                  U5        M[     U(       a"  UR                  U5        UR                  U5        U R                  XS9nU R	                  U5        U R                  X5        X4$ )zz
Given a list of BaseSchedulerNodes, split into a list of
graph partitions and compute partition input/output signatures.
TN)r|	  r}	  )r5  r2	  rË   r‡	  rX	  Ú_log_graph_partitions)ri   r|	  rM	  Úcur_partitionr}	  r•   Únode_should_partitionrQ	  s           rj   r7  ÚScheduler.graph_partition_  sØ   € ð +-ˆ
ØˆØ')ˆØˆØ—J”JˆDØ$(×$9Ñ$9¸$Ó$?ÀtÐ$KÐ!Þ Ó!HØ×!Ñ! -Ô0Ø×&Ñ& ~Ô6Ø "�à2ˆNØ× Ñ  Ö&ñ ö Ø×Ñ˜mÔ,Ø×"Ñ" >Ô2à×7Ñ7Ø!ð 8ð 
ˆ
ð 	×)Ñ)¨*Ô5à×"Ñ" :Ô:àÐ%Ð%rm   c                óŽ  • [         R                  [        R                  5      (       d  g [	        S [
        R                  R                   5       5      nU(       d  g [        S U 5       5      n[        U5      U-
  n[         R                  S[        U5      UU5        [        [        X5      5       H‘  u  nu  px[         R                  SU[        U5      UR                  (       a  SOS[        UR                  5      [        UR                  5      5        UR                  (       d  Mw  U H  n	U R!                  U	5        M     M“     g )Nc              3  ó8   #   • U  H  n[        U5      v •  M     g 7fry   )rR   )r˜   r[  s     rj   rš   Ú2Scheduler._log_graph_partitions.<locals>.<genexpr>‹  s   é € ÐOÒ:N°œV FŸ^˜^Ò:NùrÚ  c              3  óJ   #   • U  H  oR                   (       a  M  S v •  M     g7f)r   N)rM	  rb	  s     rj   rš   r¹	  �  s   é € Ð!PªZ¨×?OÕ?O§!¡!ªZùs   ‚#š	#zCCreated %d graph partitions: %d cudagraphable, %d non-cudagraphablez3  Partition %d: %d nodes, %s, inputs=%d, outputs=%dznon-cudagraphableÚcudagraphable)Úcudagraphs_logrZ  r[  rh  rö   rW   r¤   Údevice_typesré   r²   r„  r4  r)  rM	  rN	  rO	  Ú_log_non_cudagraphable_node)
ri   r|	  rQ	  Úhas_gpu_deviceÚcudagraphable_countÚnon_cudagraphable_countr1  rl	  rU	  r•   s
             rj   r³	  ÚScheduler._log_graph_partitions�  s  € ô
 ×*Ñ*¬7¯=©=×9Ñ9Øô ÑO¼!¿'¹'×:NÒ:NÓOÓOˆÞØä!Ñ!P©ZÓ!PÓPÐÜ"% j£/Ð4GÑ"GÐÜ×ÑØQÜ�
‹OØØ#ô		
ô *3´3°zÓ3NÖ)OÑ%ˆAÑ%�	Ü× Ñ ØEØÜ�I“Ø'0×'?×'?Ñ#À_Ü�I×)Ñ)Ó*Ü�I×*Ñ*Ó+ôð ×'×'Ñ'ã%�DØ×4Ñ4°TÖ:ó &ò *Prm   c                óÀ  • U R                  U5      nU(       d  gUR                  5       nUR                  b  UR                  R                  5       OSnSU 3/n[	        UR                  5      R
                  nUR                  SU 35        UbF  UR                   SSR                  S UR                   5       5       S3nUR                  SU 35        [        R                  S	USR                  U5      5        Uba  UR                  R                  S
S5      nU(       a=  UR                  5       R                  S5       H  n	[        R                  SU	5        M     ggg)z)Log details for a non-cudagraphable node.Nzreason=zir=r¢  r¼  c              3  ó8   #   • U  H  n[        U5      v •  M     g 7fry   )r  )r˜   rU  s     rj   rš   Ú8Scheduler._log_non_cudagraphable_node.<locals>.<genexpr>±  s   é € Ð2PÂ<¸a´3°q·6°6Â<ùrÚ  rœ  zfx=z
    %s: %sr   r¥  z         %s)r2	  r0  r•   rú  rÀ   r{   rË   r¨  r  rL  r¼	  r„  r©  rñ  ÚstripÚsplit)
ri   r•   r~  r  rý  ÚpartsÚir_typeÚfx_strr   Úlines
             rj   r¾	  Ú%Scheduler._log_non_cudagraphable_node¥  s,  € à×&Ñ& tÓ,ˆÞØà—M‘M“Oˆ	Ø15·±Ñ1F�$—)‘)×+Ñ+Ô-ÈDˆØ˜6˜(Ð#Ð$ˆÜ�t—y‘y“/×*Ñ*ˆØ�‰�s˜7˜)�_Ô%ØÑØŸ™Ð' q¨¯©Ñ2PÀ7Ç<Â<Ó2PÓ)PÐ(QÐQRÐSˆFØ�L‰L˜3˜v˜h˜Ô(ä×Ñ˜\¨9°d·i±iÀÓ6FÔGð ÑØ!Ÿ,™,×*Ñ*¨=¸$Ó?ˆKÞØ'×-Ñ-Ó/×5Ñ5°dÖ;�DÜ"×(Ñ(¨¸Ö=ò <ð ð rm   c                óø   • [        S5         [        R                  R                  R                  (       a  U R                  5       OU R                  U R                  5       sS S S 5        $ ! , (       d  f       g = f)NzScheduler.codegen)r   r¿  rÀ  r&   r7  Ú_codegen_partitionsÚ_codegenr5  rh   s    rj   r‹  ÚScheduler.codegen½  sO   € ÜÐ-Õ.ô —?‘?×)Ñ)×9×9ð ×(Ñ(Ô*à—]‘] 4§:¡:Ó.ð÷ /×.×.ús   ŒAA+Á+
A9c                ól  • SSK Jn  [        R                  R                  n[        U R                  5      n[        R                  R                  5          [        R                  R                  SSU 3UUS9  U R                  U5        [        [        R                  R                  U5      (       d   eU R                  U5      nU[        R                  R                  l        [        R                  R                  R                  5         [        R                  R                  n[        R                  R                  R                  [        R                  R                   5      u  pxSSS5        [        R                  R                  R#                  WW5        [        R                  R                  R%                  XR5        [        R                  R                  R&                  R)                  UR*                   V	s/ s H  o™R-                  5       PM     sn	5        g! , (       d  f       N½= fs  sn	f )z,Codegen a partition given its inputs/outputsr   )ÚSubgraphPythonWrapperCodegenTÚ
partition_)Úis_subgraphÚsubgraph_nameÚparent_wrapper_codeÚpartition_signaturesN)r‡  rÒ	  rW   r¤   rR  r3  r  Úset_current_wrapper_codeÚinit_wrapper_coderÏ	  r’   r‹	  r×	  Úwrite_prefixr¼   ÚgenerateÚis_inferenceÚdefine_subgraph_launcher_fnÚcodegen_partition_callÚ	allocatedr¨  rO	  r0  )
ri   rl	  rU	  rÒ	  rÖ	  Úgraph_partition_idÚ
graph_nameÚpartition_coderŽ  r•   s
             rj   Ú_codegen_partition_wrapperÚ$Scheduler._codegen_partition_wrapperÅ  sƒ  € õ 	BäŸg™g×2Ñ2ÐÜ! $×"?Ñ"?Ó@Ðä�W‰W×-Ñ-Õ/Ü�G‰G×%Ñ%Ø Ø *Ð+=Ð*>Ð?Ø$7Ø%.ð	 &ñ ð �M‰M˜)Ô$ô œaŸg™g×2Ñ2Ð4P×QÑQÐQÐQØ×KÑKÈIÓVˆIØ8AŒA�G‰G× Ñ Ô5Ü�G‰G× Ñ ×-Ñ-Ô/äŸ™Ÿ™ˆJÜ !§¡× 4Ñ 4× =Ñ =¼a¿g¹g×>RÑ>RÓ SÑˆN÷/ 0ô2 	
�‰×Ñ×8Ñ8¸À^ÔTä	�‰×Ñ×3Ñ3Ð4FÔRÜ	�‰×Ñ×&Ñ&×-Ñ-Ø)2×)?Ò)?Ó@Ò)? �]‰]Ž_Ñ)?Ñ@õ	
÷9 0Õ/üò: As   ÁDH Ç?H1È 
H.c                óP   ^ ^^• [         R                  SUU U4S jj5       nU" 5       $ )Nc               3  óö  >#   • TR                  T T5        TR                  (       a  [        TR                  R                  5      (       a[  TR                  R                  c   S5       e[
        R                  R                  R                  TR                  R                  5         S v •  TR                  (       aL  [        TR                  R                  5      (       a(  [
        R                  R                  R                  5         S Tl        g ! TR                  (       aL  [        TR                  R                  5      (       a(  [
        R                  R                  R                  5         S Tl        f = f7f)Núdevice should have an index)
Ú%update_graph_partition_default_devicer  rH   rÀ   r½   rW   r¤   rR  Úcodegen_device_guard_enterÚcodegen_device_guard_exit)r|	  ri   rQ	  s   €€€rj   ÚctxÚ1Scheduler.use_default_device_context.<locals>.ctxó  s  øé € à×6Ñ6°zÀ:ÔNØ×*×*Ô/@Ø×+Ñ+×0Ñ0÷0ñ 0ð ×2Ñ2×8Ñ8ÑDð Ø1óÐDô —‘×$Ñ$×?Ñ?Ø×/Ñ/×5Ñ5ôð3Ûà×.×.Ô3DØ×/Ñ/×4Ñ4÷4ñ 4ô —G‘G×(Ñ(×BÑBÔDØ.2�Õ+øð	 ×.×.Ô3DØ×/Ñ/×4Ñ4÷4ñ 4ô —G‘G×(Ñ(×BÑBÔDØ.2�Õ+üs    ƒB#E9Â'D Â+A%E9ÄA&E6Å6E9)r‹   zIterator[None])Ú
contextlibÚcontextmanager)ri   r|	  rQ	  rë	  s   ``` rj   Úuse_default_device_contextÚ$Scheduler.use_default_device_contextð  s+   ú€ ô 
×	"Ñ	"÷	3ð 	3ó 
#ð	3ñ* ‹uˆrm   c                óN  • [        U5      S:X  a  US   R                  (       d  g SS jn      SS jnS n[        X5       H   u  pgUR                  (       a  M  U" U5      n  O   Uc  g [        X5       H'  u  pgUR                  (       d  M  U" Xe5      (       a  M'    g    XPl        g )Nr   r   c                ó6   • U S   R                  5       nUc   eU$ rÑ   ©rî   )rl	  Úpartition_devices     rj   Úget_cudagraph_partition_deviceÚWScheduler.update_graph_partition_default_device.<locals>.get_cudagraph_partition_device  s'   € Ø(¨™|×6Ñ6Ó8ÐØ#Ñ/Ð/Ð/Ø#Ð#rm   c                óD   • U  H  nUR                  5       nX1:w  d  M    g   gr_  ró	  )rl	  Útarget_devicer•   r[  s       rj   Úall_on_target_deviceÚMScheduler.update_graph_partition_default_device.<locals>.all_on_target_device  s(   € ó "�ØŸ™Ó*�ØÕ*Ù ñ "ð rm   )rl	  r]   r‹   rà  )rl	  r]   rø	  rà  r‹   rx   )r²   rM	  r)  r  )ri   r|	  rQ	  rõ	  rù	  Úcudagraph_partition_devicerl	  rU	  s           rj   rè	  Ú/Scheduler.update_graph_partition_default_device  sÀ   € ô ˆz‹?˜aÓ¨
°1©×(D×(Dð ô	$ð
	Ø$ð	Ø5Að	àô	ð &*Ð"Ü$'¨
Ö$?Ñ ˆIØ×+×+Ñ+Ù-KÈIÓ-VÐ*Ùñ %@ð &Ñ-Øä$'¨
Ö$?Ñ ˆIØ×'×'Ñ'Ñ0DØ÷1ó 1ñ ñ	 %@ð 'AÕ#rm   c                ó  • U R                  5       u  p[        U5      S:”  a  [        S   S==   [        U5      -  ss'   U R                  X5         [	        X5       H\  u  p4[        U5      S:¼  d   S[        U5       35       eUR
                  (       a  U R                  U5        MK  U R                  X45        M^     SSS5        [        U R                  5      n[        R                  R                  R                  U5        US:”  as  [        R                  R                  c   eU[        [        R                  R                  5      :X  d.   SU S[        [        R                  R                  5       35       egg! , (       d  f       NÆ= f)	zª
Split nodes into partitions and codegen each partition into separate functions.
This allows further applying different optimizations (e.g., cudagraph) to
each function.
r   rø  Úcudagraph_partitionsz5Each partition must have at least one node but found Nr   zExpect z partition maps but got )r7  r²   r   rï	  r)  rM	  rÏ	  rã	  r3  r  rW   r¤   rR  Úset_all_partition_namesrL	  )ri   r|	  rQ	  rl	  rU	  Únum_partitionss         rj   rÎ	  ÚScheduler._codegen_partitions:  sO  € ð "&×!5Ñ!5Ó!7Ñˆ
äˆz‹?˜QÓÜ�ZÑ Ð!7Ó8¼CÀ
»OÑKÓ8à×,Ñ,¨ZÕDÜ(+¨JÖ(CÑ$�	Ü˜9“~¨Ó*ð ØKÌCÐPYËNÐK[Ð\óÐ*ð ×+×+Ø—M‘M )Ö,à×3Ñ3°IÖIñ )D÷ Eô ˜d×;Ñ;Ó<ˆÜ	�‰×Ñ×4Ñ4°^ÔDð ˜AÓÜ—7‘7×)Ñ)Ñ5Ð5Ð5Ø!¤S¬¯©×)?Ñ)?Ó%@Ó@ð Ø˜.Ð)Ð)AÄ#ÄaÇgÁg×F\ÑF\ÓB]ÐA^Ð_óÑ@ð ÷ EÕDús   ÁA,E<Å<
F
c                óÐ  • [         R                  (       aÅ  SS Kn[        R                  " 5       n[        5       n[        U5       H“  nUR                  S:X  a0  UR                  UR                  R                  R                  :X  a    OTUR                  UR                  4nXd;  d"   SUR                   SUR                   S35       eUR                  U5        M•     U R                  U l        U R                   b   eU R                  (       aG  [         R"                  R$                  (       a(  [&        R(                  R*                  R-                  5         U GHÌ  n[.        R1                  [2        R4                  5      (       a4   [.        R7                  SUR9                  5       UR;                  5       5        U R?                  U5        URA                  5       =n(       Ga  X€R                  :w  d*  URC                  5       (       d  URE                  5       (       a  U RG                  5         X€R                  :w  aÄ  U R                  (       aL  [I        U R                  RJ                  5      (       a(  [&        R(                  R*                  RM                  5         X€l        [I        URJ                  5      (       aG  URN                  c   S5       e[&        R(                  R*                  RQ                  URN                  5        Xpl)        U RT                  RW                  URX                  5        URE                  5       (       aN  UR[                  []        UR_                  5       5      5      u  pšnU Ra                  U5      Rc                  X«U	5        GOhURC                  5       (       a.  [d        Rf                  " [h        U5      nU Rk                  U5        GO%URm                  5       (       aw  [d        Rf                  " [n        U5      nU Ra                  U5      nS	S
K8J9n  S	SK:J;n  [y        XÎU45      (       a  UnO[{        S[K        U 5      < 35      eUR}                  U5        O™[y        U[~        5      (       a!  U Ra                  U5      R�                  U5        Oc[y        U[‚        [„        45      (       a!  U Ra                  U5      R‡                  U5        O'[y        U[ˆ        5      (       d   eUR‹                  5         [         R"                  RŒ                  (       a  U Ra                  U5      R�                  5         U R�                  RW                  UR“                  5       5        U R”                  RW                  UR—                  5       5        [y        U[ˆ        5      (       dW  URA                  5       nUbD  URJ                  S:w  a4  U Ra                  U5      R™                  5       (       a  U RG                  5         [›        S UR_                  5        5       5      (       a	  Xpl        GMÅ  S U l        GMÏ     U R                  U R                  :w  a[  U R                  c   e[I        U R                  RJ                  5      (       a(  [&        R(                  R*                  RM                  5         S U l        U RG                  5         g ! [<         a(    [.        R7                  SUR9                  5       5         GN/f = f)Nr   Ú_compile_innerzDuplicate stack frame Ú:zs; did you add a decorator to one of the functions in this stack trace?  If so, try using a context manager instead.z5Generating code for node %s with estimated runtime %fz6Generating code for node %s with estimated runtime 0.0rç	  r   )ÚCUDACombinedSchedulingrÙ  ztype(self)=r©  c              3  óB   #   • U  H  n[        U[        5      v •  M     g 7fry   )r’   r“   rC  s     rj   rš   Ú%Scheduler._codegen.<locals>.<genexpr>Ì  s   é € ÐJÒ9I°A”:˜a¤×/Ð/Ò9Iùrt  )Nr&   Ú"check_stack_no_cycles_TESTING_ONLYÚtorch._dynamo.convert_frameÚ	tracebackÚextract_stackr   r´   r¼   ÚfilenameÚ_dynamoÚconvert_frameÚ__file__Úlinenor  r  rN  r  rá   Úautotune_at_compile_timerW   r¤   rR  Úwrite_get_raw_stream_headerr°  rZ  r[  rh  r„  r0  r  r¯  r$	  rî   rm  rj  r
	  rH   rÀ   rê	  r½   ré	  r  rA  r¨  r~  r:  r  r�   rÌ  Úcodegen_templater÷  rø  rë  r	  rp  r	  Ú codegen.cuda_combined_schedulingr
  rÝ  rÚ  r’   r  Úcodegen_combo_kernelrâ  Úcodegen_mix_order_reductionr¿   r“   Úcodegen_noder‘  rü  Údebug_sync_kernelÚcodegen_syncr  r=  rŽ  rð   Úready_to_flushrœ   )ri   r5  r¿  Ústackrá  Úframer�  r•   r[  r7  r8  r9  Úbackend_r
  rÚ  r  s                   rj   rÏ	  ÚScheduler._codegenZ  s  € Ü×4×4Û.ä×+Ò+Ó-ˆEÜ7A³|ˆDÜ! %ž�ð —J‘JÐ"2Ó2ØŸ™¨%¯-©-×*EÑ*E×*NÑ*NÓNáØ—~‘~ u§|¡|Ð4�Ø“ð Ø,¨U¯^©^Ð,<¸A¸e¿l¹l¸^ð LJð Jó�ð
 —‘˜–ñ )ð #×9Ñ9ˆÔØ×!Ñ!Ñ)Ð)Ð)ð ×&×&¬6¯=©=×+Q×+QÜ�G‰G× Ñ ×<Ñ<Ô>äˆDÜ×Ñ¤§¡×.Ñ.ð
Ü—I‘IØOØŸ™›Ø×2Ñ2Ó4ôð ×Ñ˜tÔ$àŸ™Ó*Ð*ˆvÖ*à×1Ñ1Ó1Ø—~‘~×'Ñ'Ø×'Ñ'×)Ñ)à—J‘J”LØ×0Ñ0Ó0Ø×*×*Ô/@Ø×+Ñ+×0Ñ0÷0ñ 0ô Ÿ™×,Ñ,×FÑFÔHØ*0Ô'Ü(¨¯©×5Ñ5Ø%Ÿ|™|Ñ7ÐVÐ9VÓVÐ7ÜŸ™×,Ñ,×GÑGÈÏÉÔUà $ÔØ×%Ñ%×,Ñ,¨T¯_©_Ô=à×Ñ×!Ñ!Ø48×4WÑ4WÜ˜Ÿ™Ó)Ó*ó5Ñ1�¨ð × Ñ  Ó(×9Ñ9Ø!¨Xöð —‘×!Ñ!Ü—{’{Ô#<¸dÓC�Ø×(Ñ(¨Ö.Ø—‘×"Ñ"Ü—{’{Ô#=¸tÓD�à×+Ñ+¨FÓ3�ÝTÝ8ä˜hÐ9OÐ(P×QÑQØ&‘Gä(¨K¬D°«J©=Ð)9Ó:Ð:Ø×,Ñ,¨TÕ2Ü˜DÔ"9×:Ñ:à× Ñ  Ó(×DÑDÀTÕJÜ˜DÔ#5´}Ð"E×FÑFà× Ñ  Ó(×5Ñ5°dÕ;ä! $Ô(>×?Ñ?Ð?Ð?Ø—‘”ô �}‰}×.×.à× Ñ  Ó(×5Ñ5Ô7à×'Ñ'×.Ñ.¨t×/DÑ/DÓ/FÔGØ×%Ñ%×,Ñ,¨T×-EÑ-EÓ-GÔHä˜dÔ$:×;Ñ;ØŸ™Ó*�àÑ&ØŸ™ vÓ-Ø×(Ñ(¨Ó0×?Ñ?×AÑAà—J‘J”LäÑJ¸¿¹Ô9IÓJ×JÑJØ%)×"à%)�×"ñs ðv ×Ñ $×"=Ñ"=Ó=ð ×&Ñ&Ñ2Ð2Ð2Ü  ×!4Ñ!4×!9Ñ!9×:Ñ:ô —‘×$Ñ$×>Ñ>Ô@à!ˆÔØ�
‰
�øô} !ó Ü—I‘IØPØŸ™›÷ðús   Æ3Z3Ú3.[%Û$[%c                ó¬   • US   R                  5       nU [        R                  l        X0l        Uc   eU R                  U5      nUR                  X5      $ )r  r   )rî   rW   r¤   r(  rN  rÌ  Úbenchmark_combo_kernel)ri   rP  Únode_benchmark_resultsr[  r  s        rj   r 
  Ú Scheduler.benchmark_combo_kernelÞ  sU   € ð ˜1‘×(Ñ(Ó*ˆØ Œ�‰ÔØ$ÔØÑ!Ð!Ð!Ø×"Ñ" 6Ó*ˆØ×-Ñ-¨iÓPÐPrm   c                ó\  ^• UnUS   R                  5       m[        U4S jU 5       5      (       d   S5       e[        R                  (       d  gSSKJn  S/ pT0 n[        U5       H¢  u  pxUR                  5       n	U R                  U	5      (       a  [        R                  S5         U R                  U	5      u  p«X«4Xh'   [        R                  " U
5      (       a  [        R                  SU5          g	 XJ-  nUR                  U5        M¤      U R                  X&5      u  pÞnXÞ-
  S:  =(       d    US:  n[        R!                  ["        R$                  5      (       aS  XM:”  d  U(       a$  [        R                  S['        XM-  S 5      5        O#[        R                  S[)        XM-  S 5      5        XÞ-
  U:  =(       d    U$ ! U a0  nS
[        U5      ;   a  [        R                  S5         SnA  ge SnAff = f! U a/  nS
[        U5      ;   a  [        R                  S5         SnAge SnAff = f)ra  r   c              3  óH   >#   • U  H  oR                  5       T:H  v •  M     g 7fry   ró	  )r˜   r•   r[  s     €rj   rš   Ú4Scheduler.speedup_by_combo_kernel.<locals>.<genexpr>õ  s   øé € ÐKº?°4—?‘?Ó$¨Ö.º?ùrñ  z<All nodes in a combo kernel group must be on the same deviceTrd  g        z<ComboKernel: benchmarking may not accurate due to atomic_addz;ComboKernel benchmark: register spilling of %d-th subkernelFr›  zCComboKernel benchmark: return True because of loop-carried variableNg333333Ó?z/can fuse (benchmark): fusing causes %sx speeduprg  z3cannot fuse (benchmark): fusing causes %sx slowdown)rî   rœ   r&   r 
  r¤  re  r4  r�   rQ  rƒ  r„  r	  r�  rž  r  rË   rZ  r[  rh  rB   rC   )ri   r5  Úsubkernel_nodesre  rj  Ú
path1_listr!
  r1  r\  rP  r  rƒ  r  rk  Ú	ms2_cloneÚ_path2_listÚsmall_kernelr[  s                    @rj   rñ  Ú!Scheduler.speedup_by_combo_kernelì  s  ø€ ð  ˆØ  Ñ#×.Ñ.Ó0ˆäÔK¹?ÓK×KÑKð 	
ØJó	
ÐKô ×,×,Øå;à˜rˆZØ!#ÐÜ! /Ö2‰HˆAØŸ™Ó)ˆIð ×#Ñ# I×.Ñ.Ü× Ñ ØRôðØ×5Ñ5°iÓ@‘�Ø13°
Ð&Ñ-Ü—:’:˜b—>‘>Ü×$Ñ$ØUØôñ !ð "ð ‰IˆCØ×Ñ˜dÖ#ñ9 3ð<	Ø*.×*EÑ*EØó+Ñ'ˆC˜Kð ‘¨Ñ,×9°°c±	ˆÜ×"Ñ"¤7§=¡=×1Ñ1Ø‹yžLÜ× Ñ ØEÜ #¡)¨C Ó2õô
 × Ñ ØIÜ ¡	¨#˜Ó0ôð
 ‰ Ñ$×4¨Ð4øðQ $ó à*¬c°!«fÓ4Ü×$Ñ$Ø]ôõ  àûðûð   ó 	à&¬#¨a«&Ó0Ü× Ñ ØYôô àûð	ús=   Â%A	F=ÄG6 Æ=G3Ç$G.Ç-G.Ç.G3Ç6H+Ç<$H&È%H&È&H+c                ór   • U R                   U   nUR                  c   eUR                  R                  5       $ ry   )rX  r•   Ú
get_layout)ri   rR  rÄ   s      rj   Úget_buffer_layoutÚScheduler.get_buffer_layout<  s5   € Ø×Ñ˜xÑ(ˆØ�x‰xÑ#Ð#Ð#Ø�x‰x×"Ñ"Ó$Ð$rm   c                ó  • U R                    Hô  nUR                  5       (       d  M  UR                  R                   HÀ  n[        R
                  R                  R                  UR                  5      nU(       d  M?  [        U5      S:X  d  MP  [        UR                  [        [        45      (       a  Mw  UR                  5       / :X  d  M�  [        R
                  R                  R!                  UR                  5        MÂ     Mö     g rX  )r5  rR   rº   r»   rW   r¤   r  rñ  r¼   r9   r’   r=  r=   r<   rÃ  Úzero_dim_cpu_tensor_listr  )ri   r•   r—  r­  s       rj   r  Ú$Scheduler.update_zero_dim_cpu_tensorA  sª   € Ø—J”JˆDØ�{‰{�}‹}Ø ×,Ñ,×2Ô2�DÜŸW™W×3Ñ3×7Ñ7¸¿	¹	ÓB�Fç˜Ü+¨FÓ3°uÕ<Ü *Ø"ŸM™M¬JÔ8IÐ+J÷!ó !ð #ŸO™OÓ-°Õ3äŸ™×8Ñ8×<Ñ<¸T¿Y¹YÖGó 3ò rm   )r  r  r  rA  rŽ  rN  r  r  r!  ró  rƒ  rX  rW  r)  r  r5  r  rB  r
  r  rD  r  )r5  zlist[ir.Operation]r‹   rs  )r‹   z!dict[str, SchedulerDonatedBuffer]rv  )r[  rw  r‹   rs  rr  )r]  r  r‹   rs  )r•   r<  r‹   r\   )rL  úOptional[str]r‹   rx   ri  )r\  r\   r‹   rI  )r‹   rj  ©r5  rê  r‹   útuple[float, str]ry   ©r5  rê  r  rx   r  úOptional[int]r‹   r  )r  r   r[  rà  r‹   r5
  )r  úir.MultiTemplateBufferr‹   rx   )
r?  úir.OperationBufferr  r8
  r1  r!  r•   r“   r‹   rs  )rP  rê  r‹   rx   )r5  rê  r  r7
  r‹   z)tuple[Optional[LambdaFuture], ModuleType])r…   r\   r†   r\   r‹   ra   )r•   r\   r‹   r\   )r…   r\   r†   r\   r(  úOrderedSet[BaseSchedulerNode]r‹   r\   )r…   r\   r†   r\   r¾  rz   r(  r:
  )rÂ  ú,dict[BaseSchedulerNode, list[PendingFusion]]r(  r:
  r‹   rs  )
rÔ  ú1list[tuple[BaseSchedulerNode, BaseSchedulerNode]]rÑ  ú&dict[BaseSchedulerNode, PendingFusion]rÕ  r;
  r(  r:
  rÿ  rx   )r(  r:
  rÑ  r=
  )rà  r<
  rá  r<
  )r5  rI  rÿ  rx   r‹   rI  )r÷  r7
  r‹   rs  rþ  )r5  rI  rÿ  rx   r‹   r<
  r  )r…   r\   r†   r\   r8  r!  r‹   rx   )r…   r\   r†   r\   rN  z'Union[tuple[str, ...], OrderedSet[str]]r‹   r  r"  r  )r•  r\   r8  r\   r  r{  r‹   rx   )r…   r\   r†   r\   r‹   z/Optional[tuple[int, SchedulerNode, sympy.Expr]])FT)
r…   r\   r†   r\   r¾  rx   rè  rx   r‹   rx   )rÚ  r4   r…   r\   r†   r\   r‹   rx   )r—  r1   rs  r2   r‹   rx   rE  )rÆ   r1   rõ  rx   r‹   r!  )TFT)r…   r\   r†   r\   rõ  rx   rë  rx   rè  rx   r‹   zint | tuple[int, bool])rà  r<
  r‹   r<
  )r5  rŒ   r‹   r   )r	  rë  r‹   rs  )r[  rà  r‹   ÚBaseScheduling)r[  rw  r‹   r>
  r�	  )r¼   r  r9  r}  r‹   rx   )r•   r\   r‹   r3
  )r‹   rj	  )r‹   ú;dict[str, Union[ir.IRNode, ir.TorchBindObject, sympy.Expr]])rQ	  úlist[GraphPartitionSignature]r‹   rs  )rl	  r]   rN	  r?
  r‹   rj	  )r|	  úlist[PartitionType]r}	  z
list[bool]r‹   r@
  )rU	  r:   r‹   r:   )r‹   z9tuple[list[PartitionType], list[GraphPartitionSignature]])r|	  rA
  rQ	  r@
  r‹   rs  )rl	  r]   rU	  r:   r‹   rs  )r|	  rA
  rQ	  r@
  r‹   z'contextlib.AbstractContextManager[None]©rP  rê  r‹   z(tuple[float, float, list[Optional[str]]])r5  rI  r‹   rx   )rR  r  r‹   z	ir.Layout)cr{   r|   r}   r~   r#  r”  rí  r  ÚpropertyrN  Úsetterr@  r^  r  r   rZ   r>  r  rÚ  r  rî  rC  r  r  rw  r6  r	  r  r  r!  r&  r6  rQ  r^  r³  r�  r¹  r¿  rÊ  rØ  rÝ  ræ  r   r-  r*  rë  r½  r-  rC  rH  rW  r{  r…  rÿ  r™  r°  rþ   r¼  r¡  rÎ  r�  rù  r  r  r;  r	  r
	  r	  r	  rÌ  r$	  r7  r2	  rF   r@	  r5	  rI	  rX	  ro	  r‡	  r‹	  r¡	  r9  r:  r7  r³	  r¾	  r‹  rã	  rï	  rè	  rÎ	  rÏ	  r 
  rñ  r.
  r  r�   rº  r»  s   @rj   r'  r'  :  sX  ø† ñô
÷U9ôn	#ð ó&ó ð&ð ×Ñó(ó ð(ô7ô#ô,ô"ôHMPô^KôZ+#ôZ ðØ,ðà	 ôô6Sô*ô4#ô&$ô6!ôF	ð8Ø0ð8à	ô8ð, (,ð	à*ðð ðð %ð	ð
 
õð&
>Ø ð
>Ø*6ð
>à	ô
>ð$Ø0ð$à	ô$ôLVDðp'8à&ð'8ð +ð'8ð ð	'8ð
 ð'8ð 
ô'8ôR
ð RVðØ0ðØANðà	2õð uØ&ðuØ/@ðuà	ôuôn>ðà ðð !ðð 3ð	ð
 
ôð"à ðð !ðð 'ð	ð
 3ôð"D2à$PðD2ð 3ðD2ð 
ô	D2ðLO?àPðO?ð @ðO?ð  Lð	O?ð
 3ðO?ð ôO?ðbSà2ðSð @ôSð00àKð0ð $Uô0ð(Eà&ðEð ðEð 
!ô	EöN..ô`?ð6 à&ð6 ð ð6 ð 
;ô	6 ðp,Ø&ð,Ø/@ð,à	ô,ð\7Ø&ð7Ø/@ð7à	ô7ðr.2Ø&ð.2Ø/@ð.2ØMPð.2à	ô.2ð`$Ø&ð$Ø/@ð$à	ô$ð6<à ð<ð !ð<ð Bð	<ð
 
ô<ð|MØ&ðMØ/@ðMà	ôMð^Y
Ø&ðY
Ø/@ðY
à	ôY
ôv
ð9à(ð9ð )ð9ð ð	9ð
 
ô9ðv`Ø&ð`Ø/@ð`à	8ô`ðL "Ø*.ðuMà ðuMð !ðuMð ð	uMð
 $(ðuMð 
õuMðn3Ø&ð3Ø/@ð3à	ô3ðj-)Øð-)Ø(9ð-)ØBSð-)à	ô-)ôf%öN;ð !Ø.3Ø*.ð3
à ð3
ð !ð3
ð ð	3
ð
 (,ð3
ð $(ð3
ð 
 õ3
ðj6Ø Qð6à	:ô6ð@4Ø@ð4à	ô4ô	8ô*ô4ô
ô'ô*%ô5ð$
Øð
Ø+:ð
à	ô
ô=ð~ ó!ó ð!ðFØ%ðà	ôð"à	Dôð 'à1ð'ð 
ô'ðRBHà ðBHð QðBHð 
"ô	BHðHK Ø-ðK Ø@JðK à	&ôK ðZ"
Ø0ð"
à	 ô"
ðH?à&ð?ð 
!ô?ðBà&ðð 
!ôð>%Ø,ð%à	 ô%ð@ &à	Bô &ðD";à'ð";ð 2ð";ð 
ô	";ôH>ô0ð)
à ð)
ð +ð)
ð 
ô	)
ðVØ-ðØ;Xðà	0ôð6-AØ-ð-AØ;Xð-Aà	ô-Aô^ô@BðHQØ4ðQà	1ôQôN5ô`%÷
Hò Hrm   c                  ór  ^ • \ rS rSrSU 4S jjrSS jrSS jr      SS jr      SS jr      SS jr	      SS jr
    SS	 jr        SS
 jr S       SS jjrS S jrS!S jrSS jrS"S jrSS jr    S#S jrS$S jr      S%S jr    S&S jr S     S'S jjrSrU =r$ )(r>
  iQ  c                ó.   >• [         TU ]  5         Xl        g ry   )r¬  r”  r(  )ri   r(  r¯  s     €rj   r”  ÚBaseScheduling.__init__R  s   ø€ Ü‰ÑÔØ"�rm   c                ó\   • U R                   (       a  U R                   R                  5         g g ry   )r(  r	  rh   s    rj   Úfree_buffers_in_schedulerÚ(BaseScheduling.free_buffers_in_schedulerV  s   € Ø�>�>Ø�N‰N×'Ñ'Õ)ð rm   c                ó   • [        5       $ )z0Return a set of .codegen.common.BackendFeature()r   rZ  s     rj   Úget_backend_featuresÚ#BaseScheduling.get_backend_featuresZ  s
   € ä‹|Ðrm   c                ó   • [         e)z?
Check whether node1 and node2 can be vertically fused or not.
rÍ  r€  s      rj   r¼  Ú BaseScheduling.can_fuse_vertical^  ó
   € ô "Ð!rm   c                ó   • [         e)zA
Check whether node1 and node2 can be horizontally fused or not.
rÍ  r€  s      rj   r½  Ú"BaseScheduling.can_fuse_horizontalf  rP
  rm   c                ó   • g)aE  
A Multi-Output Template (referenced in #144012) is a template node
with MultiOutputLayout, and its output buffers are instances of MultiOutput.
In this context, we verify whether node1 represents the Multi-Output Template
and node2 corresponds to one of its outputs. If so, we further check if
backend supports this fusion.
Frw   r€  s      rj   r·  Ú.BaseScheduling.can_fuse_multi_outputs_templaten  s   € ð rm   c                ó@  • UR                  5       (       d  UR                  5       (       a  [        R                  X5      $ [        R	                  X5      (       a  [        X5      $ [        U[
        5      (       a  UR                  U5      $ [        R                  X5      $ )z
Fuse two nodes
)	rp  r	  rq   rŽ   r  râ  r’   r  r¿   r€  s      rj   rq   ÚBaseScheduling.fusez  s|   € ð ×Ñ×Ñ ×!1Ñ!1×!3Ñ!3Ü-×2Ñ2°5Ó@Ð@Ü×7Ñ7¸×EÑEÜ*¨5Ó8Ð8Ü˜Ô6×7Ñ7Ø—?‘? 5Ó)Ð)ä%×*Ñ*¨5Ó8Ð8rm   c                ó   • [         e)zK
Process the iteration sizes in case a transformation needs to be applied.
rÍ  )ri   rç  s     rj   rÍ  ÚBaseScheduling.group_fn‰  rP
  rm   c                ó   • [         e)zÃ
Given a template node, generate a kernel.

This function is only available for triton now. If the third-party backend behaves as a sub-class
of TritonScheduling, it can override it or reuse it.
rÍ  )ri   r8  Úepilogue_nodesr¶  s       rj   r
  ÚBaseScheduling.codegen_template‘  s
   € ô "Ð!rm   c                ó   • [         e©z4
Generate a kernel given a list of pre-fused nodes.
rÍ  )ri   r5  r  r  s       rj   r  Ú.BaseScheduling.generate_kernel_code_from_nodesŸ  s
   € ô "Ð!rm   c                ó   • [         er]
  rÍ  rÄ  s     rj   r
  ÚBaseScheduling.codegen_nodeª  ó
   € ô "Ð!rm   c                ó   • [         ery   rÍ  rÄ  s     rj   r
  Ú*BaseScheduling.codegen_mix_order_reduction°  rÐ  rm   c                ó   • [         e)zd
Generate synchronization code for the kernel. This method depends on the hardware characteristics.
rÍ  rh   s    rj   r
  ÚBaseScheduling.codegen_sync³  ra
  rm   c                ó   • g)z}
Check whether the backend is requesting the scheduler to flush the generated kernel.
If not supported, please return False.
Frw   rh   s    rj   r
  ÚBaseScheduling.ready_to_flush¹  s   € ð
 rm   c                ó   • [         e)zM
Flush the generated kernel and python wrapper code to the source code file.
rÍ  rh   s    rj   r
	  ÚBaseScheduling.flushÀ  ra
  rm   c                ó   • [         e)r  rÍ  rî  s     rj   r	  Ú$BaseScheduling.benchmark_fused_nodesÆ  ó
   € ô "Ð!rm   c                ó   • [         e)zi
Benchmark a compiled module and return the execution time
in milliseconds on randomly generated inputs.
rÍ  )ri   r  s     rj   r  Ú)BaseScheduling.benchmark_codegened_moduleÏ  s
   € ô
 "Ð!rm   c                ó   • g)zt
Return an unsigned integer which represents the priority of this fusion pair.
The smaller is with higher priority.
r   rw   r€  s      rj   rø  Ú'BaseScheduling.get_fusion_pair_priorityÖ  s   € ð rm   c                ó   • [         e)z‰
Benchmark the list of nodes to combine and return the execution time
and memory copy time in milliseconds on randomly generated inputs.
rÍ  )ri   rP  r!
  s      rj   r 
  Ú%BaseScheduling.benchmark_combo_kernelß  rl
  rm   c                ó„   • U(       a9  SSK Jn  U" UU5      n[        R                  R                  R                  X$5        g g )Nr   )Ú'set_kernel_post_grad_provenance_tracing)r  rt
  rW   r¤   rR  Úwrite_provenance_debug_handle)ri   Únode_schedulerU  rt
  Údebug_handles        rj   Úcodegen_commentÚBaseScheduling.codegen_commentè  s<   € ö
 ÝUáBØØóˆLô �G‰G× Ñ ×>Ñ>Øõð rm   rT  )r(  zOptional[Scheduler]rr  )r[  rà  r‹   zOrderedSet[BackendFeature]r  rÞ  )rç  rZ  r‹   z"tuple[tuple[sympy.Expr, ...], ...])r8  r\   rZ
  rê  r¶  rê  r‹   r3
  ry   r6
  )r•   z(Union[FusedSchedulerNode, SchedulerNode]r‹   rs  )r•   râ  r‹   rs  rt  r4
  )r  r   r‹   r5
  r"  rB
  )rv
  rê  rU  r3
  r‹   rs  )r{   r|   r}   r~   r”  rI
  rL
  r¼  r½  r·  rq   rÍ  r
  r  r
  r
  r
  r
  r
	  r	  r  rø  r 
  rx
  r�   rº  r»  s   @rj   r>
  r>
  Q  s†  ø† ÷#ô*ôð"Ø&ð"Ø/@ð"à	ô"ð"Ø&ð"Ø/@ð"à	ô"ð
Ø&ð
Ø/@ð
à	ô
ð9Ø&ð9Ø/@ð9à	ô9ð"Ø3ð"à	+ô"ð"à(ð"ð 4ð"ð 4ð	"ð
 
ô"ð$ (,ð		"à*ð	"ð ð	"ð %ð		"ð
 
õ	"ô"ô"ô"ôô"ð"Ø0ð"à	ô"ô"ðØ&ðØ/@ðà	ôð"Ø4ð"à	1ô"ð &*ðà2ðð #ðð 
÷	ó rm   r>
  )r‹   z$torch._inductor.codecache.LocalCache)r\  r\   r‹   r  )r\  r\   r‹   zOptional[Callable[[Any], Any]])r\  r\   r‹   rˆ  )r”  r   r‹   r  )r•   r\   r)  rB  rX  r†  r‹   rs  )r_  ú/Union[FusedSchedulerNode, GroupedSchedulerNode]r‹   rs  )r_  rz
  r(  r'  rÁ   rI  r‹   rs  )rw   )r¡  zlist[list[int]]rç  r[  r¨  rX  r‹   z	list[int])r²  r8
  r)  r9
  r‹   rs  rG  rt  )r•   z	ir.IRNoder‹   rj	  )r•   r\   r‹   rj	  )r…   r\   r†   r\   )¸Ú
__future__r   rñ  rí	  rx  r¤  r	  r  r[  r�  r©  rV  r’  r“  r

  r÷  r   r   Úconcurrent.futuresr   r   r   r	   r
   r   r   r   r   Útyping_extensionsr   Útorch.utils._ordered_setr   r)   r   Úcollections.abcr   r   r   Útypesr   rô   r¿  Útorch._inductor.async_compileÚtorch.utils._pytreers  Ú_pytreerZ  Útorch._dynamo.utilsr   r   Ú torch._inductor.autotune_processr   Útorch._inductor.codecacher   r   Útorch._inductor.irr   Útorch._inductor.metricsr   r   Ú%torch.fx.experimental.symbolic_shapesr    Útorch.utils._sympy.symbolr!   r"   r#   Útorch.utils._tritonr$   rµ  r%   r&   r'   r(   r*   Úanalyze_preserves_zero_maskr+   Úcodegen.commonr,   r-   r.   Úcomm_analysisr/   r0   r1   r2   r3   r4   Úexcr5   r6   Úfx_utilsr7   r8   r9   r:   r;   r<   r=   r  r>   r.  r?   r@   Úruntime.hintsrA   Úruntime.runtime_utilsrB   rC   r¥   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   rV   ÚvirtualizedrW   Ú	getLoggerr{   r°  Ú_loggingÚgetArtifactLoggerrƒ  r  r’  r¼	  r  r]   r   r^   r_   Ú	dataclassra   rƒ   rŽ   r&  r{  r\   r  r  r  rg  r  r{  r?  r`  r(  rë  r‘  r“   re  rn  r¿   râ  r	  rm  r«  r¸  rÀ  rÂ  r  r  rÐ  rÖ  rÛ  râ  ræ  rè  rê  r'  r>
  rw   rm   rj   Ú<module>r˜
     s  ðÞ "ã Û Û Û Û Û Û Û Û Û 	Û Û Û Û ß ,ß 3ß S× SÑ SÝ 'å /å ö ß<Ñ<Ý ã ã Û $ß $Ð $ß 6Ý Eß ?Ý 7ß MÝ >ß OÑ OÝ *ç D× DÝ Dß MÑ M÷÷ ;Ó :ß 2Ý $÷÷ õ  ß JÝ (ß 7Ý &÷÷ ÷ ÷ ÷ õ( ð ×Ó˜Ó!€Ø�^Š^×-Ò-¨h¸ÓA€
Ø—N’N×4Ò4°X¸ÓOÐ Ø Ÿ>š>×;Ò;ØÐ$óÐ ð —’×1Ò1°(¸LÓI€àÐ 3Ñ4€ˆyÓ 4ÙˆTƒ]€Ùˆtƒ_€ð ×Ò÷Dð Dó ðDð* ×Ò÷(ð (ó ð(÷Vñ Vðr ×Ò÷h8ð h8ó ðh8ðV ×Òô4˜_ó 4ó ð4÷y1ñ y1ðx ‡‚ó2ó ð2ôô('ô #ðL ×Ó˜TÑ"÷
ð 
ó #ð
ô*÷ñ ð *KØ
ð*Kà4ð*Kð ,ð*Kð 
ô	*KôZWÐ 1ô Wô"5Ð.ô 5ôL*Ð%ô L*ð^
Ø@ðà	ôð$Ø@ðàðð $ðð 
ô	ô,}*Ð*ô }*ô@[GÐ0ô [Gô|w:Ð!3ô w:ôtbÐ,ô bðP #%ð+Ø#ð+àð+ð  ð+ð õ	+ð\0Ø%ð0Ø1Cð0à	ô0ô8
1ð ×Ò÷
ð 
ó ð
ð> %Ÿ?›?Ó,Ð ô4ôð$Ø
ðàôô&VôVôPô@÷T@Hñ T@H÷n@eò erm   