Ë
    g^(hæ² ã                  ó0  — d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlZd dlZd dlZd dlZd dlmZmZ d dlmZmZmZmZmZmZmZ erd dlmZ d dlmZ d dlZd dlZd dlZd dlm Z m!Z! d dl"m#Z#m$Z$ d d	l%m&Z&m'Z' d d
l(m)Z) d dl*m+Z+ d dl,m-Z-m.Z. d dl/m0Z0 ddl1m2Z2m3Z3m4Z4m5Z5m6Z6 ddl7m8Z8 ddl9m:Z:m;Z;m<Z< ddl=m>Z> ddl4m?Z?m@Z@mAZAmBZB ddlCmDZDmEZE ddl5mFZFmGZGmHZHmIZImJZJ ddlKmLZL ddlMmNZNmOZO ddlPmQZQmRZR ddlSmTZT ddlUmVZVmWZWmXZXmYZYmZZZm[Z[m\Z\m]Z]m^Z^m_Z_m`Z`maZambZb ddlcmdZd  ejÊ                  ef«      ZgejÐ                  jÓ                  efd«      ZjejÐ                  jÓ                  efd«      Zkeld   ZmejÜ                   G d„ d «      «       ZoejÜ                   G d!„ d"eo«      «       Zp G d#„ d«      Zq G d$„ d%«      Zrd@d&„Zs G d'„ d(«      Zt	 	 	 	 	 	 	 	 dAd)„Zuejì                  jî                  jð                  ejì                  jî                  jò                  ejì                  jî                  jô                  ejì                  jî                  jö                  ejì                  jî                  jø                  d*œZ} G d+„ d,eq«      Z~ G d-„ d.eq«      Z G d/„ d0eq«      Z€	 	 	 	 dBd1„Z�	 	 	 	 	 	 	 	 dCd3„Z‚ G d4„ d5eq«      Zƒ G d6„ d7eƒ«      Z„ G d8„ d9eq«      Z…	 dD	 	 	 	 	 	 	 dEd:„Z†ejÜ                   G d;„ d<«      «       Z‡ e�j                  «       Z‰ G d=„ d2«      ZŠ G d>„ d?«      Z‹y)Fé    )ÚannotationsN)ÚCounterÚdefaultdict)ÚAnyÚCallableÚGenericÚOptionalÚTYPE_CHECKINGÚTypeVarÚUnion)ÚSequence)Ú
ModuleType)ÚcountersÚdynamo_timed)ÚLambdaFutureÚPyCodeCache)Úget_metric_tableÚis_metric_table_enabled)Úfree_unbacked_symbols©Ú
OrderedSet)Úfree_symbol_is_typeÚSymT)Ú
has_tritoné   )ÚcommsÚconfigÚdependenciesÚirÚmetrics)Úcan_codegen_without_upcasts)ÚBackendFeatureÚget_scheduling_for_deviceÚKernel)Ú estimate_nccl_collective_runtime)ÚDepÚ	MemoryDepÚStarDepÚWeakDep)ÚGPUTooOldForTritonÚTritonMissing)ÚComputedBufferÚget_device_typeÚGraphPartitionSignatureÚMultiOutputÚMultiOutputLayout)ÚLoopBody)ÚMemoryPlanningInfoForBufferÚMemoryPlanningInfoForNode)Ú
green_textÚred_text)ÚSimplifyIndexing)Úcache_on_selfÚcmpÚdevice_need_guardÚget_device_tflopsÚget_dtype_sizeÚget_gpu_dram_gbpsÚIndentedBufferÚis_collectiveÚis_gpuÚis_multi_outputs_templateÚ#is_output_of_multi_outputs_templateÚis_waitÚsympy_product)ÚVÚfusionÚloop_orderingÚBaseSchedulerNodec                  óÔ   — e Zd ZU ded<   ded<   ded<    ej
                  e¬«      Zded	<    ej
                  e¬«      Z	d
ed<   dd„Z
dd„Zdd„Zdd„Zdd„Zdd„Zdd„Zdd„Zdd„Zy)ÚSchedulerBufferÚ	SchedulerÚ	schedulerz	ir.BufferÚnodeúOptional[BaseSchedulerNode]Údefining_op)Údefault_factoryúlist[NodeUser]Úusersr2   Ú
mpi_bufferc                óB   — | j                   }|€J ‚|j                  «       S ©N)rN   Úget_name)ÚselfÚops     úW/var/www/skyplay_api_hub/venv/lib/python3.12/site-packages/torch/_inductor/scheduler.pyÚdefining_op_namez SchedulerBuffer.defining_op_nameX   s#   € Ø×ÑˆØˆ~Ðˆ~Ø�{‰{‹}Ðó    c                ó@   — t        | j                  j                  «      S rT   )ÚhashrL   Úname©rV   s    rX   Ú__hash__zSchedulerBuffer.__hash__]   s   € Ü�D—I‘I—N‘NÓ#Ð#rZ   c                óv  — t        «       }| j                  «       }|j                  |› dt        | j                  «      j
                  › �«       |j                  |› d| j                  j                  › �«       | j                  «       r-|j                  |› dt        | j                  «       «      › �«       | j                  «       r-|j                  |› dt        | j                  «       «      › �«       t        | j                  «      dk  r0|j                  |› d| j                  › �«       |j                  «       S |j                  |› d�«       |j                  d«      5  | j                  D ]  }|j                  |› d�«       Œ 	 d d d «       |j                  d	«       |j                  «       S # 1 sw Y   Œ*xY w)
Nú: z
.layout = z.aliases = z.mutations = r   z	.users = z
.users = [ú,ú])r=   rU   Ú	writelineÚtyperL   Ú__name__ÚlayoutÚget_aliasesÚpformatÚget_mutationsÚlenrQ   ÚindentÚgetrawvalue)rV   Úresultr]   Úusers       rX   Ú	debug_strz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Ó!ñ 1Ø ŸJ™Jò 1�DØ×$Ñ$¨ v¨Q ZÕ0ñ1÷1ð ×Ñ˜SÔ!Ø×!Ñ!Ó#Ð#÷	1ð 1ús   Å&F/Æ/F8c                ó6   — | j                   j                  «       S rT   ©rL   rU   r^   s    rX   rU   zSchedulerBuffer.get_namet   ó   € Ø�y‰y×!Ñ!Ó#Ð#rZ   c                óö  — | j                   €J ‚| j                   j                  «       sy | j                   j                  «       sL| j                   j                  «       s2t	        | j                   j                  «       t        j                  «      r4t        j                  j                  j                  | j                   «       y t        t        j                  d«      ré| j                  «       t        j                  j                  v r¿t        j                  j                  | j                  «          }|| j                   j"                  v r$| j                   j"                  |   j                   }n#| j                   j$                  |   j                   }t        j                  j                  j'                  || j                   «       y t        j                  j                  j                  | j                   «       y )NÚargs)rL   Úshould_allocateÚget_inputs_that_alias_outputÚget_mutation_namesÚ
isinstanceÚget_output_specr   ÚCommBufferLayoutrD   ÚgraphÚwrapper_codeÚcodegen_allocationÚhasattrÚkernelrU   Úinplace_update_buffersrK   Úname_to_donated_bufferÚname_to_bufÚcodegen_inplace_reuse)rV   Úinput_buffer_nameÚinput_buffers      rX   ÚallocatezSchedulerBuffer.allocatew   sV  € Ø�y‰yÐ$Ð$Ð$Ø�y‰y×(Ñ(Ô*Øð �I‰I×2Ñ2Ô4Ø�y‰y×+Ñ+Ô-Ü˜$Ÿ)™)×3Ñ3Ó5´r×7JÑ7JÔKä�G‰G× Ñ ×3Ñ3°D·I±IÔ>Øô ”A—H‘H˜fÔ%Ø—‘“¤1§8¡8×#BÑ#BÑBô !"§¡× ?Ñ ?ÀÇÁÃÑ PÐØ  D§N¡N×$IÑ$IÑIØ#Ÿ~™~×DÑDØ%ñ ç‘$ñ ð  $Ÿ~™~×9Ñ9Ð:KÑL×QÑQ�Ü�G‰G× Ñ ×6Ñ6ØØ—	‘	õô
 �G‰G× Ñ ×3Ñ3°D·I±IÕ>rZ   c                ó  — | j                   €J ‚t        | j                   j                  t        j                  «      st        | j                   «      ry| j                  D ]  }t        |j                   t        «      sŒ y y©NFT)rL   ry   rg   r   Ú
NoneLayoutr@   rQ   Ú
OutputNode)rV   Úuses     rX   Úcan_freezSchedulerBuffer.can_free˜   sg   € à�y‰yÐ$Ð$Ð$Ü�d—i‘i×&Ñ&¬¯©Ô6Ô:SØ�I‰Iô;
ð Ø—:‘:ò 	ˆCÜ˜#Ÿ(™(¤JÕ/Ùð	ð rZ   c                ó,  — i }|D ]o  }t        |j                  «      |v r>|j                  |t        |j                  «         «      |t        |j                  «      <   ŒX||t        |j                  «      <   Œq t        |j	                  «       «      | _        y rT   )ÚidrL   ÚmergeÚlistÚvaluesrQ   )rV   rQ   rn   rŒ   s       rX   Ú	set_userszSchedulerBuffer.set_users¤   st   € à&(ˆØò 	+ˆCÜ�#—(‘(‹|˜vÑ%Ø'*§y¡y°¼¸3¿8¹8»Ñ1EÓ'F�”r˜#Ÿ(™(“|Ò$à'*�”r˜#Ÿ(™(“|Ò$ð		+ô
 ˜&Ÿ-™-›/Ó*ˆ�
rZ   c                óR   — | j                   €J ‚| j                   j                  «       S rT   )rL   rw   r^   s    rX   rh   zSchedulerBuffer.get_aliases®   s%   € Ø�y‰yÐ$Ð$Ð$Ø�y‰y×5Ñ5Ó7Ð7rZ   c                óR   — | j                   €J ‚| j                   j                  «       S rT   )rL   rx   r^   s    rX   rj   zSchedulerBuffer.get_mutations²   ó%   € Ø�y‰yÐ$Ð$Ð$Ø�y‰y×+Ñ+Ó-Ð-rZ   N©ÚreturnÚstr©r˜   Úint©r˜   ÚNone©r˜   Úbool)rQ   rP   r˜   r�   ©r˜   zSequence[str])rf   Ú
__module__Ú__qualname__Ú__annotations__ÚdataclassesÚfieldr‘   rQ   r2   rR   rY   r_   rp   rU   r‡   r�   r“   rh   rj   © rZ   rX   rI   rI   N   su   … àÓØ
ƒOØ,Ó,Ø-˜K×-Ñ-¸dÔC€Eˆ>ÓCØ.?¨k×.?Ñ.?Ø3ô/€JÐ+ó óó
$ó$ó($ó?óB
ó+ó8ô.rZ   rI   c                  ó   — e Zd ZU dZded<   y)ÚSchedulerDonatedBufferNrM   rN   )rf   r¡   r¢   rN   r£   r¦   rZ   rX   r¨   r¨   ·   s   … à/3€KÐ,Ô3rZ   r¨   c                  ó‚  — e Zd ZU ded<   ded<   ded<   ded<   ded	<   d
ed<   d?d„Zd@d„ZdAd„ZdAd„ZdAd„ZdBd„Z	dAd„Z
dCd„Z	 	 	 	 	 	 dDd„ZdEd„ZdFd„ZdGd„ZdHd„Z	 	 	 	 	 	 dId„ZdCd„ZdJd„ZdJd„ZdCd„ZdCd„Z	 	 	 	 dKd„ZdAd „ZdAd!„ZedJd"„«       ZedJd#„«       ZedGd$„«       ZedGd%„«       ZdLd&„ZdMd'„Z dNd(„Z!dOd)„Z"dGd*„Z#dGd+„Z$dGd,„Z%dGd-„Z&dGd.„Z'dGd/„Z(dGd0„Z)dPd1„Z*dGd2„Z+dCd3„Z,	 dQ	 	 	 	 	 dRd4„Z-edSd5„«       Z.edSd6„«       Z/edSd7„«       Z0	 	 	 	 	 	 dTd8„Z1	 	 	 	 	 	 dUd9„Z2edVd:„«       Z3dWd;„Z4dXd<„Z5e6	 	 	 	 dYd=„«       Z7y>)ZrG   z7tuple[torch.device, tuple[tuple[sympy.Expr, ...], ...]]Úgroupúdependencies.ReadWritesÚread_writeszOrderedSet[Dep]Úunmet_dependenciesr›   Ú	min_orderÚ	max_orderr3   Úmpi_nodec                ó"   — || _         d„ | _        y )Nc                 ó   — g S rT   r¦   )ru   Úkwargss     rX   ú<lambda>z,BaseSchedulerNode.__init__.<locals>.<lambda>Ì   s   €  B€ rZ   )rK   Údebug_device_str)rV   rK   s     rX   Ú__init__zBaseSchedulerNode.__init__É   s   € Ø$-ˆŒá&ð 	ÕrZ   c                óZ  — || _         t        t           «       | _        t        t           «       | _        d| _        |j                  «       D �cg c]  }t        | j                  || ¬«      ‘Œ c}| _	        | j                  D �ci c]  }|j                  «       |“Œ c}| _        y c c}w c c}w )NF)rK   rL   rN   )rL   r   r™   Ú	ancestorsÚ
last_usageÚwrittenÚget_outputsrI   rK   ÚoutputsrU   Úoutputs_by_name)rV   rL   ÚoutputÚbufs       rX   Ú_init_from_nodez!BaseSchedulerNode._init_from_nodeÏ   s    € Ø,0ˆŒ	Ü#¤C™Ó*ˆŒÜ$Üñ
ó ˆŒð ˆŒð ×*Ñ*Ó,ö/
ð ô ØŸ.™.ØØ öò/
ˆŒð ,0¯<©<ö<
Ø$'ˆC�L‰L‹N˜CÑò<
ˆÕùò/
ùò<
s   ÁB#ÂB(c                óT   — t        | «      j                  › d| j                  «       ›d�S )Nz(name=ú)©re   rf   rU   r^   s    rX   Ú__repr__zBaseSchedulerNode.__repr__â   s'   € Ü�t“*×%Ñ%Ð& f¨T¯]©]«_Ð,?¸qÐAÐArZ   c                óH  — | j                  «       }t        «       }|j                  |› dt        | «      j                  › dt        t        | dd«      «      j                  › d|› dt        | j                  j                  «      › d|› dt        | j                  «      › d|› d	t        | j                  j                  | j                  z
  «      › d|› d
�«       |j                  «       5  | j                  «       D ]!  }|j                  |j                  «       «       Œ# 	 ddd«       |j                  d«       	 |j                  | j                  «       «       |j'                  «       j)                  «       S # 1 sw Y   ŒXxY w# t         $ r t"        j%                  dd¬«       Y ŒLw xY w)ú#Longer form printout for trace logsra   ú(rL   Nú)
ú
.writes = ú
ú.unmet_dependencies = ú.met_dependencies = z.outputs = [
        rc   úIgnoring error in debug_str()T©Úexc_info)rU   r=   Úsplicere   rf   Úgetattrri   r¬   Úwritesr­   Úreadsrl   r»   rp   rd   Údebug_str_extraÚ	ExceptionÚlogÚwarningrm   Úrstrip)rV   r]   r¿   Úouts       rX   rp   zBaseSchedulerNode.debug_strå   sƒ  € à�}‰}‹ˆÜÓˆØ�
‰
à€€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   Ã%5E2Ä5E> Å2E;Å> F!Æ F!c                 ó   — y)NÚ r¦   r^   s    rX   rÔ   z!BaseSchedulerNode.debug_str_extraþ   ó   € ØrZ   c                ó$   — | j                  | «      S rT   )rµ   r^   s    rX   Ú_debug_str_for_devicez'BaseSchedulerNode._debug_str_for_device  s   € Ø×$Ñ$ TÓ*Ð*rZ   c                ó°  — t        | j                  dd «      }d}t        |t        j                  j
                  j                  «      r'd|j                  |j                  «       gdd¬«      z   }nct        |t        j                  j
                  j                  «      r5d|j                  |j                  «       |j                  «       gdd¬«      z   }| › |› �S )NÚdatarÛ   z, F)ÚshortenÚ	multiline)rÑ   rL   ry   ÚtorchÚ	_inductorr   Ú	PointwiseÚ
str_helperÚget_sizeÚ	ReductionÚget_reduction_sizeÚget_reduction_type)rV   Ú
maybe_dataÚdata_strs      rX   Údebug_str_shortz!BaseSchedulerNode.debug_str_short  sË   € Ü˜TŸY™Y¨°Ó5ˆ
ØˆÜ�j¤%§/¡/×"4Ñ"4×">Ñ">Ô?Ø˜j×3Ñ3Ø×$Ñ$Ó&Ð'°À%ð 4ó ñ ‰Hô ˜
¤E§O¡O×$6Ñ$6×$@Ñ$@ÔAØ˜j×3Ñ3Ø×.Ñ.Ó0°*×2OÑ2OÓ2QÐRØØð 4ó ñ ˆHð
 �˜�zÐ"Ð"rZ   c                óp   — t         j                  d| | j                  | j                  j                  «       y )Nz(%s: unmet_dependencies = %s, writes = %s)rÖ   Úinfor­   r¬   rÒ   r^   s    rX   Úlog_detailszBaseSchedulerNode.log_details  s,   € Ü�‰Ø6ØØ×#Ñ#Ø×Ñ×#Ñ#õ		
rZ   c                 ó   — y rT   r¦   )rV   Úself_depÚ	other_deps      rX   Úreorder_loops_by_dep_pairz+BaseSchedulerNode.reorder_loops_by_dep_pair  s   € ð 	rZ   c                óX   — | j                  | j                  j                  |«      «       y rT   )Úset_read_writesr¬   Úrename©rV   Úrenamess     rX   Úupdate_mutated_namesz&BaseSchedulerNode.update_mutated_names   s!   € Ø×Ñ˜T×-Ñ-×4Ñ4°WÓ=Õ>rZ   c                óX   — | j                  | j                  j                  |«      «       y rT   )rö   r¬   Ú	with_read©rV   Údeps     rX   Úadd_fake_depzBaseSchedulerNode.add_fake_dep#  s!   € Ø×Ñ˜T×-Ñ-×7Ñ7¸Ó<Õ=rZ   c                óB   — t        d„ | j                  «       D «       «      S )Nc              3  ó`   K  — | ]&  }|j                  «       xs |j                  «       –— Œ( y ­wrT   )rh   rj   )Ú.0r¿   s     rX   ú	<genexpr>z=BaseSchedulerNode.has_aliasing_or_mutation.<locals>.<genexpr>'  s-   è ø€ ò 
Ø9<ˆC�O‰OÓÒ4 ×!2Ñ!2Ó!4Ó4ñ
ùs   ‚,.)Úanyr»   r^   s    rX   Úhas_aliasing_or_mutationz*BaseSchedulerNode.has_aliasing_or_mutation&  s%   € Üñ 
Ø@D×@PÑ@PÓ@Rô
ó 
ð 	
rZ   c                óh   — || _         | j                   j                  | _        | j                  «        y rT   )r¬   rÓ   r­   Ú
prune_deps)rV   Úrws     rX   rö   z!BaseSchedulerNode.set_read_writes+  s(   € ØˆÔØ"&×"2Ñ"2×"8Ñ"8ˆÔØ�‰ÕrZ   c                ób   ‡— | j                  «       }t        ˆfd„|D «       «      }||z
  | _        y )Nc              3  óB   •K  — | ]  }‰j                  ||«      –— Œ y ­wrT   )Úget)r  ÚkÚmutation_real_names     €rX   r  z3BaseSchedulerNode.set_last_usage.<locals>.<genexpr>4  s   øè ø€ Ò!UÀ1Ð"4×"8Ñ"8¸¸A×">Ñ!Uùs   ƒ)Úused_or_aliased_buffer_namesr   r¹   )rV   Úfuture_used_buffersr  Úused_bufferss     ` rX   Úset_last_usagez BaseSchedulerNode.set_last_usage0  s0   ø€ ð ×8Ñ8Ó:ˆÜ!Ó!UÈÔ!UÓUˆØ&Ð)<Ñ<ˆ�rZ   c                óF   — | j                   D ]  }|j                  «        Œ y rT   )r¼   r‡   )rV   r¿   s     rX   Úmark_runzBaseSchedulerNode.mark_run7  s   € Ø—<‘<ò 	ˆCØ�L‰L�Nñ	rZ   c                óž   — t        d„ t        j                  | j                  j                  | j                  j
                  «      D «       «      S )Nc              3  ó4   K  — | ]  }|j                   –— Œ y ­wrT   ©r]   ©r  rþ   s     rX   r  z6BaseSchedulerNode.used_buffer_names.<locals>.<genexpr><  s   è ø€ ò 
àð �H�Hñ
ùó   ‚)r   Ú	itertoolsÚchainr¬   rÓ   rÒ   r^   s    rX   Úused_buffer_namesz#BaseSchedulerNode.used_buffer_names;  s?   € Üñ 
ä —‘ t×'7Ñ'7×'=Ñ'=¸t×?OÑ?O×?VÑ?VÓWô
ó 
ð 	
rZ   c                ó2  ‡— t        t           «       Št        j                  | j                  j
                  | j                  j                  «      D �cg c]  }|j                  ‘Œ }}t        |«      dkD  rœ|j                  «       }‰j                  |«       t        j                  j                  j                  |«      rC|j                  ˆfd„t        j                  j                  |   j!                  «       D «       «       t        |«      dkD  rŒœ‰S c c}w )Nr   c              3  ó*   •K  — | ]
  }|‰vr|–— Œ y ­wrT   r¦   )r  ÚaliasÚ
used_namess     €rX   r  zABaseSchedulerNode.used_or_aliased_buffer_names.<locals>.<genexpr>L  s#   øè ø€ ò àð  JÑ.ô	 ñùs   ƒ)r   r™   r  r  r¬   rÓ   rÒ   r]   rk   ÚpopÚaddrD   r|   Úname_to_bufferr  Úextendrw   )rV   rþ   Údepsr  s      @rX   r  z.BaseSchedulerNode.used_or_aliased_buffer_namesA  sß   ø€ Ü¤‘_Ó&ˆ
ô !—‘ t×'7Ñ'7×'=Ñ'=¸t×?OÑ?O×?VÑ?VÓWö
àð �H‹Hð
ˆð 
ô �$‹i˜!ŠmØ—(‘(“*ˆCØ�N‰N˜3ÔÜ�w‰w×%Ñ%×)Ñ)¨#Ô.Ø—‘ó ä!"§¡×!7Ñ!7Øñ"ç2Ñ2Ó4ô	ô ô	 �$‹i˜!‹mð Ðùò
s   ÁDc                óL   ‡ — t        ˆ fd„‰ j                  D «       «      ‰ _        y )Nc              3  óf   •K  — | ](  }|j                   ‰j                  j                  vr|–— Œ* y ­wrT   )r]   rK   Úavailable_buffer_names©r  rþ   rV   s     €rX   r  z/BaseSchedulerNode.prune_deps.<locals>.<genexpr>V  s/   øè ø€ ò -
àØ�x‰x˜tŸ~™~×DÑDÑDô ñ-
ùs   ƒ.1©r   r­   r^   s   `rX   r  zBaseSchedulerNode.prune_depsU  s#   ø€ Ü",ó -
à×.Ñ.ô-
ó #
ˆÕrZ   c                ó¸   ‡ ‡— dˆ fd„Št        ˆfd„‰ j                  j                  D «       «      }‰ j                  ‰ j                  j	                  |«      «       y )Nc                óÀ   •— t        | t        «      sy‰j                  j                  | j                     j                  «       }|t        j                  j                  v S ©NF)	ry   r)   rK   rƒ   r]   rY   rD   r|   Úremoved_operations)rþ   Úop_namerV   s     €rX   Úshould_prunez7BaseSchedulerNode.prune_weak_deps.<locals>.should_prune^  sF   ø€ Ü˜c¤7Ô+ØØ—n‘n×0Ñ0°·±Ñ:×KÑKÓMˆGØœaŸg™g×8Ñ8Ð8Ð8rZ   c              3  ó4   •K  — | ]  } ‰|«      sŒ|–— Œ y ­wrT   r¦   ©r  rþ   r/  s     €rX   r  z4BaseSchedulerNode.prune_weak_deps.<locals>.<genexpr>d  s   øè ø€ ò 
Ø±\À#Õ5FŒCñ
ùó   ƒ‘©rþ   r&   r˜   rŸ   )r   r¬   rÓ   rö   Úremove_reads)rV   Ú	to_remover/  s   ` @rX   Úprune_weak_depsz!BaseSchedulerNode.prune_weak_deps\  sN   ù€ õ	9ô ó 
Ø×+Ñ+×1Ñ1ô
ó 
ˆ	ð 	×Ñ˜T×-Ñ-×:Ñ:¸9ÓEÕFrZ   c                óF   — t        | || j                  j                  «       y rT   )Ú_prune_redundant_depsrK   rƒ   )rV   Úname_to_fused_nodes     rX   Úprune_redundant_depsz&BaseSchedulerNode.prune_redundant_depsi  s   € ô 	˜dÐ$6¸¿¹×8RÑ8RÕSrZ   c                óR   — | j                   €J ‚| j                   j                  «       S rT   )rL   Úget_operation_namer^   s    rX   rU   zBaseSchedulerNode.get_namen  r–   rZ   c                ó"   — | j                  «       S rT   ©rU   r^   s    rX   Úget_first_namez BaseSchedulerNode.get_first_namer  s   € Ø�}‰}‹ÐrZ   c                óB   — t        d„ | j                  «       D «       «      S )Nc              3  ó<   K  — | ]  }|j                  «       –— Œ y ­wrT   r>  )r  rL   s     rX   r  z8BaseSchedulerNode.get_operation_names.<locals>.<genexpr>w  s   è ø€ ÒG¨d˜$Ÿ-™-Ÿ/ÑGùó   ‚)r   Ú	get_nodesr^   s    rX   Úget_operation_namesz%BaseSchedulerNode.get_operation_namesu  s   € äÑG°d·n±nÓ6FÔGÓGÐGrZ   c                ó:   — t        d„ | j                  D «       «      S )Nc              3  ó<   K  — | ]  }|j                  «       –— Œ y ­wrT   r>  ©r  rÙ   s     rX   r  z5BaseSchedulerNode.get_buffer_names.<locals>.<genexpr>{  s   è ø€ ÒA¨S˜#Ÿ,™,Ÿ.ÑAùrB  )r   r¼   r^   s    rX   Úget_buffer_namesz"BaseSchedulerNode.get_buffer_namesy  s   € äÑA°D·L±LÔAÓAÐArZ   c                óB   — t        d„ | j                  «       D «       «      S )Nc              3  óZ   K  — | ]#  }t        |t        «      xr t        |d ¬«      –— Œ% y­w)T)Údisallow_fp32_opsN©ry   ÚSchedulerNoder!   ©r  Úns     rX   r  zABaseSchedulerNode.can_codegen_in_low_precision.<locals>.<genexpr>  s7   è ø€ ò 
ð ô �qœ-Ó(ò GÜ+¨AÀÔFóGñ
ùs   ‚)+©ÚallrC  r^   s    rX   Úcan_codegen_in_low_precisionz.BaseSchedulerNode.can_codegen_in_low_precision}  s%   € äñ 
ð —^‘^Ó%ô
ó 
ð 	
rZ   c                óB   — t        d„ | j                  «       D «       «      S )Nc              3  óV   K  — | ]!  }t        |t        «      xr t        |«      –— Œ# y ­wrT   rL  rN  s     rX   r  z@BaseSchedulerNode.can_codegen_without_upcasts.<locals>.<genexpr>‡  s-   è ø€ ò 
àô �qœ-Ó(ÒKÔ-HÈÓ-KÓKñ
ùs   ‚')rP  r^   s    rX   r!   z-BaseSchedulerNode.can_codegen_without_upcasts…  s#   € äñ 
à—^‘^Ó%ô
ó 
ð 	
rZ   c                ó   — | gS rT   r¦   r^   s    rX   rC  zBaseSchedulerNode.get_nodesŒ  s	   € ØˆvˆrZ   c                ó   — | j                   S rT   )r¼   r^   s    rX   r»   zBaseSchedulerNode.get_outputs�  s   € Ø�|‰|ÐrZ   c                ó    — | j                   |   S rT   )r½   )rV   Úbuf_names     rX   Ú
get_outputzBaseSchedulerNode.get_output’  s   € Ø×#Ñ# HÑ-Ð-rZ   c                óR   — | j                   €J ‚| j                   j                  «       S rT   )rL   Ú
get_devicer^   s    rX   r[  zBaseSchedulerNode.get_device•  s%   € Ø�y‰yÐ$Ð$Ð$Ø�y‰y×#Ñ#Ó%Ð%rZ   c                óL   — | j                  «       }|d uxr |j                  dk(  S ©NÚcpu)r[  re   ©rV   Údevices     rX   Úis_cpuzBaseSchedulerNode.is_cpu™  s'   € Ø—‘Ó"ˆØ˜TÐ!Ò: f§k¡k°UÑ&:Ð:rZ   c                óX   — | j                  «       }|d uxr t        |j                  «      S rT   )r[  r?   re   r_  s     rX   r?   zBaseSchedulerNode.is_gpu�  s'   € Ø—‘Ó"ˆØ˜TÐ!Ò9¤f¨V¯[©[Ó&9Ð9rZ   c                 ó   — yr,  r¦   r^   s    rX   Úis_reductionzBaseSchedulerNode.is_reduction¡  ó   € ØrZ   c                 ó   — yr,  r¦   r^   s    rX   Úis_split_scanzBaseSchedulerNode.is_split_scan¤  re  rZ   c                 ó   — yr,  r¦   r^   s    rX   Úis_templatezBaseSchedulerNode.is_template§  re  rZ   c                 ó   — yr,  r¦   r^   s    rX   Ú	is_externzBaseSchedulerNode.is_externª  re  rZ   c                 ó   — yr,  r¦   r^   s    rX   Ú
is_foreachzBaseSchedulerNode.is_foreach­  re  rZ   c                 ó   — yr,  r¦   ©rV   Úread_deps     rX   Úcan_inplacezBaseSchedulerNode.can_inplace°  re  rZ   c                 ó   — yr,  r¦   r^   s    rX   Úhas_side_effectsz"BaseSchedulerNode.has_side_effects³  re  rZ   c                ó\
  ‡ — ddl m} t        ‰ t        «      rÇt        j
                  r·t        j                  j                  ‰ j                  «       t        j                  «      r{t        t        j                  t        j                  j                  j                   j"                  «      rt%        t        j                  dd«      �t'        t        j                  d«      sy‰ j(                  t        j                  j*                  z  ‰ j,                  j.                  z  }dˆ fd„}‰ j1                  «       D �]ð  }|j2                  }|€J ‚|j5                  «       rJ|j7                  «       s:|j9                  «       s*|j;                  «       t        j                  j<                  v rŒo‰ j>                  j@                  D �]h  }|jB                  ‰ j,                  jD                  v r$‰ j,                  jD                  |jB                     }n/‰ j,                  jF                  jI                  |jB                  «      }|sŒ|t        j                  jJ                  jM                  |‰ «      sŒ§t        |jN                  tP        «      rŒÂ|jR                  €J ‚|jR                  D �cg c]   }|j2                  j;                  «       |vr|‘Œ" }	}tU        |	«      dk(  s�Œ|	d   jV                  s�Œ&|	d   j2                  ‰ u s�Œ9|j2                  €�ŒGt        |j2                  jY                  «       tZ        j\                  tZ        j^                  tZ        j`                  f«      r�Œš|jN                  rft        |jN                  j2                  tZ        jb                  tZ        jd                  f«      r(tU        |j2                  j7                  «       «      dkD  r�Œ ||j2                  |j2                  «      s�Œ+ ||«      s�Œ5t        j                  jf                  ji                  |j;                  «       |j;                  «       «       t        t        j                  t        j                  j                  j                   j"                  «      rnt        j                  jj                  jm                  |j;                  «       «       t        j                  jj                  jm                  |j;                  «       «       |j;                  «       t        j                  jn                  |j;                  «       <    �Œð �Œó yc c}w )	z~
        Decide if there should be inplace updates for the node
        and record the decision in the active kernel.
        r   )Úcan_match_buffer_sizeÚ	mutationsNru   c                óv  •‡— | j                   j                  ‰«      }| j                  «       Št        «       }| j                  D ]s  }|j
                  }t        |t        «      sŒ | j                   j                  |«      |urŒ>|ˆfd„|j                  j                  «       D «       z  }t        |«      dkD  sŒs y y)Nc              3  ó@   •K  — | ]  }|j                   ‰k(  r|–— Œ y ­wrT   r  )r  ÚorX  s     €rX   r  z^BaseSchedulerNode.decide_inplace_update.<locals>.single_index_in_fused_node.<locals>.<genexpr>ç  s%   øè ø€ ò àØ—v‘v Ò)ô ñùó   ƒr   FT)rK   Úget_fused_noderU   r   rQ   rL   ry   rG   r¬   Úreads_and_writesrk   )Úbuf_to_be_inplacedÚ
fused_noder$  ro   Ú	user_noderX  rV   s        @€rX   Úsingle_index_in_fused_nodezKBaseSchedulerNode.decide_inplace_update.<locals>.single_index_in_fused_nodeÑ  s¼   ù€ ð
 ,×5Ñ5×DÑDÀTÓJˆJØ)×2Ñ2Ó4ˆHô %/£LˆDØ*×0Ñ0ò !�Ø ŸI™I�	Ü! )Ô->Ô?Øð '×0Ñ0×?Ñ?À	ÓJØ%ñ&ð àó à&×2Ñ2×CÑCÓEôñ �ô
 �t“9˜q“=Ù ð#!ð& rZ   r   )r}  rI   r˜   rŸ   )8Úcodegen.wrapperru  ry   rM  r   Úinplace_buffersrD   r|   Úhas_featurer[  r"   ÚINPLACE_BUFFERSr€   rã   rä   ÚcodegenÚsimdÚ
SIMDKernelrÑ   r   r¸   r-  rK   Úcompleted_operationsr»   rL   rv   rw   rx   rU   Úremoved_buffersr¬   rÓ   r]   r‚   rƒ   r  r}   Ú	can_reuserN   ÚNopKernelSchedulerNoderQ   rk   rq  rz   r   rŠ   r0   ÚMutationLayoutSHOULDREMOVEÚFallbackKernelr/   ru   Úmake_inplacerv  r!  r�   )
rV   ru  Úinconsequential_nodesr€  r¿   Úbuf_nodeÚreadÚ	input_bufÚxÚremaining_usess
   `         rX   Údecide_inplace_updatez'BaseSchedulerNode.decide_inplace_update¶  s­  ø€ õ
 	;ô �tœ]Ô+Ü×&Ò&Ü—‘×#Ñ# D§O¡OÓ$5´~×7UÑ7UÔVäœqŸx™x¬¯©×)@Ñ)@×)EÑ)E×)PÑ)PÔQÜœ1Ÿ8™8 [°$Ó7ÐCô œŸ™ &Ô)àð �N‰NÜ�g‰g×(Ñ(ñ)à�n‰n×1Ñ1ñ2ð 	õ	ð@ ×#Ñ#Ó%ó C	ˆCØ—x‘xˆHØÐ'Ð'Ð'à×,Ñ,Ô.Ø×8Ñ8Ô:Ø×.Ñ.Ô0Ø—<‘<“>¤Q§W¡W×%<Ñ%<Ñ<àà×(Ñ(×.Ñ.ó 8�à—9‘9 §¡× EÑ EÑEØ $§¡× EÑ EÀdÇiÁiÑ P‘Ià $§¡× :Ñ :× >Ñ >¸t¿y¹yÓ I�Iò ÜŸ™×,Ñ,×6Ñ6°yÀ$ÕGÜ& y×'<Ñ'<Ô>TÕUà$Ÿ?™?Ð6Ð6Ð6ð "+§¡ö&àØŸ6™6Ÿ?™?Ó,Ð4IÑIò ð&�Nð &ô ˜NÓ+¨qÔ0Ø*¨1Ñ-×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Ù6°yÖ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8ñC	ùò0&s   Ê%T)c                ó.  — t         j                  sy |r| j                  ry | j                  €J ‚| j                  j	                  «       }g }|D �]  }|j
                  dk(  rŒ|j                  d«       |j                  d«       d|j
                  › d|j                  › �}d|j                  v r|d|j                  d   › �z   }|j                  |«       d|j                  v sŒ•|j                  d   › }|j                  d	«      d
   }|j                  d|j                  dd«      j                  dd«      j                  dd«      z   «       |j                  d«       |j                  d«       �Œ! t        |«      dk(  ry |j                  |«       d| _        y )Nr¾   rÛ   z#pragma CMT ORIGIN:z#pragma CMT ú Úseq_nrz seq_nr:Ústack_traceú|éÿÿÿÿú{z{{ú}z}}rÊ   ú\z#pragma CMT END ORIGINr   T)r   Úcomment_originrº   rL   Úget_originsrW   ÚappendÚtargetÚmetaÚsplitÚreplacerk   Ú
writelines)	rV   ÚbufferÚ	only_onceÚoriginsÚ	out_linesry  Úop_info_strr™  Ústack_trace_last_lines	            rX   Úcodegen_originating_infoz*BaseSchedulerNode.codegen_originating_info6  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×(9Ñ(9¸#Ó(>¸rÑ(BÐ%Ø× Ñ Ø"Ø+×3Ñ3°C¸Ó>ß‘W˜S $Ó'ß‘W˜T 4Ó(ñ)ôð × Ñ Ð!9Ô:Ø× Ñ  Ö$ð-	%ô0 ˆy‹>˜QÒØð 	×Ñ˜)Ô$Øˆ�rZ   c                ó(   — | j                  dd¬«      S )NT©Úinclude_readsÚinclude_writes©Ú!get_read_write_buffers_sizes_implr^   s    rX   Úget_read_write_buffers_sizesz.BaseSchedulerNode.get_read_write_buffers_sizesb  s   € à×5Ñ5Ø¨tð 6ó 
ð 	
rZ   c                ó(   — | j                  dd¬«      S )NTFr¯  r²  r^   s    rX   Úget_read_buffer_sizesz'BaseSchedulerNode.get_read_buffer_sizesh  s   € à×5Ñ5Ø¨uð 6ó 
ð 	
rZ   c                ó(   — | j                  dd¬«      S )NFTr¯  r²  r^   s    rX   Úget_write_buffer_sizesz(BaseSchedulerNode.get_write_buffer_sizesn  s   € à×5Ñ5Ø°ð 6ó 
ð 	
rZ   c                óZ   — t        | j                  ||¬«      j                  «       d¬«      S )Nr¯  r   )Ústart)ÚsumÚget_read_write_buffer_accessesr’   )rV   r°  r±  s      rX   r³  z3BaseSchedulerNode.get_read_write_buffers_sizes_implt  s3   € ô Ø×/Ñ/Ø+¸Nð 0ó ç‰f‹hØô	
ð 	
rZ   c                ó$  ‡ ‡‡‡‡‡— t        ‰ t        «      ri S t        ‰ t        «      rt        ‰ j                  t        «      ri S dd„Št        ‰ t
        «      r@ ‰t        ‰ j                  «       d   «      t        ‰ j                  «       d   «      z  «      Šnt        d«      Št        j                  t        «      }|r9‰ j                  j                  D ]   }||j                     j                  |«       Œ" |r9‰ j                  j                   D ]   }||j                     j                  |«       Œ" |r&t#        d„ ‰ j                  j                  D «       «      n	t#        «       }|r&t#        d„ ‰ j                  j                   D «       «      n	t#        «       }dˆ fd„Št        ‰ t$        «      rt#        ˆˆ fd„|D «       «      }||z
  }||z
  }i }||z  D ]º  }	t'        ˆfd	„||	   D «       «      Š|	t(        j*                  j,                  v rt(        j*                  j,                  |	   }
n;|	t(        j*                  j.                  v rt(        j*                  j.                  |	   }
nŒ�	 	 	 	 dˆˆˆ ˆfd
„Š ‰|
«      }|	|vr|||	<   Œ®||	xx   |z  cc<   Œ¼ |S )az  
        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                óX   — t         j                  j                  j                  | d¬«      S )Nr   ©Úfallback)rD   r|   ÚsizevarsÚ	size_hint)Úss    rX   Útry_size_hintzGBaseSchedulerNode.get_read_write_buffer_accesses.<locals>.try_size_hint¡  s"   € Ü—7‘7×#Ñ#×-Ñ-¨a¸!Ð-Ó<Ð<rZ   r   r   ç    eÍÍAc              3  ó4   K  — | ]  }|j                   –— Œ y ­wrT   r  r  s     rX   r  zCBaseSchedulerNode.get_read_write_buffer_accesses.<locals>.<genexpr>¶  s   è ø€ ÒB C�s—x•xÑBùr  c              3  ó4   K  — | ]  }|j                   –— Œ y ­wrT   r  r  s     rX   r  zCBaseSchedulerNode.get_read_write_buffer_accesses.<locals>.<genexpr>»  s   è ø€ ÒC C�s—x•xÑCùr  c                ó¢   •— ‰j                   j                  |    j                  }t        d„ |D «       «      }t	        |t        |«      z
  «      dkD  S )Nc              3  ó4   K  — | ]  }|j                   –— Œ y ­wrT   ©rL   )r  ro   s     rX   r  z\BaseSchedulerNode.get_read_write_buffer_accesses.<locals>.is_materialized.<locals>.<genexpr>Â  s   è ø€ Ò!>° $§)¥)Ñ!>ùr  r   )rK   rƒ   rQ   r   rk   )r¿   ÚsnodesrQ   Úbuf_usesrV   s       €rX   Úis_materializedzIBaseSchedulerNode.get_read_write_buffer_accesses.<locals>.is_materializedÀ  sG   ø€ Ø—N‘N×.Ñ.¨sÑ3×9Ñ9ˆEÜ!Ñ!>¸Ô!>Ó>ˆHÜ�x¤*¨VÓ"4Ñ4Ó5¸Ñ9Ð9rZ   c              3  óJ   •K  — | ]  } ‰|‰j                   «      rŒ|–— Œ y ­wrT   ©rË  )r  rþ   rÍ  rV   s     €€rX   r  zCBaseSchedulerNode.get_read_write_buffer_accesses.<locals>.<genexpr>Æ  s#   øè ø€ ò )Ø©_¸SÀ$Ç+Á+Õ-N”ñ)ùs   ƒ#œ#c              3  ó"   •K  — | ]  }‰–— Œ y ­wrT   r¦   )r  rþ   Ú
node_numels     €rX   r  zCBaseSchedulerNode.get_read_write_buffer_accesses.<locals>.<genexpr>Ï  s   øè ø€ Ò$R°C¤ZÑ$Rùs   ƒc                ó  •— | syt        | t        j                  «      r| j                  «       S t        | j                  t
        «      r²‰j                  j                  | j                  «          j                  }d}|D ]x  }t        |j                  t        «      sJ ‚t        |j                  j                  t        «      r5|j                  j                  «       D ]  }| ‰|j                  «      z  }Œ Œx y |S t        | j                  t        j                  «      r"t        ˆfd„| j!                  «       D «       «      S  ‰	t#        | j%                  «       «      «      }t'        | j)                  «       «      t+        ‰|«      z  S )Nr   c              3  óh   •K  — | ])  } ‰t         j                  j                  |«      «      –— Œ+ y ­wrT   )rD   r|   Ú
get_buffer)r  Úmut_nameÚget_buf_bytess     €rX   r  zZBaseSchedulerNode.get_read_write_buffer_accesses.<locals>.get_buf_bytes.<locals>.<genexpr>ñ  s-   øè ø€ ò à$ñ &¤a§g¡g×&8Ñ&8¸Ó&B×Cñùs   ƒ/2)ry   r   ÚTorchBindObjectrÖ  rg   r0   rK   rƒ   rU   rQ   rL   rG   r/   r»   rŠ   r»  rx   rC   rç   r;   Ú	get_dtypeÚmin)
r¿   rQ   Útotro   Ú	sched_bufÚ	buf_elemsÚbuf_accessed_elemsrÖ  rV   rÄ  s
         €€€€rX   rÖ  zGBaseSchedulerNode.get_read_write_buffer_accesses.<locals>.get_buf_bytesØ  sC  ø€ ñ Øä˜c¤2×#5Ñ#5Ô6Ø×,Ñ,Ó.Ð.Ü §
¡
Ô,=Ô>ð !ŸN™N×6Ñ6°s·|±|³~ÑF×LÑL�EØ�CØ %ò 	%˜Ü)¨$¯)©)Ô5FÔGÐGÐGÜ% d§i¡i§n¡n´kÔBØ-1¯Y©Y×-BÑ-BÓ-Dò E 	Ø #¡}°Y·^±^Ó'DÑ D¡ñEñ $%ð	%ð �JÜ §
¡
¬B¯M©MÔ:Üó à(+×(>Ñ(>Ó(@ôó ð ñ
 !.¬m¸C¿L¹L»NÓ.KÓ L�IÜ)¨#¯-©-«/Ó:¼SØ*¨Ió>ñ ð rZ   )rÃ  z
sympy.Exprr˜   r›   )r¿   r™   rË  úSequence[BaseSchedulerNode]r˜   rŸ   )r¿   z<Optional[Union[ir.Buffer, ir.TensorBox, ir.TorchBindObject]]r˜   r›   )ry   r‹  ÚExternKernelSchedulerNoderL   r/   rM  rC   Ú
get_rangesr›   Úcollectionsr   r‘   r¬   rÓ   r]   r¡  rÒ   r   ÚFusedSchedulerNoder»  rD   r|   r"  Úgraph_inputs)rV   r°  r±  Úbuf_accessesrþ   rÓ   rÒ   r‰  Úbuf_byte_accessesrX  r¿   Ú	buf_bytesrÝ  rÖ  rÍ  rÑ  rÄ  s   `           @@@@@rX   r¼  z0BaseSchedulerNode.get_read_write_buffer_accesses~  sn  ý€ ô6 �dÔ2Ô3ØˆIÜ�dÔ5Ô6¼:Ø�I‰I”{ô<
ð ˆIó	=ô �dœMÔ*Ù&Ü˜dŸo™oÓ/°Ñ2Ó3Ü §¡Ó 1°!Ñ 4Ó5ñ6ó‰Jô
 ˜S›ˆJÜ"×.Ñ.¬tÓ4ˆáØ×'Ñ'×-Ñ-ò 3�Ø˜SŸX™XÑ&×-Ñ-¨cÕ2ð3ñ Ø×'Ñ'×.Ñ.ò 3�Ø˜SŸX™XÑ&×-Ñ-¨cÕ2ð3ñ
 ô ÑB¨4×+;Ñ+;×+AÑ+AÔBÔBä“ð 	ñ ô ÑC¨4×+;Ñ+;×+BÑ+BÔCÔCä“ð 	õ	:ô
 �dÔ.Ô/Ü(ô )Ø%ô)ó ˆOð ˜oÑ-ˆFØ˜OÑ+ˆEà,.Ðà ™ò 1	9ˆ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ð!à÷!ð !ñF & cÓ*ˆIØÐ0Ñ0Ø.7Ð! (Ò+à! (Ó+¨yÑ8Ô+ðc1	9ðf !Ð rZ   c                ój  — | j                  «       d   j                  «       d   }|j                  j                  «       }t	        t        |«      «      syt        | j                  «      r<t        | j                  t        j                  «      sJ ‚	 t        | j                  «      S t        | j                  «      ry|j                  j!                  «       }	 t#        «       }t%        |«      dz  }t        | t(        «      �rÈt        | j                  t        j*                  «      sJ dt-        | j                  «      ›�«       ‚t.        j1                  t3        | j                  dd«      d«      }|��Xddlm} ddlm}	 t=        d	„ | j                  j>                  D «       «      ry |«       5 }
 |	d
¬«      5 }tA        jB                  | j                  jD                  «      5  tA        jF                  |
«      5  ddlm$} | j                  j>                  D �cg c]  } ||d
¬«      ‘Œ }}| j                  jJ                  } |jL                  |g|¢­i | j                  jN                  ¤Ž d}|jQ                  «       }| jS                  «       }||z  |z  dz  }||z  }tU        ||«      cddd«       cddd«       cddd«       cddd«       S yt        | tV        «      st        | j                  tX        «      r| jS                  «       |z  S y# t        $ r}t        j                  |«       Y d}~yd}~wt        $ r}t        j                  |«       Y d}~yd}~ww xY w# t&        $ r Y yw xY wc c}w # 1 sw Y   nxY wddd«       n# 1 sw Y   nxY wddd«       n# 1 sw Y   nxY wddd«       y# 1 sw Y   yxY w)zB
        Returns estimated op runtime in nanoseconds (ns)
        r   Nl    J)£útype(self.node)=Úpython_kernel_namerÛ   )ÚFakeTensorMode)ÚFlopCounterModec              3  óf   K  — | ])  }t        t        |j                  «       «      «      d kD  –— Œ+ y­w©r   N)rk   r   Ú	get_numelrN  s     rX   r  z:BaseSchedulerNode.get_estimated_runtime.<locals>.<genexpr>6  s.   è ø€ ò àô Ô-¨a¯k©k«mÓ<Ó=ÀÕAñùs   ‚/1F)Údisplayr   )Úir_node_to_tensor)Úguard_shapeg      ð?rÅ  )-rC  r»   rL   rz   r?   r-   r>   ry   r   ÚIRNoder%   Ú
ValueErrorrÖ   rï   Ú	TypeErrorrB   Úmaybe_get_dtyper<   r:   rÕ   rß  ÚExternKernelre   Úkernel_name_to_opr  rÑ   Útorch._subclasses.fake_tensorrê  Útorch.utils.flop_counterrë  r  ÚinputsrD   Úset_current_nodeÚfx_nodeÚset_fake_moderð  Ú	__class__Úprocess_kernelr³   Úget_total_flopsr´  Úmaxrâ  r,   )rV   r¿   rg   ÚeÚdtypeÚgpu_memory_bandwidthÚ	gpu_flopsrW   rê  rë  Ú	fake_modeÚflop_counter_moderð  ÚinputÚfake_inputsÚclsÚfactorÚcounted_flopsÚcounted_bytesÚcompute_timeÚtransfer_times                        rX   Úget_estimated_runtimez'BaseSchedulerNode.get_estimated_runtime  s>  € ð
 �n‰nÓ˜qÑ!×-Ñ-Ó/°Ñ2ˆØ—‘×)Ñ)Ó+ˆÜ”o fÓ-Ô.àô ˜Ÿ™Ô#Ü˜dŸi™i¬¯©Ô3Ð3Ð3ð
Ü7¸¿	¹	ÓBÐBô �T—Y‘YÔð
 à—‘×(Ñ(Ó*ˆð	Ü#4Ó#6Ð Ü)¨%Ó0°6Ñ9ˆIô �dÔ5Õ6Ü˜dŸi™i¬¯©Ô9ÐPÐ>N¼dÀ4Ç9Á9»oÐ=OÐ;PÓPÐ9Ü"×&Ñ&Ü˜Ÿ	™	Ð#7¸Ó<¸dóˆBð
 ‰~ÝHÝDäñ à!ŸY™Y×-Ñ-ôô ð ñ #Ó$ð<Ø(1Ù#¨EÔ2ð<à6GÜ×&Ñ& t§y¡y×'8Ñ'8Ó9ñ<ô —O‘O IÓ.ñ	<õ 6ð &*§Y¡Y×%5Ñ%5ö#à!ñ *¨%¸UÖCð#�Kð #ð Ÿ)™)×-Ñ-�CØ&�C×&Ñ& rÐL¨KÒL¸4¿9¹9×;KÑ;KÒLð !�FØ$5×$EÑ$EÓ$G�MØ$(×$EÑ$EÓ$G�MØ$*¨]Ñ$:¸YÑ$FÈ#Ñ#M�LØ$1Ð4HÑ$H�Mô ˜|¨]Ó;÷/<÷ <÷ <÷ <ô <ð> ô ˜Ô0Ô1´ZØ�I‰I”~ô6
ð ×4Ñ4Ó6Ð9MÑMÐMàøôU ò ô —‘˜”ÜûÜò ä—‘˜”Üûðûô  ò 	Ùð	üò<#÷<ð <ú÷ <÷ <ñ <ú÷ <÷ <ñ <ú÷ <ð> ÷?<ð> ús©   ÂL ÃM Æ(
N)Æ2*NÇM?Ç2M*	ÈM%È"A?M*	Ê!	M?Ê*	NÊ3	N)Ì	MÌL(Ì(MÌ4MÍMÍ	M"Í!M"Í%M*	Í*M3Í/M?Í6	NÍ?NÎNÎ	N)ÎN	ÎN)Î)N2c                 ó   — y rT   r¦   r^   s    rX   Úget_template_nodez#BaseSchedulerNode.get_template_node_  ó   € ØrZ   c                ó.   — | j                  «       }|€J ‚|S rT   ©r  )rV   Útemplates     rX   Úget_template_node_or_throwz,BaseSchedulerNode.get_template_node_or_throwb  s!   € Ø×)Ñ)Ó+ˆØÐ#Ð#Ð#ØˆrZ   c                óf   — t        d„ t        | «      D «       «      }| d| }| |   }| |dz   d }|||fS )zQ
        For the list of nodes, get the prologue, template, and epilogue
        c              3  óH   K  — | ]  \  }}|j                  «       sŒ|–— Œ y ­wrT   ©ri  )r  ÚirO  s      rX   r  zCBaseSchedulerNode.get_prologue_template_epilogue.<locals>.<genexpr>n  s   è ø€ ÒP¡D A qÀÇÁÅœaÑPùs   ‚"›"Nr   )ÚnextÚ	enumerate)ÚnodesÚtemplate_indexÚprologueÚtemplate_nodeÚepilogues        rX   Úget_prologue_template_epiloguez0BaseSchedulerNode.get_prologue_template_epilogueg  sN   € ô ÑP¬I°eÓ,<ÔPÓPˆà˜˜.Ð)ˆØ˜nÑ-ˆØ˜¨!Ñ+Ð-Ð.ˆØ˜¨Ð0Ð0rZ   N)rK   rJ   r˜   r�   )rL   úir.Operationr˜   r�   r—   )r˜   z	list[str]rœ   ©rò   r'   ró   r'   r˜   r�   ©rù   údict[str, str]r˜   r�   )rþ   r&   r˜   r�   rž   )r  r«   r˜   r�   ©r  úOrderedSet[str]r  r'  r˜   r�   ©r˜   r)  ©r9  údict[str, BaseSchedulerNode]r˜   r�   ©r˜   rÞ  )r˜   zSequence[SchedulerBuffer])rX  r™   r˜   rI   ©r˜   úOptional[torch.device]©rp  zdependencies.Depr˜   rŸ   ©T)r§  r=   r¨  rŸ   r˜   r�   rš   )r°  rŸ   r±  rŸ   r˜   r›   )r°  rŸ   r±  rŸ   r˜   zdict[str, int])r˜   Úfloat©r˜   zOptional[ir.TemplateBuffer])r˜   zir.TemplateBuffer)r  úlist[BaseSchedulerNode]r˜   zJtuple[list[BaseSchedulerNode], BaseSchedulerNode, list[BaseSchedulerNode]])8rf   r¡   r¢   r£   r¶   rÀ   rÄ   rp   rÔ   rÞ   rí   rð   rô   rú   rÿ   r  rö   r  r  r  r  r  r6  r:  rU   r?  r7   rD  rH  rR  r!   rC  r»   rY  r[  ra  r?   rd  rg  ri  rk  rm  rq  rs  r•  r­  r´  r¶  r¸  r³  r¼  r  r  r  Ústaticmethodr#  r¦   rZ   rX   rG   rG   ¼   sX  … ØBÓBØ(Ó(Ø'Ó'ð ƒNØƒNØ'Ó'ó
ó
ó&Bó*ó2ó+ó#ó
ðØ!ðØ.7ðà	óó
?ó>ó
ó
ð
=Ø#2ð=ØHVð=à	ó=óó
óó(
óGðTØ">ðTà	óTó
.óð òHó ðHð òBó ðBð ò
ó ð
ð ò
ó ð
óóó.ó&ó;ó:óóóóóóóó~ðB 9=ð*Ø$ð*Ø15ð*à	ó*ðX ò
ó ð
ð
 ò
ó ð
ð
 ò
ó ð
ð

Ø!ð
Ø37ð
à	ó
ðC!Ø!ðC!Ø37ðC!à	óC!ðJ òYó ðYóvóð
 ð1Ø&ð1à	Sò1ó ñ1rZ   c                  óB   — e Zd ZU g d¢Zded<   ded<   d
d„Zdd„Zdd„Zy	)Ú	WhyNoFuse)Únode1Únode2Úreasonru   r™   r:  ztuple[Any, ...]ru   c                ó    — || _         || _        y rT   )r8  r9  ©rV   r8  r9  s      rX   r¶   zWhyNoFuse.__init__}  s   € ØˆŒ
Øˆ�
rZ   c                óJ   — || _         || _        t        j                  | «       y rT   )r:  ru   Ú
fusion_logÚdebug)rV   r:  ru   s      rX   Ú__call__zWhyNoFuse.__call__�  s   € ØˆŒØˆŒ	Ü×Ñ˜ÕrZ   c                ó¨   — d| j                   j                  «       › d| j                  j                  «       › d�| j                  | j                  z  z   S )Nzcannot fuse z with ra   )r8  rU   r9  r:  ru   r^   s    rX   Ú__str__zWhyNoFuse.__str__†  sK   € Ø˜dŸj™j×1Ñ1Ó3Ð4°F¸4¿:¹:×;NÑ;NÓ;PÐ:QÐQSÐTØ�K‰K˜$Ÿ)™)Ñ#ñ
ð 	
rZ   N©r8  rG   r9  rG   r˜   r�   )r:  r™   ru   r   r˜   r�   r—   )rf   r¡   r¢   Ú	__slots__r£   r¶   r@  rB  r¦   rZ   rX   r7  r7  v  s#   … ò 5€IØƒKØ
Óóóô

rZ   r7  c                ó¼   — t        | t        t        f«      rt        | t        ¬«      } t        j                  | d¬«      }d|v rdt        j                  |d«      › �S |S )N©Úkeyé   )rl   rÊ   ú    )	ry   r   ÚsetÚsortedr™   Úpprintri   Útextwraprl   )Úobjrn   s     rX   ri   ri   Œ  sR   € Ü�#œ
¤CÐ(Ô)ä�SœcÔ"ˆÜ�^‰^˜C¨Ô*€FØˆv�~Ø”H—O‘O F¨GÓ4Ð5Ð6Ð6Ø€MrZ   c                  ó0   — e Zd Zdd„Zdd„Zdd„Zd	d„ZeZy)
r‹   c                ó&   — t        |g«      | _        y rT   r)  rý   s     rX   r¶   zOutputNode.__init__—  s   € Ü",¨c¨UÓ"3ˆÕrZ   c                 ó   — yr,  r¦   r^   s    rX   rd  zOutputNode.is_reductionš  re  rZ   c                 ó   — y)Nr¦   r¦   r^   s    rX   rw   z'OutputNode.get_inputs_that_alias_output�  rÜ   rZ   c                 ó   — y)NÚOUTPUTr¦   r^   s    rX   rU   zOutputNode.get_name   s   € ØrZ   N)rþ   r(   r˜   r�   rž   r    r—   )rf   r¡   r¢   r¶   rd  rw   rU   rÄ   r¦   rZ   rX   r‹   r‹   –  s   „ ó4óóóð �HrZ   r‹   c                óÀ  ‡ ‡‡‡‡— t        j                  «       Š‰ j                  D ]N  }t        |t        «      rŒ‰|j
                     j                  «       }‰‰|   j                  «       xx   dz  cc<   ŒP dˆˆˆˆ fd„Št        ˆfd„‰ j                  D «       «      }|r?‰ j                  |z
  ‰ _        ‰ j                  ‰ j                  j                  |«      «       yy)am  
    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                ó®   •— t        | t        «      rD‰| j                     j                  «       }‰‰|   j	                  «          dkD  }‰|   ‰k(  }|xs |S y)Nr   F)ry   r)   r]   rY   rU   )rþ   r.  Úis_redundantÚis_self_deprƒ   Úname_to_dep_countr9  rL   s       €€€€rX   r/  z+_prune_redundant_deps.<locals>.should_pruneº  sb   ø€ Ü�cœ7Ô#Ø! #§(¡(Ñ+×<Ñ<Ó>ˆGØ,Ð-?ÀÑ-H×-QÑ-QÓ-SÑTÐWXÑXˆLð -¨WÑ5¸Ñ=ˆKØÒ. ;Ð.àrZ   c              3  ó4   •K  — | ]  } ‰|«      sŒ|–— Œ y ­wrT   r¦   r1  s     €rX   r  z(_prune_redundant_deps.<locals>.<genexpr>Æ  s   øè ø€ ò Ø±,¸sÕ2CŒñùr2  Nr3  )rá  r   r­   ry   r)   r]   rY   rU   r   rö   r¬   r4  )rL   r9  rƒ   rþ   r.  Údeps_to_prunerY  r/  s   ```   @@rX   r8  r8  ¦  sÐ   ü€ ô '2×&9Ñ&9Ó&;Ðà×&Ñ&ò KˆÜ˜#œwÕ'Ø! #§(¡(Ñ+×<Ñ<Ó>ˆGØÐ0°Ñ9×BÑBÓDÓEÈÑJÔEðK÷

ð 
ô ó Ø×.Ñ.ôó €Mñ Ø"&×"9Ñ"9¸MÑ"IˆÔØ×Ñ˜T×-Ñ-×:Ñ:¸=ÓIÕJð rZ   )zextern_kernels.convolutionzextern_kernels.mmzextern_kernels.bmmzextern_kernels.addmmzextern_kernels._scaled_mmc                  ó8   ‡ — e Zd Zdˆ fd„Zdd„Zdd„Zdd„Zˆ xZS )rß  c                ó„   •— t         ‰| �  |«       | j                  |«       | j                  |j	                  «       «       y rT   ©Úsuperr¶   rÀ   rö   Úget_read_writes©rV   rK   rL   rþ  s      €rX   r¶   z"ExternKernelSchedulerNode.__init__Ú  ó5   ø€ Ü‰Ñ˜Ô#Ø×Ñ˜TÔ"Ø×Ñ˜T×1Ñ1Ó3Õ4rZ   c                óV   — | j                  «       › dt        | j                  dd «      › �S )Nz.node.kernel = ré  )rU   rÑ   rL   r^   s    rX   rÔ   z)ExternKernelSchedulerNode.debug_str_extraß  s*   € Ø—-‘-“/Ð" /´'¸$¿)¹)ÐEYÐ[_Ó2`Ð1aÐbÐbrZ   c                 ó   — y©NTr¦   r^   s    rX   rk  z#ExternKernelSchedulerNode.is_externâ  r  rZ   c                ó‚   — | j                   €J ‚t        | j                   d«      xr | j                   j                  «       S )Nrs  )rL   r   rs  r^   s    rX   rs  z*ExternKernelSchedulerNode.has_side_effectså  s6   € Ø�y‰yÐ$Ð$Ð$Ü�t—y‘yÐ"4Ó5ÒV¸$¿)¹)×:TÑ:TÓ:VÐVrZ   ©rK   rJ   rL   r$  r˜   r�   r—   rž   )rf   r¡   r¢   r¶   rÔ   rk  rs  Ú__classcell__©rþ  s   @rX   rß  rß  Ù  s   ø„ õ5ó
có÷WrZ   rß  c                  ó    ‡ — e Zd Zdˆ fd„Zˆ xZS )r‹  c                ó„   •— t         ‰| �  |«       | j                  |«       | j                  |j	                  «       «       y rT   r^  ra  s      €rX   r¶   zNopKernelSchedulerNode.__init__ë  rb  rZ   rg  )rf   r¡   r¢   r¶   rh  ri  s   @rX   r‹  r‹  ê  s   ø„ ÷5ñ 5rZ   r‹  c                  óJ  ‡ — e Zd ZU ded<   ded<   	 	 	 	 	 	 dˆ fd„Z	 	 d	 	 	 	 	 dd„Z	 	 d	 	 	 	 	 dd„Z	 	 	 	 	 	 dd„Zdd	„Zdd
„Z		 	 	 	 	 	 d d„Z
d!d„Zd"d„Zd#d„Zd#d„Zd#d„Zd$d„Zd%d„Z	 	 	 	 d&d„Zd'd„Z	 d(	 	 	 d)d„Zed*d„«       Zed*d„«       Zd+d„Zed,d„«       Zˆ xZS )-rM  z tuple[Sequence[sympy.Expr], ...]Ú_sizesr1   Ú_bodyc                óf   •— t         ‰| �  |«       | j                  |«       | j                  «        y rT   )r_  r¶   rÀ   Ú_compute_attrsra  s      €rX   r¶   zSchedulerNode.__init__õ  s,   ø€ ô
 	‰Ñ˜Ô#Ø×Ñ˜TÔ"Ø×ÑÕrZ   c                óÞ  — t        | j                  t        j                  t        j                  f«      sJ ‚| j                  j                  ||¬«      \  | _        | _        | j                  j                  «       }| j                  j                  |«      j                  }| || j                  «      f| _        t        j                   xs t        |j                   «       }t        | j                  t        j                  «      r,| j#                  | j                  j%                  |¬«      «       y | j#                  t'        j$                  | j                  g| j                  ¢­d|iŽ«       y )N©Úextra_indexing_constraintsÚrecompute_sizes_body_func)Ú	normalizeru  )ry   rL   r   r,   ÚTemplateBufferÚsimplify_and_reorderrm  rn  Úget_device_or_errorrK   Úget_backendÚgroup_fnrª   r   Úloop_ordering_after_fusionr?   re   rö   Úextract_read_writesr   )rV   rs  rt  r`  rz  Úshould_normalizes         rX   rp  zSchedulerNode._compute_attrsþ  s3  € ô
 ˜$Ÿ)™)¤b×&7Ñ&7¼×9JÑ9JÐ%KÔLÐLÐLØ"&§)¡)×"@Ñ"@Ø'AØ&?ð #Aó #
ÑˆŒ�T”Zð
 —‘×.Ñ.Ó0ˆØ—>‘>×-Ñ-¨fÓ5×>Ñ>ˆØ™h t§{¡{Ó3Ð4ˆŒ
ô  &×@Ñ@Ð@ò 
ÌØ�K‰KóI
ð E
Ðô �d—i‘i¤×!2Ñ!2Ô3Ø× Ñ Ø—	‘	×-Ñ-Ð8HÐ-ÓIõð × Ñ Ü×0Ñ0Ø—J‘JðØ!%§¡òØ8HñõrZ   c                ó*   — | j                  ||¬«       y )Nrr  )rp  )rV   rs  rt  s      rX   Úrecompute_size_and_bodyz%SchedulerNode.recompute_size_and_body  s   € ð
 	×ÑØ'AØ&?ð 	õ 	
rZ   c                ób  — t        d„ | j                  j                  D «       «      }| j                  t	        j
                  | j                  g| j                  ¢­d|iŽj                  |«      «       | j                  j                  | «       |r!ddlm} |j                  j                  «        y y )Nc              3  óN   K  — | ]  }t        |t        t        f«      sŒ|–— Œ y ­wrT   )ry   r)   r(   r  s     rX   r  z5SchedulerNode.refresh_dependencies.<locals>.<genexpr>-  s#   è ø€ ò 0
Ø´ZÀÄgÌwÐEWÕ5XŒCñ0
ùs   ‚%ž%ru  r   ©ÚSIMDScheduling)r   r¬   rÓ   rö   r   r|  rn  rm  rü   Úpointwise_read_writesÚclear_cacheÚcodegen.simdrƒ  Úcandidate_tilingsÚcache_clear)rV   ru  Úneed_clear_tiling_cacheÚ	fake_depsrƒ  s        rX   Úrefresh_dependenciesz"SchedulerNode.refresh_dependencies(  sŸ   € ô
 &0ñ 0
Ø×+Ñ+×1Ñ1ô0
ó &
ˆ	ð 	×ÑÜ×,Ñ,Ø—
‘
ðØ!Ÿ[™[òØ4=ñç‰i˜	Ó"ô	
ð 	×"Ñ"×.Ñ.¨tÔ4á"Ý4ð ×,Ñ,×8Ñ8Õ:ð #rZ   c                ó    — | j                   j                  |«      | _         | j                   j                  | _        | j	                  dd¬«       y )NFT©ru  r‰  )rn  Úreorder_iter_loopsÚsizesrm  r‹  )rV   Ú	new_orders     rX   Úapply_new_loop_orderz"SchedulerNode.apply_new_loop_orderD  sA   € Ø—Z‘Z×2Ñ2Øó
ˆŒ
ð —j‘j×&Ñ&ˆŒà×!Ñ!¨EÈ4Ð!ÕPrZ   c                óž   — | j                   j                  «       | _         | j                   j                  | _        | j	                  dd¬«       y )NTFr�  )rn  Úmerge_loopsr�  rm  r‹  r^   s    rX   r“  zSchedulerNode.merge_loopsL  s<   € Ø—Z‘Z×+Ñ+Ó-ˆŒ
Ø—j‘j×&Ñ&ˆŒð 	×!Ñ!¨DÈ%Ð!ÕPrZ   c                óŠ  — d }| j                   d   }t        |«      |j                  cxk(  r|j                  k(  rn n|j                  |«      }|rPt        xj
                  dz  c_        t        j                  d| j                  «       |«       | j                  |«       y t        j                  d| j                  «       «       y )Nr   r   z"Reorder loops for %s with order %szEDon't reordering %s because we can not decide the suitable loop order)
rm  rk   Únum_varsÚdecide_loop_order_to_matchr    Únum_loop_reorderingÚloop_ordering_logr?  rU   r‘  )rV   rò   ró   r�  Ú
self_sizess        rX   rô   z'SchedulerNode.reorder_loops_by_dep_pairX  sœ   € ð ˆ	Ø—[‘[ ‘^ˆ
Üˆz‹?˜h×/Ñ/ÔE°9×3EÑ3EÕEØ ×;Ñ;¸IÓFˆIáÜ×'Ò'¨1Ñ,Õ'Ü×#Ñ#Ø4°d·m±m³oÀyôð ×%Ñ% iÕ0ä×#Ñ#ØWØ—‘“õrZ   c                ó$  — | j                  «       }|› d| j                  d   › �|› d| j                  d   › �|› d| j                  › �g}| j                  j	                  «       D ]‚  }t        |t        «      rŒ|j                  }t        j                  j                  |«      }t        |t        j                  «      rŒZ|j                  |› dt        |j                  «      › �«       Œ„ t        | j                   t"        «      rR|j                  d|› d�«       |j                  t%        j&                  | j                   j)                  «       d	«      «       | j*                  €J ‚|j-                  | j/                  «       «       d
j1                  |«      S )Nz.group.device = r   z.group.iteration = r   z	.sizes = z
_layout = zclass z_loop_body:rI  rÊ   )rU   rª   rm  r¬   r|  ry   r)   r]   rD   r|   rÔ  r   r×  r¡  ri   rg   rn  r1   rM  rl   rp   rL   r#  rÞ   Újoin)rV   r]   Úlinesrþ   rX  r¿   s         rX   rÔ   zSchedulerNode.debug_str_extral  sK  € Ø�}‰}‹ˆàˆfÐ$ T§Z¡Z°¡] OÐ4ØˆfÐ'¨¯
©
°1© Ð7Øˆf�I˜dŸk™k˜]Ð+ð
ˆð
 ×#Ñ#×4Ñ4Ó6ò 	OˆCÜ˜c¤7Õ+ØŸ8™8�Ü—g‘g×(Ñ(¨Ó2�Ü! #¤r×'9Ñ'9Õ:Ø—L‘L H :¨Z¼ÀÇ
Á
Ó8KÐ7LÐ!MÕNð	Oô �d—j‘j¤(Ô+Ø�L‰L˜6 $  {Ð3Ô4Ø�L‰LœŸ™¨¯©×)=Ñ)=Ó)?ÀÓHÔIà�y‰yÐ$Ð$Ð$Ø�‰�T×/Ñ/Ó1Ô2à�y‰y˜ÓÐrZ   c                ó   — | j                   S rT   )rm  r^   s    rX   rà  zSchedulerNode.get_ranges‚  ó   € Ø�{‰{ÐrZ   c                óê   — t        | j                  t        j                  t        j                  f«      sJ dt        | j                  «      ›�«       ‚t        | j                  j                  «       «      S ©Nrè  )ry   rL   r   r,   rv  re   rŸ   rê   r^   s    rX   rd  zSchedulerNode.is_reduction…  s[   € Ü˜$Ÿ)™)¤b×&7Ñ&7¼×9JÑ9JÐ%KÔLð 	
ØŒt�D—I‘I‹Ð Ð!ó	
ÐLô �D—I‘I×0Ñ0Ó2Ó3Ð3rZ   c                óL  — t        | j                  t        j                  t        j                  f«      sJ dt        | j                  «      ›�«       ‚t        | j                  t        j                  «      xr. t        | j                  j                  t        j                  «      S r   )ry   rL   r   r,   rv  re   rà   Ú	SplitScanr^   s    rX   rg  zSchedulerNode.is_split_scan‹  sy   € Ü˜$Ÿ)™)¤b×&7Ñ&7¼×9JÑ9JÐ%KÔLð 	
ØŒt�D—I‘I‹Ð Ð!ó	
ÐLô ˜$Ÿ)™)¤R×%6Ñ%6Ó7ò 
¼JØ�I‰I�N‰NœBŸL™Ló=
ð 	
rZ   c                óJ   — t        | j                  t        j                  «      S rT   ©ry   rL   r   rv  r^   s    rX   ri  zSchedulerNode.is_template“  s   € Ü˜$Ÿ)™)¤R×%6Ñ%6Ó7Ð7rZ   c                óf   — t        | j                  t        j                  «      r| j                  S d S rT   r¤  r^   s    rX   r  zSchedulerNode.get_template_node–  s$   € Ü& t§y¡y´"×2CÑ2CÔDˆt�y‰yÐNÈ$ÐNrZ   c                óf   — | j                  «        | j                  «        | j                  |«       y rT   )r•  r  r…  )rV   Ú
index_varss     rX   ÚrunzSchedulerNode.run™  s#   € Ø×"Ñ"Ô$Ø�‰ŒØ�‰�ZÕ rZ   c                ó&  — | j                   }t        t        t        |«      «      t        t        t        |«      «      k(  sJ ‚t	        t        t        j                  j                  |«      t        j                  j                  |«      «      «      }|S rT   )	rm  r»  Úmaprk   ÚdictÚzipr  r  Úfrom_iterable)rV   r§  r�  Ú
var_rangess       rX   Úranges_from_index_varsz$SchedulerNode.ranges_from_index_varsž  sp   € ð —‘ˆÜ”3”s˜E“?Ó#¤s¬3¬s°JÓ+?Ó'@Ò@Ð@Ð@ÜÜÜ—‘×-Ñ-¨jÓ9Ü—‘×-Ñ-¨eÓ4óó
ˆ
ð ÐrZ   c                ó–  — | j                  |«      }	 t        j                  t        t        j                  «       |«      «      5  t        j
                  j                  | «      5   | j                  |Ž  d d d «       d d d «       y # 1 sw Y   ŒxY w# 1 sw Y   y xY w# t        $ r" t        j                  d| j                  «       ‚ w xY w)NzError in codegen for %s)r¯  rD   Úset_ops_handlerr6   Úget_ops_handlerr€   rû  rn  rÕ   rÖ   ÚfatalrL   )rV   r§  r®  s      rX   r…  zSchedulerNode.codegen«  s¨   € Ø×0Ñ0°Ó<ˆ
ð	ä×!Ñ!Ô"2´1×3DÑ3DÓ3FÈ
Ó"SÓTñ(ä—‘×)Ñ)¨$Ó/ñ(ð �—
‘
˜JÑ'÷	(÷ (÷ (ñ (ú÷ (ð (ûô
 ò 	Ü�I‰IÐ/°·±Ô;Øð	úsA   “1B Á BÁ$BÁ4BÁ<B ÂB	Â
BÂBÂB ÂB Â+Cc                óÞ   — |r| j                   nt        | j                   «      \  }}t        j                  | j                  |t
        j                  j                  gt        |«      z  g¬«      S )z\
        Get the memory dependencies in either the pointwise or the reduction axes.
        )Úhidden_args)	rm  Úreversedr   r|  rn  ÚsympyÚSÚZerork   )rV   Ú	pointwiseÚ
keep_sizesÚignore_sizess       rX   Ú"pointwise_or_reduction_read_writesz0SchedulerNode.pointwise_or_reduction_read_writes·  sT   € ñ 3< 4§;¢;ÄÈ$Ï+É+ÓAVÑ ˆ
�LÜ×/Ñ/Ø�J‰J˜
´%·'±'·,±,°Ä#ÀlÓBSÑ1SÐ0Tô
ð 	
rZ   c                ó&   — | j                  d¬«      S )zH
        Get the memory dependencies in the non-reduction axes.
        T©rº  ©r½  r^   s    rX   r„  z#SchedulerNode.pointwise_read_writesÂ  s   € ð
 ×6Ñ6ÀÐ6ÓFÐFrZ   c                ó&   — | j                  d¬«      S )zD
        Get the memory dependencies in the reduction axes.
        Fr¿  rÀ  r^   s    rX   Úreduction_read_writesz#SchedulerNode.reduction_read_writesÉ  s   € ð
 ×6Ñ6ÀÐ6ÓGÐGrZ   c                óò  — | j                  «       ryt        d„ | j                  «       D «       «      ryt        | j                  j
                  «      dk(  r£t        |t        j                  «      r‰t        t        | j                  j
                  «      «      }t        |t        j                  «      sJ dt        |«      ›�«       ‚|j                  |j                  k(  xr |j                  |j                  k(  S y)NFc              3  ó<   K  — | ]  }|j                  «       –— Œ y ­wrT   )rh   rG  s     rX   r  z,SchedulerNode.can_inplace.<locals>.<genexpr>Ó  s   è ø€ Ò? Sˆs�‰× Ñ?ùrB  r   ztype(write_dep)=)ri  r  r»   rk   r¬   rÒ   ry   r   r'   r  Úiterre   ÚindexÚsize)rV   rp  Ú	write_deps      rX   rq  zSchedulerNode.can_inplaceÐ  sÃ   € Ø×ÑÔØÜÑ?¨D×,<Ñ,<Ó,>Ô?Ô?ØÜˆt×Ñ×&Ñ&Ó'¨1Ò,´Ø”l×,Ñ,ô2
ô œT $×"2Ñ"2×"9Ñ"9Ó:Ó;ˆIÜ˜i¬×)?Ñ)?Ô@ÐWÐEUÄTÈ)Ã_ÐDVÐBWÓWÐ@Ø—>‘> Y§_¡_Ñ4ÒX¸¿¹È)Ï.É.Ñ9XÐXØrZ   c                ó  — t        t           «       }t        | j                  t        «      rà| j                  j                  «       D ]Ã  }|j                  dk(  sŒ|j                  dk(  sŒ#d|j                  v r|j                  d   dk(  s,t        |j                  «      dk(  sŒ\|j                  d   dk(  sŒo|j                  d|j                  v r|j                  d   n(t        |j                  «      dk\  r|j                  d	   nd
«       ŒÅ |S )NÚcall_methodÚstoreÚmodeÚ
atomic_addé   rH  r]   é   r   rÛ   )r   r™   ry   rn  r1   rC  rW   r¢  r³   rk   ru   r!  )rV   Úbuffers_store_as_atomic_addrL   s      rX   Ú_get_atomic_add_buffersz%SchedulerNode._get_atomic_add_buffersÝ  sÚ   € ä&0´¡oÓ&7Ð#Ü�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õðð +Ð*rZ   )rK   rJ   rL   z+Union[ir.ComputedBuffer, ir.TemplateBuffer]r˜   r�   ©NN)rs  z*Optional[tuple[dict[Any, Any], list[Any]]]rt  zOptional[Callable[..., Any]]r˜   r�   )ru  rŸ   r‰  rŸ   r˜   r�   )r�  zSequence[int]r˜   r�   rœ   r%  r—   )r˜   úSequence[Sequence[sympy.Expr]]rž   r3  )r§  úSequence[sympy.Expr]r˜   r�   )r§  rÓ  r˜   zdict[sympy.Expr, sympy.Expr])r§  rÓ  r˜   r�   r1  )rº  rŸ   r˜   r«   )r˜   r«   r0  r*  )rf   r¡   r¢   r£   r¶   rp  r  r‹  r‘  r“  rô   rÔ   rà  rd  rg  ri  r  r¨  r¯  r…  r½  r7   r„  rÂ  rq  rÑ  rh  ri  s   @rX   rM  rM  ñ  sk  ø… Ø,Ó,ØƒOðàðð :ðð 
õ	ð RVØBFðà$Nðð $@ðð 
ó	ðD RVØBFð
à$Nð
ð $@ð
ð 
ó	
ð;Øð;Ø8<ð;à	ó;ó8Qó
QðØ!ðØ.7ðà	óó( ó,ó4ó
ó8óOó!ð
Ø8ðà	%óó
ð !%ð	
Øð	
à	 ó	
ð òGó ðGð òHó ðHóð ò+ó ô+rZ   rM  c           	     ón  ‡ — ‰ j                   }‰ j                  t        j                  j	                  |D �cg c]  }|j
                  ‘Œ c}«      «       t        ˆ fd„t        j                  |D �cg c]  }|j                  ‘Œ c}Ž D «       «      ‰ j
                  j                  z
  ‰ _        y c c}w c c}w )Nc              3  óZ   •K  — | ]"  }|j                   ‰j                  «       vr|–— Œ$ y ­wrT   ©r]   rH  )r  rþ   Úgroup_snodes     €rX   r  z2refresh_group_node_dependencies.<locals>.<genexpr>û  s.   øè ø€ ò 
àØ�x‰x˜{×;Ñ;Ó=Ñ=ô ñ
ùó   ƒ(+)
rË  rö   r   Ú
ReadWritesÚ
merge_listr¬   r   Úunionr­   rÒ   )rØ  rË  r“  s   `  rX   Úrefresh_group_node_dependenciesrÝ  ò  sž   ø€ ð ×Ñ€FØ×ÑÜ×Ñ×*Ñ*À6Ö+J¸a¨A¯M«MÒ+JÓKôô
 	ó 
ä!×'Ñ'ÈÖ)OÀ1¨!×*>Ó*>Ò)OÐPô
ó 	
ð
 ×
!Ñ
!×
(Ñ
(ñ	)ð Õ"ùò ,Kùò *Ps   ¶B-Á0B2rJ   c                óè  — t        | t        t        f«      sJ ‚|| _        || _        d | _        t        j                  |D �cg c]  }|j                  €Œ|j                  ‘Œ c}Ž | _        t        | «       t        d„ | j                  D «       «      | _        t        d„ | j                  D «       «      | _        | j                  «       D �ci c]  }|j                  «       |“Œ c}| _        y c c}w c c}w )Nc              3  ó4   K  — | ]  }|j                   –— Œ y ­wrT   ©r®   ©r  r“  s     rX   r  z"init_group_node.<locals>.<genexpr>  ó   è ø€ ÒH° §¥ÑHùr  c              3  ó4   K  — | ]  }|j                   –— Œ y ­wrT   )r¯   rá  s     rX   r  z"init_group_node.<locals>.<genexpr>  râ  r  )ry   râ  ÚGroupedSchedulerNoderË  rK   rL   r   rÜ  r¸   rÝ  rÙ  r®   r  r¯   r»   rU   r½   )rØ  rK   rË  r“  r¿   s        rX   Úinit_group_noderå    sÔ   € ô
 �kÔ$6Ô8LÐ#MÔNÐNÐNØ€KÔØ%€KÔØ€KÔÜ&×,Ñ,Ø%Ö	A˜!¨¯©Ñ)@ˆ!�+‹+Ò	Að€KÔô $ KÔ0äÑH°[×5GÑ5GÔHÓH€KÔÜÑH°[×5GÑ5GÔHÓH€KÔà'2×'>Ñ'>Ó'@ö#Ø #ˆ�‰‹˜Ñò#€KÕùò 
Bùò#s   ÁC*ÁC*Ã	C/c                  ót  ‡ — e Zd ZU dZded<   e	 	 	 	 	 	 dd„«       Z	 	 	 	 	 	 dd„Zdˆ fd„Ze	dd„«       Z
dd„Ze	d d	„«       Zd!d
„Zdd„Zdd„Z	 	 	 	 	 	 d"ˆ fd„Ze	d d„«       Ze	d d„«       Zd#d„Zdd„Ze	d$d„«       Ze	d$d„«       Ze	d$d„«       Ze	d%d„«       Zd&d„Ze	d$d„«       Zd'd„Zd(d„Zd)d„Zdd„Zˆ xZS )*râ  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.
    r4  rË  c           	     ó¸  — |j                   |j                   u sJ ‚t        |t        t        f«      sJ ‚|j	                  «       �r­t        |t
        «      �rœt        |j                  t        «      sJ ‚t        |j                  j                  «      dk(  sJ ‚t        t        t        |j                  j                  «      «      t        «      sJ ‚t        t        |j                  j                  «      «      j                  }|j                  «       D �cg c]  }|j	                  «       sŒ|‘Œ }}t        |«      dk(  sJ ‚|d   }t        |j                  j                  «      dk(  sJ ‚t        t        |j                  j                  «      «      }t        |t         «      sJ ‚t#        t!        ||j$                  |j&                  |j(                  |j*                  «      g«      |j                  _
        nt        |t        t        f«      sJ ‚t-        t/        j0                  |j                  «       |j                  «       «      «      } | |j                   |«      S c c}w )Nr   r   )rK   ry   rM  râ  ri  rß  rL   r/   rk   r¬   rÒ   r  rÅ  r(   r]   rC  r'   r   rÆ  Ú	var_namesrÇ  rÌ  r‘   r  r  )	r
  r8  r9  r]   rL   Útemplate_nodesr!  Úwriter  s	            rX   ÚfusezFusedSchedulerNode.fuse#  sÛ  € ð �‰ %§/¡/Ñ1Ð1Ð1Ü˜%¤-Ô1CÐ!DÔEÐEÐEØ×ÑÕ¤:¨eÔ5NÕ#Oô ˜eŸj™j¬+Ô6Ð6Ð6Ü�u×(Ñ(×/Ñ/Ó0°AÒ5Ð5Ð5Üœd¤4¨×(9Ñ(9×(@Ñ(@Ó#AÓBÄGÔLÐLÐLÜœ˜U×.Ñ.×5Ñ5Ó6Ó7×<Ñ<ˆDØ/4¯©Ó/@ÖW tÀD×DTÑDTÕDVšdÐWˆNÐWÜ�~Ó&¨!Ò+Ð+Ð+Ø*¨1Ñ-ˆMÜ�}×0Ñ0×7Ñ7Ó8¸AÒ=Ð=Ð=Üœ˜m×7Ñ7×>Ñ>Ó?Ó@ˆEÜ˜e¤YÔ/Ð/Ð/Ü'1äØ˜eŸk™k¨5¯?©?¸E¿J¹JÈÏ
É
óðó(ˆE×ÑÕ$ô ˜e¤mÔ5GÐ%HÔIÐIÐIÜ”Y—_‘_ U§_¡_Ó%6¸¿¹Ó8IÓJÓKˆÙ�5—?‘? EÓ*Ð*ùò! Xs   ÄIÄ'Ic                óÔ  — | j                  «       ry d }| j                  D ]`  }t        |t        «      sJ ‚|�;t	        |«      t	        |j
                  d   «      k7  rt        j                  d«        y |j
                  d   }Œb d }|€J ‚t        |«      |j                  cxk(  r|j                  k(  rn n|j                  |«      }|s%t        j                  d| j                  «       «       y t        xj                  dz  c_        t        j                  d| j                  «       |«       | j                  D ]%  }t        |t        «      sJ ‚|j                  |«       Œ' t        | «       y )Nr   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 %s)ri  rË  ry   rM  Útuplerm  r˜  r?  rk   r•  r–  rU   r    r—  r‘  rÝ  )rV   rò   ró   r™  Úsnoder�  s         rX   rô   z,FusedSchedulerNode.reorder_loops_by_dep_pairE  sI  € ð ×ÑÔàØˆ
Ø—[‘[ò 	)ˆEÜ˜e¤]Ô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ô	
ð —[‘[ò 	2ˆEÜ˜e¤]Ô3Ð3Ð3Ø×&Ñ& yÕ1ð	2ô 	(¨Õ-rZ   c                ó†   •— t         ‰| �  |«       t        | ||«       g | _        t	        |d„ ¬«      j
                  | _        y )Nc                ó4   — t        | j                  «       «      S rT   )r›   rd  ©r“  s    rX   r´   z-FusedSchedulerNode.__init__.<locals>.<lambda>n  s   € ¬s°1·>±>Ó3CÓ/D€ rZ   rF  )r_  r¶   rå  rQ   r  rª   ©rV   rK   rË  rþ  s      €rX   r¶   zFusedSchedulerNode.__init__j  s8   ø€ Ü‰Ñ˜Ô#Ü˜˜i¨Ô0Ø%'ˆŒ
Ü˜Ñ%DÔE×KÑKˆ�
rZ   c                óz   — dj                  | j                  D �cg c]  }|j                  «       ‘Œ c}«      S c c}w ©NÚ_©r›  rË  rU   ©rV   r“  s     rX   rU   zFusedSchedulerNode.get_namep  ó)   € à�x‰x¨t¯{©{Ö;¨!˜Ÿ™�Ò;Ó<Ð<ùÒ;ó   š8c                ó<   — | j                   d   j                  «       S ©Nr   ©rË  rU   r^   s    rX   r?  z!FusedSchedulerNode.get_first_namet  ó   € Ø�{‰{˜1‰~×&Ñ&Ó(Ð(rZ   c                ó|   — t        j                  | j                  D �cg c]  }|j                  «       ‘Œ c}Ž S c c}w rT   ©r   rÜ  rË  rH  r÷  s     rX   rH  z#FusedSchedulerNode.get_buffer_namesw  ó.   € ä×ÑÀÇÁÖ!L¸1 !×"4Ñ"4Õ"6Ò!LÐMÐMùÒ!Ló   ž9c                ój   — g }| j                   D ]!  }|j                  |j                  «       «       Œ# |S rT   ©rË  r#  r»   ©rV   rn   rL   s      rX   r»   zFusedSchedulerNode.get_outputs{  ó4   € Ø(*ˆØ—K‘Kò 	.ˆDØ�M‰M˜$×*Ñ*Ó,Õ-ð	.àˆrZ   c           
     ó~  — t        | j                  «      D ��cg c]+  \  }}| j                  «       › d|› d|j                  «       › �‘Œ- }}}| j                  d   j                  }|�|j                  | j                  «       «       t        j                  dj                  |«      j                  «       d«      S c c}}w )Nz.snodes[z] =
r   rÊ   rI  )r  rË  rU   rp   rL   r#  rÞ   rM  rl   r›  rØ   )rV   r  rL   rœ  s       rX   rÔ   z"FusedSchedulerNode.debug_str_extra�  s¦   € ô % T§[¡[Ó1÷
á��4ð �}‰}‹Ð˜x¨ s¨%°·±Ó0@Ð/AÒBð
ˆñ 
ð �{‰{˜1‰~×"Ñ"ˆØÐØ�L‰L˜×3Ñ3Ó5Ô6ä�‰˜tŸy™y¨Ó/×6Ñ6Ó8¸&ÓAÐAùó
s   ™0B9c                óh   — | j                   D �cg c]  }|j                  «       ‘Œ }}| › d|› �S c c}w )Nz
, snodes: )rË  rí   )rV   rL   Ú
snodes_strs      rX   rí   z"FusedSchedulerNode.debug_str_shortŒ  s9   € Ø9=¿¹ÖE°�d×*Ñ*Õ,ÐEˆ
ÐEØ��z * Ð.Ð.ùò Fs   �/c                óÖ   •— t         ‰| �  ||«       t        t           «       }t	        | j
                  «      D ]/  }|j                  ||«       |j                  |j                  «       Œ1 y rT   )r_  r  r   r™   r¶  rË  Úupdater¹   )rV   r  r  rL   rþ  s       €rX   r  z!FusedSchedulerNode.set_last_usage�  sa   ø€ ô
 	‰ÑÐ2Ð4FÔGô )¬™oÓ/ÐÜ˜TŸ[™[Ó)ò 	8ˆDØ×ÑÐ 3Ð5GÔHØ×&Ñ& t§¡Õ7ñ	8rZ   c                ó|   — t        j                  | j                  D �cg c]  }|j                  «       ‘Œ c}Ž S c c}w rT   )r   rÜ  rË  r  r÷  s     rX   r  z$FusedSchedulerNode.used_buffer_names�  s.   € ä×ÑÀÇÁÖ!M¸A !×"5Ñ"5Õ"7Ò!MÐNÐNùÒ!Mr  c                ó|   — t        j                  | j                  D �cg c]  }|j                  «       ‘Œ c}Ž S c c}w rT   )r   rÜ  rË  r  r÷  s     rX   r  z/FusedSchedulerNode.used_or_aliased_buffer_names¡  s3   € ä×ÑØ8<¿¹ÖD°1ˆa×,Ñ,Õ.ÒDð
ð 	
ùÚDr  c                ó   — | j                   S rT   rÏ  r^   s    rX   rC  zFusedSchedulerNode.get_nodes§  rž  rZ   c                óT   — t        | «      j                  › d| j                  «       › d�S )Nz(nodes=rÂ   rÃ   r^   s    rX   rÄ   zFusedSchedulerNode.__repr__ª  s'   € Ü�t“*×%Ñ%Ð& g¨d¯m©m«oÐ->¸aÐ@Ð@rZ   c                ó:   — t        d„ | j                  D «       «      S )Nc              3  ó<   K  — | ]  }|j                  «       –— Œ y ­wrT   )rd  rá  s     rX   r  z2FusedSchedulerNode.is_reduction.<locals>.<genexpr>¯  s   è ø€ Ò9¨�1—>‘>×#Ñ9ùrB  ©r  rË  r^   s    rX   rd  zFusedSchedulerNode.is_reduction­  s   € äÑ9¨T¯[©[Ô9Ó9Ð9rZ   c                ó:   — t        d„ | j                  D «       «      S )Nc              3  ó<   K  — | ]  }|j                  «       –— Œ y ­wrT   )rg  rá  s     rX   r  z3FusedSchedulerNode.is_split_scan.<locals>.<genexpr>³  s   è ø€ Ò:¨�1—?‘?×$Ñ:ùrB  r  r^   s    rX   rg  z FusedSchedulerNode.is_split_scan±  s   € äÑ:¨d¯k©kÔ:Ó:Ð:rZ   c                ó:   — t        d„ | j                  D «       «      S )Nc              3  ó<   K  — | ]  }|j                  «       –— Œ y ­wrT   r  rá  s     rX   r  z1FusedSchedulerNode.is_template.<locals>.<genexpr>·  s   è ø€ Ò8 q�1—=‘=—?Ñ8ùrB  r  r^   s    rX   ri  zFusedSchedulerNode.is_templateµ  s   € äÑ8¨D¯K©KÔ8Ó8Ð8rZ   c                ój   — | j                   D ]$  }|j                  «       sŒ|j                  «       c S  y rT   )rË  ri  r  ©rV   rL   s     rX   r  z$FusedSchedulerNode.get_template_node¹  s5   € à—K‘Kò 	0ˆDØ×ÑÕ!Ø×-Ñ-Ó/Ò/ð	0ð rZ   c                ó    — | j                   d   S rû  )rª   r^   s    rX   r[  zFusedSchedulerNode.get_deviceÀ  s   € Ø�z‰z˜!‰}ÐrZ   c                ó:   — t        d„ | j                  D «       «      S )Nc              3  ó<   K  — | ]  }|j                  «       –— Œ y ­wrT   )r  rá  s     rX   r  z>FusedSchedulerNode.has_aliasing_or_mutation.<locals>.<genexpr>Å  s   è ø€ ÒE°A�1×-Ñ-×/ÑEùrB  r  r^   s    rX   r  z+FusedSchedulerNode.has_aliasing_or_mutationÃ  s   € äÑE¸¿¹ÔEÓEÐErZ   c                ó   — t         ‚rT   ©ÚNotImplementedErrorrø   s     rX   rú   z'FusedSchedulerNode.update_mutated_namesÉ  ó   € Ü!Ð!rZ   c                ó   — t         ‚rT   r  )rV   r]   s     rX   rÿ   zFusedSchedulerNode.add_fake_depÌ  r  rZ   c                ó   — t         ‚rT   r  ro  s     rX   rq  zFusedSchedulerNode.can_inplaceÏ  r  rZ   c                óP  — | j                  «       }dj                  d„ | j                  D «       «      }t        «       }|j	                  |› dt        | «      j                  › d|› d|› dt        | j                  j                  «      › d|› dt        | j                  «      › d|› d	t        | j                  j                  | j                  z
  «      › d|› d
�«       |j                  «       5  | j                  «       D ]!  }|j	                  |j                  «       «       Œ# 	 ddd«       |j                  d«       	 |j	                  | j!                  «       «       |j)                  «       j+                  «       S # 1 sw Y   ŒXxY w# t"        $ r t$        j'                  dd¬«       Y ŒLw xY w)rÆ   rb   c              3  óF   K  — | ]  }t        |«      j                  –— Œ y ­wrT   )re   rf   rN  s     rX   r  z/FusedSchedulerNode.debug_str.<locals>.<genexpr>Õ  s   è ø€ ÒF°Q¤ Q£× 0Õ 0ÑFùs   ‚!ra   rÇ   rÈ   rÉ   rÊ   rË   rÌ   z.outputs = [
            Nrc   rÍ   TrÎ   )rU   r›  rË  r=   rÐ   re   rf   ri   r¬   rÒ   r­   rÓ   rl   r»   rp   rd   rÔ   rÕ   rÖ   r×   rm   rØ   )rV   r]   Únode_typestrr¿   rÙ   s        rX   rp   zFusedSchedulerNode.debug_strÒ  s…  € à�}‰}‹ˆØ—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   Ã)5E6Ä9F Å6E?Æ F%Æ$F%©r8  rG   r9  rG   r˜   râ  r%  ©rK   rJ   rË  r4  r˜   r�   r—   r*  ©r˜   zlist[SchedulerBuffer]r(  r-  rž   r3  )r˜   útorch.devicer&  )r]   r&   r˜   r�   r0  ) rf   r¡   r¢   Ú__doc__r£   Úclassmethodrë  rô   r¶   r7   rU   r?  rH  r»   rÔ   rí   r  r  r  rC  rÄ   rd  rg  ri  r  r[  r  rú   rÿ   rq  rp   rh  ri  s   @rX   râ  râ    so  ø… ñð $Ó#àð+Ø%ð+Ø.?ð+à	ò+ó ð+ðB#.Ø!ð#.Ø.7ð#.à	ó#.õJLð ò=ó ð=ó)ð òNó ðNóó	Bó/ð8Ø#2ð8ØHVð8à	õ8ð òOó ðOð ò
ó ð
ó
óAð ò:ó ð:ð ò;ó ð;ð ò9ó ð9ð òó ðóð òFó ðFó
"ó"ó"÷*rZ   râ  c                  óN  ‡ — e Zd ZU dZ	 	 	 	 dd„Z	 	 	 	 dd„Zedd„«       Ze	 	 	 	 	 	 dd„«       Z	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 dˆ fd„Z	e	 	 	 	 dd„«       Z
e	 	 	 	 dd„«       ZeZd	ed
<   e	 	 	 	 dd„«       Ze	 	 	 	 dd„«       Zdd„Zdd„Zdd„Zdd„Zd d„Zd!d„Z	 	 	 	 d"d„Zˆ xZS )#ÚForeachKernelSchedulerNodezš
    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                ó¤   — |j                  «       D ]=  }|j                  «       | j                  v sŒ | j                  |j                  «          c S  y rT   )r»   rU   Úread_to_node)rV   Úproducerr¿   s      rX   Úget_consumer_subnode_forz3ForeachKernelSchedulerNode.get_consumer_subnode_foró  sL   € ð ×'Ñ'Ó)ò 	9ˆCØ�|‰|‹~ ×!2Ñ!2Ò2Ø×(Ñ(¨¯©«Ñ8Ò8ð	9ð rZ   c                ó¢  — t        t           «       }|j                  j                  D ]ƒ  }|j                  | j
                  j                  vrŒ&| j
                  j                  |j                     j                  «       }|| j                  v sŒf|j                  | j                  |   «       Œ… t        |«      dk(  rt        t        |«      «      S y ©Nr   )r   rG   r¬   rÓ   r]   rK   rƒ   rY   Úname_to_noder!  rk   r  rÅ  )rV   ÚconsumerÚ	producersÚrdÚ	node_names        rX   Úget_producer_subnode_forz3ForeachKernelSchedulerNode.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×-Ñ-Ò-Ø—‘˜d×/Ñ/°	Ñ:Õ;ð	<ô ˆy‹>˜QÒÜœ˜Y›Ó(Ð(àrZ   c                óœ  ‡— t        ‰|«      }‰j                  «       r¯|j                  «       rŸt        j                  t        ‰«      Št        j                  t        |«      }t        ‰j                  «      t        |j                  «      k(  }|s |d«       |xr2 t        ˆfd„t        ‰j                  |j                  «      D «       «      S |j                  «       rk‰j                  «       r	 |d«       yt        j                  t        |«      }|j                  ‰«      }|�|j                  j                  ‰|«      S  |d«       y‰j                  «       rk|j                  «       r	 |d«       yt        j                  t        ‰«      Š‰j                  |«      }|�‰j                  j                  ||«      S  |d«       yt        d«      ‚)	Nzforeach do not have same lengthc              3  ó\   •K  — | ]#  \  }}‰j                   j                  ||«      –— Œ% y ­wrT   )rK   Úcan_fuse)r  ÚlÚrr.  s      €rX   r  z6ForeachKernelSchedulerNode.can_fuse.<locals>.<genexpr>  s0   øè ø€ ò )á�A�qð ×"Ñ"×+Ñ+¨A¨q×1ñ)ùs   ƒ),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)r7  rm  ÚtypingÚcastr+  rk   rË  rQ  r¬  rd  r/  rK   r:  r7  ÚAssertionError)r
  r.  r3  ÚwhyÚforeach_matchÚconsumer_subnodeÚproducer_subnodes    `     rX   r:  z#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ÀXÓNÐNáÐGÔHØäØfó
ð 	
rZ   c                ó
  — |j                  «       s|j                  «       sJ ‚|j                  «       r3t        j                  t        |«      }|j                  }|j
                  }n2t        j                  t        |«      }|j                  }|j
                  }d }d }|j                  «       rŒ|j                  «       r|t        j                  t        |«      }t        j                  t        |«      }t        |j                  |j                  «      D ��cg c]  \  }}t        j                  ||«      ‘Œ }	}}�n/|j                  «       r‚t        j                  t        |«      }|j                  |«      }
g }	|}d }|j                  D ]A  }||
u r*t        j                  ||«      }|}|	j                  |«       Œ1|	j                  |«       ŒC n�|j                  «       r‚t        j                  t        |«      }|j                  |«      }g }	|}d }|j                  D ]A  }||u r*t        j                  ||«      }|}|	j                  |«       Œ1|	j                  |«       ŒC nt        d«      ‚ | |j                  |	||||¬«      S c c}}w )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)rm  r=  r>  r+  rE  rH  r¬  rË  râ  rë  r7  r¡  r/  r?  rK   )r
  r.  r3  rE  rH  rF  rG  r;  r<  Úfused_nodesrC  rL   Únew_noderB  s                 rX   rë  zForeachKernelSchedulerNode.fuse>  sZ  € ð ×"Ñ"Ô$¨×(;Ñ(;Ô(=Ð=Ð=Ø×ÑÔ Ü—{‘{Ô#=¸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�qô #×'Ñ'¨¨1Õ-ðˆKó ð × Ñ Ô"Ü—{‘{Ô#=¸xÓHˆHØ'×@Ñ@ÀÓJÐØˆKØ"ˆKØˆKØ Ÿ™ò -�ØÐ+Ñ+Ü1×6Ñ6°t¸XÓ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   Ä I?c                ó@  •‡ — i ‰ _         i ‰ _        |�|€qt        ‰‰ �  ||«       |D ]Z  }|j                  j
                  D ]  }|‰ j                   |j                  <   Œ |j                  «       D ]  }	|‰ j                  |	<   Œ Œ\ �n¬|‰ _        |‰ _	        d ‰ _
        g ‰ _        ‰ j                  t        j                  j                  |j                  |j                  g«      «       t!        ˆ fd„t!        j"                  |j$                  |j$                  «      D «       «      ‰ j                  j&                  z
  ‰ _        t)        |j*                  |j*                  g«      ‰ _        t-        |j.                  |j.                  g«      ‰ _        |j1                  «       rt3        |t4        «      sJ ‚||}}
nt3        |t4        «      sJ ‚||}}
|
j6                  ‰ _        ‰ j6                  j9                  |j6                  «       |
j                  ‰ _        |j                  «       D ]  }	|‰ j                  |	<   Œ |‰ _        |d   j=                  «       }|sJ ‚|t?        j@                  d«      fff‰ _!        t!        tD        jF                  jH                     «       ‰ _%        |‰ _&        y )Nc              3  óZ   •K  — | ]"  }|j                   ‰j                  «       vr|–— Œ$ y ­wrT   r×  r(  s     €rX   r  z6ForeachKernelSchedulerNode.__init__.<locals>.<genexpr>¡  s0   øè ø€ ò àð —x‘x t×'<Ñ'<Ó'>Ñ>ô	 ñùrÙ  r   Úcombo_kernel)'r-  r2  r_  r¶   r¬   rÓ   r]   rD  rK   rË  rL   rQ   rö   r   rÚ  rÛ  r   rÜ  r­   rÒ   rÙ  r®   r  r¯   rm  ry   r+  r¸   r
  rE  r[  r·  ÚExprrª   rã   ÚfxÚNoder©  rH  )rV   rK   rË  rE  rF  rG  rH  rL   r‘  r]   Úforeach_nodeÚ
other_noder`  rþ  s   `            €rX   r¶   z#ForeachKernelSchedulerNode.__init__  sq  ù€ ð ˆÔØˆÔàÐ +Ð"5Ü‰GÑ˜Y¨Ô/àò 3�Ø ×,Ñ,×2Ñ2ò 8�DØ37�D×%Ñ% d§i¡iÒ0ð8ð !×4Ñ4Ó6ò 3�DØ.2�D×%Ñ% dÒ+ñ3ò	3ð 'ˆ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Ø+6¸˜j‘ä! +Ô/IÔJÐJÐJØ+6¸˜j�à)×3Ñ3ˆDŒNØ�N‰N×!Ñ! *×"6Ñ"6Ô7à ,× 9Ñ 9ˆDÔØ"×6Ñ6Ó8ò 5�Ø*4�×!Ñ! $Ò'ð5ð *CˆÔ&Ø˜‘×%Ñ%Ó'ˆÙˆˆvØ¤§
¡
¨>Ó :Ð<Ð>Ð?ˆŒ
Ü!¤%§(¡(§-¡-Ñ0Ó2ˆŒØ.ˆÕrZ   c           	     ó   — |D �cg c]  }t        |t        «      sŒ|‘Œ }}|rSt        j                  dt	        |«      |D �cg c])  }|j
                  €Œ|j
                  j                  «       ‘Œ+ c}«       |D �cg c]  }t        |t        t        f«      s|‘Œ }}|D �cg c]  }t        |t        «      sŒ|‘Œ }}|rt        j                  dt	        |«      «       |D �cg c]  }t        |t        «      rŒ|‘Œ }}|D �cg c]  }|j                  «       sŒ|‘Œ }}|r)t        j                  dt        t	        |«      g«      «       |D �cg c]	  }||vsŒ|‘Œ }}|S c c}w c c}w c c}w c c}w c c}w c c}w c c}w )Nz/ComboKernels: %d external nodes are filtered %sz+ComboKernels: %d foreach nodes are filteredz,ComboKernels: %d template nodes are filtered)ry   rß  rÖ   r?  rk   rL   r   r‹  r+  ri  r   )r
  r  r“  ÚexternrL   Úfiltered_nodesÚforeach_nodesré  s           rX   Úcombinable_nodesz+ForeachKernelSchedulerNode.combinable_nodesÃ  sy  € ð #ÖO˜¤j°Ô4MÕ&N’!ÐOˆÐOÙÜ�I‰IØAÜ�F“Ø5;ÖU¨T¸t¿y¹yÑ?T�—‘×&Ñ&Õ(ÒUôð ö
àÜ˜aÔ"8Ô:SÐ!TÔUò ð
ˆð 
ð &ö
Ø¬°AÔ7QÕ)RŠAð
ˆð 
ñ Ü�I‰IÐCÄSÈÓEWÔXà%ö
Ø¬Z¸Ô;UÕ-VŠAð
ˆð 
ð &4ÖG °q·}±}µš!ÐGˆÐGÙÜ�I‰IØ>ÜœC Ó/Ð0Ó1ôð &4ÖO °qÀÒ7Nš!ÐOˆÐOØÐùò7 Pùò
 Vùò
ùò

ùò

ùò Hùò PsL   …E›EÁE"ÁE"Á:E'ÂE,Â5E,Ã E1Ã6E1Ä E6ÄE6Å	E;ÅE;c           
     ó¸   — | j                  «       }g }d}|D ];  }|j                  t        dt        |«      |«      D �cg c]
  }||||z    ‘Œ c}«       Œ= |S c c}w )zS
        Returns a list of lists of nodes that are to be grouped together.
        é   r   )Ú_topological_sort_nodesr#  Úrangerk   )rK   Úsorted_nodesÚgrouped_nodesÚmax_num_nodesr  r  s         rX   Ú&_default_group_nodes_for_combo_kernelszAForeachKernelSchedulerNode._default_group_nodes_for_combo_kernelsä  sw   € ð !×8Ñ8Ó:ˆØˆØˆØ!ò 	ˆEØ× Ñ ô # 1¤c¨%£j°-Ó@öàð ˜!˜a -Ñ/Ò0òõð	ð Ðùòs   ½A
ú4Callable[[Scheduler], list[list[BaseSchedulerNode]]]Ú!group_algorithm_for_combo_kernelsc                ó   — | t         _        y rT   ©r+  ra  )Úcustom_group_algorithms    rX   Ú%set_group_algorithm_for_combo_kernelsz@ForeachKernelSchedulerNode.set_group_algorithm_for_combo_kernelsü  s   € ð
 #ô 	#ÕDrZ   c                ó,   — t         j                  | «      S rT   rc  ©rK   s    rX   Úgroup_nodes_for_combo_kernelsz8ForeachKernelSchedulerNode.group_nodes_for_combo_kernels  s   € ô *×KÑKÈIÓVÐVrZ   c                ó   — t         ‚rT   r  r^   s    rX   r  z#ForeachKernelSchedulerNode.mark_run
  r  rZ   c                ó   — t         ‚rT   r  r^   s    rX   r…  z"ForeachKernelSchedulerNode.codegen  r  rZ   c                 ó   — yre  r¦   r^   s    rX   rm  z%ForeachKernelSchedulerNode.is_foreach  r  rZ   c                ó,   — t        | j                  «      S )zeReturns a list of nodes which comprise the combo kernel.
        These nodes may be vertically fused.)r‘   rË  r^   s    rX   Úget_subkernel_nodesz.ForeachKernelSchedulerNode.get_subkernel_nodes  s   € ô �D—K‘KÓ Ð rZ   c                ót   — t        t        j                  j                  d„ | j                  D «       «      «      S )zqReturns all nodes contained in this kernel, unpacking fused nodes
        into their constituent scheduler nodes.c              3  ó<   K  — | ]  }|j                  «       –— Œ y ­wrT   )rC  rá  s     rX   r  z7ForeachKernelSchedulerNode.get_nodes.<locals>.<genexpr>  s   è ø€ Ò1UÀA°!·+±+·-Ñ1UùrB  )r‘   r  r  r­  rË  r^   s    rX   rC  z$ForeachKernelSchedulerNode.get_nodes  s(   € ô ”I—O‘O×1Ñ1Ñ1UÈÏÉÔ1UÓUÓVÐVrZ   c                ó<   — | j                   d   j                  «       S rû  )rË  r?  r^   s    rX   r?  z)ForeachKernelSchedulerNode.get_first_name  s   € Ø�{‰{˜1‰~×,Ñ,Ó.Ð.rZ   c                óŠ   — t        | || j                  j                  «       | j                  D ]  }|j	                  |«       Œ y rT   )r8  rK   rƒ   rË  r:  )rV   r9  rL   s      rX   r:  z/ForeachKernelSchedulerNode.prune_redundant_deps   s=   € ô 	˜dÐ$6¸¿¹×8RÑ8RÔSà—K‘Kò 	:ˆDØ×%Ñ%Ð&8Õ9ñ	:rZ   )r.  rG   r˜   rM   )r3  rG   r˜   rM   ©r.  rG   r3  rG   r˜   rŸ   )r.  rG   r3  rG   r˜   r+  )NNF)rK   rJ   rË  r4  rE  rŸ   rF  rM   rG  rM   rH  rŸ   r˜   r�   ©r  r4  r˜   r4  )rK   rJ   r˜   úlist[list[BaseSchedulerNode]])rd  r`  r˜   r�   rœ   rž   ©r˜   r4  r-  r—   r+  )rf   r¡   r¢   r(  r/  r7  r)  r:  rë  r¶   rW  r5  r_  ra  r£   re  rh  r  r…  rm  rm  rC  r?  r:  rh  ri  s   @rX   r+  r+  í  s®  ø… ñð
Ø)ðà	$óðØ)ðà	$óð& ò,
ó ð,
ð\ ð>
Ø(ð>
Ø4Eð>
à	#ò>
ó ð>
ðJ 48Ø37Ø %ðB/àðB/ð (ðB/ð $(ð	B/ð
 1ðB/ð 1ðB/ð ðB/ð 
õB/ðH ðØ+ðà	 òó ðð@ ðØðà	&òó ðð* 	/ð &ð (ó /ð ð
Ø Tð
à	ò
ó ð
ð ðWØðWà	&òWó ðWó
"ó"óó!ó
Wó
/ð:Ø">ð:à	÷:rZ   r+  c                  ó    ‡ — e Zd ZU dZded<   edd„«       Zdˆ fd„Zdd„Zdd„Z	e
dd„«       Zdd	„Ze
dd
„«       Zdd„Zdd„Zedd„«       Zˆ xZS )rä  aC  
    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.
    r4  rË  c                óæ   ‡— |d   j                   Št        ˆfd„|D «       «      sJ ‚ | ‰|«      }|D ]  }|‰j                  |j                  «       <   Œ! |‰j                  |j                  «       <   |S )Nr   c              3  ó:   •K  — | ]  }|j                   ‰u –— Œ y ­wrT   rg  )r  rL   rK   s     €rX   r  z.GroupedSchedulerNode.create.<locals>.<genexpr>8  s   øè ø€ ÒB°4�4—>‘> YÔ.ÑBùó   ƒ)rK   rQ  r9  rU   )r
  rË  Úgrouped_snoderî  rK   s       @rX   ÚcreatezGroupedSchedulerNode.create5  sy   ø€ à˜1‘I×'Ñ'ˆ	ÜÓB¸6ÔBÔBÐBÐBÙ˜I vÓ.ˆØò 	KˆEØ=JˆI×(Ñ(¨¯©Ó)9Ò:ð	KàANˆ	×$Ñ$ ]×%;Ñ%;Ó%=Ñ>ØÐrZ   c                ó>   •— t         ‰| �  |«       t        | ||«       y rT   )r_  r¶   rå  rò  s      €rX   r¶   zGroupedSchedulerNode.__init__?  s   ø€ Ü‰Ñ˜Ô#Ü˜˜i¨Õ0rZ   c                ó  — | j                   D ])  }|| j                  j                  |j                  «       <   Œ+ | j                  j                  | j                  «       = | j                  j	                  | j                   «      S )z�
        Do fusion among nodes within this GroupedSchedulerNode,
        and then unpack this GroupedSchedulerNode into regular nodes.
        )rË  rK   r9  rU   Ú
fuse_nodes)rV   rî  s     rX   ÚunpackzGroupedSchedulerNode.unpackC  se   € ð
 —[‘[ò 	HˆEØBGˆD�N‰N×-Ñ-¨e¯n©nÓ.>Ò?ð	Hà�N‰N×-Ñ-¨d¯m©m«oÐ>Ø�~‰~×(Ñ(¨¯©Ó5Ð5rZ   c                óŽ   — | j                  | j                  j                  |«      «       | j                  j	                  |«       y rT   )rö   r¬   rü   r­   r!  )rV   Úfake_deps     rX   rÿ   z!GroupedSchedulerNode.add_fake_depM  s5   € Ø×Ñ˜T×-Ñ-×7Ñ7¸ÓAÔBØ×Ñ×#Ñ# HÕ-rZ   c                óz   — dj                  | j                  D �cg c]  }|j                  «       ‘Œ c}«      S c c}w rô  rö  r÷  s     rX   rU   zGroupedSchedulerNode.get_nameQ  rø  rù  c                ó<   — | j                   d   j                  «       S rû  rü  r^   s    rX   r?  z#GroupedSchedulerNode.get_first_nameU  rý  rZ   c                ó|   — t        j                  | j                  D �cg c]  }|j                  «       ‘Œ c}Ž S c c}w rT   rÿ  r÷  s     rX   rH  z%GroupedSchedulerNode.get_buffer_namesX  r   r  c                ój   — g }| j                   D ]!  }|j                  |j                  «       «       Œ# |S rT   r  r  s      rX   r»   z GroupedSchedulerNode.get_outputs\  r  rZ   c                ó   — | j                   S rT   rÏ  r^   s    rX   rC  zGroupedSchedulerNode.get_nodesb  rž  rZ   c                 ó   — yr,  r¦   )r
  r.  r3  s      rX   r:  zGroupedSchedulerNode.can_fusee  s   € ð rZ   )rË  r4  r˜   rä  r%  ru  )r�  r&   r˜   r�   r—   r*  r&  r-  rr  )rf   r¡   r¢   r(  r£   r)  r{  r¶   r  rÿ   r7   rU   r?  rH  r»   rC  r:  rh  ri  s   @rX   rä  rä  )  s~   ø… ñð $Ó#àòó ðõ1ó6ó.ð ò=ó ð=ó)ð òNó ðNóóð òó ôrZ   rä  c           
     ó   ‡ ‡— t         j                  dˆˆ fd„«       }t        t        t	        t        ‰ d   «      «      «      «      }t        |«      dkD  r|D �cg c]  }‰ |   ‘Œ	 c}Š t        j                  r|j                  |¬«       |S c c}w )z�
    A heuristic to decide loop iteration orders.  This has not been well
    tuned and may be something we should autotune.
    c                ót  •— ‰|    dk(  s‰|   dk(  rt        ‰|    dk(  ‰|   dk(  «      S ‰D �cg c]  }t        ||    «      ‘Œ }}‰D �cg c]  }t        ||   «      ‘Œ }}t        d„ t        ||«      D «       «      }t        d„ t        ||«      D «       «      }||kD  ry||kD  ryt        || «      S c c}w c c}w )Nr   c              3  ó:   K  — | ]  \  }}|d k(  xs ||k  –— Œ y­wrí  r¦   ©r  Úsl_aÚsl_bs      rX   r  z5pick_loop_order.<locals>.index_cmp.<locals>.<genexpr>‚  ó)   è ø€ ò 
Ù)3¨¨tˆD�A‰IÒ$˜ ™Ó$ñ
ùó   ‚c              3  ó:   K  — | ]  \  }}|d k(  xs ||k  –— Œ y­wrí  r¦   r‹  s      rX   r  z5pick_loop_order.<locals>.index_cmp.<locals>.<genexpr>…  rŽ  r�  r›  )r8   Úabsr»  r¬  )	ÚaÚbÚslÚstride_len_aÚstride_len_bÚa_firstÚb_firstr�  Ústride_lengthss	          €€rX   Ú	index_cmpz"pick_loop_order.<locals>.index_cmpu  sÛ   ø€ à�‰8�qŠ=˜E !™H¨šMä�u˜Q‘x 1‘} e¨A¡h°!¡mÓ4Ð4ð .<Ö< rœ˜B˜q™E�
Ð<ˆÐ<Ø-;Ö< rœ˜B˜q™E�
Ð<ˆÐ<ô ñ 
Ü7:¸<ÈÓ7Vô
ó 
ˆô ñ 
Ü7:¸<ÈÓ7Vô
ó 
ˆð �WÒØØ�WÒØô �1�a‹yÐùò# =ùÚ<s   ®B0Á	B5r   rF  )r’  r›   r“  r›   r˜   r›   )	Ú	functoolsÚ
cmp_to_keyr‘   r¶  r[  rk   r   Úpick_loop_ordersÚsort)r™  r�  Úpriority_idxrš  ÚorderÚpis   ``    rX   Úpick_loop_orderr¢  k  s�   ù€ ô ×Ñõó ðô4 ”œ%¤ N°1Ñ$5Ó 6Ó7Ó8Ó9€EÜ
ˆ<Ó˜1Òà7CÖD°˜.¨Ó,ÒDˆÜ×ÒØ�
‰
�yˆ
Ô!Ø€Lùò Es   ÁBc                  óT   — e Zd ZU ded<   dZded<   dZded<   dd„Zdd„Zdd	„Zdd
„Z	y)ÚNodeUserú$Union[BaseSchedulerNode, OutputNode]rL   FrŸ   rq  Úis_weakc                óv   — t        | j                  j                  «       | j                  | j                  f«      S rT   )r\   rL   rU   rq  r¦  r^   s    rX   r_   zNodeUser.__hash__¢  s+   € Ü�T—Y‘Y×'Ñ'Ó)¨4×+;Ñ+;¸T¿\¹\ÐJÓKÐKrZ   c                óÔ   — t        |t        «      xrW | j                  «       |j                  «       k(  xr4 | j                  |j                  k(  xr | j                  |j                  k(  S rT   )ry   r¤  rU   rq  r¦  ©rV   Úothers     rX   Ú__eq__zNodeUser.__eq__¥  s[   € ä�uœhÓ'ò .Ø—‘“ 5§>¡>Ó#3Ñ3ò.à× Ñ  E×$5Ñ$5Ñ5ò.ð —‘ §¡Ñ-ð		
rZ   c                ó6   — | j                   j                  «       S rT   rr   r^   s    rX   rU   zNodeUser.get_name­  rs   rZ   c                óÄ   — | j                   |j                   u sJ ‚t        | j                   | j                  xr |j                  | j                  xr |j                  «      S rT   )rL   r¤  rq  r¦  r©  s     rX   r�   zNodeUser.merge°  sP   € Ø�y‰y˜EŸJ™JÑ&Ð&Ð&ÜØ�I‰IØ×ÑÒ2 ×!2Ñ!2Ø�L‰LÒ*˜UŸ]™]ó
ð 	
rZ   Nrš   )rª  Úobjectr˜   rŸ   r—   )rª  r¤  r˜   r¤  )
rf   r¡   r¢   r£   rq  r¦  r_   r«  rU   r�   r¦   rZ   rX   r¤  r¤  ™  s3   … à
.Ó.Ø€K�Óð €GˆTÓóLó
ó$ô
rZ   r¤  c                  óN  ‡ — e Zd ZU ded<   dCd„ZdCˆ fd„ZdDd„ZedEd„«       Zej                  dFd„«       ZdGd„Z
dHd	„ZdId
„ZdGd„ZdGd„ZdGd„Z	 	 	 	 dJd„ZdKd„ZdLd„ZdGd„ZdGd„ZdJd„ZdGd„Z	 	 	 	 dMd„Z	 	 	 	 	 	 dNd„Z	 	 	 	 	 	 dOd„ZdGd„ZdPd„Z	 	 	 	 	 	 dQd„ZdRd„Z	 	 	 	 dJd„ZdSdTd„ZdUd„Z 	 	 	 	 dVd„Z!	 	 	 	 	 	 dWd „Z"	 	 	 	 	 	 dWd!„Z#	 	 	 	 	 	 dWd"„Z$	 	 	 	 	 	 	 	 dXd#„Z%	 	 	 	 	 	 dYd$„Z&dZd%„Z'	 	 	 	 	 	 	 	 d[d&„Z(dWd'„Z)	 	 	 	 	 	 dWd(„Z*	 	 	 	 	 	 	 	 d\d)„Z+d]d*„Z,d^d+„Z-	 	 	 	 	 	 dYd,„Z.	 	 	 	 d_d-„Z/	 	 	 	 d`d.„Z0dGd/„Z1dGd0„Z2dGd1„Z3dad2„Z4dbd3„Z5dcd4„Z6ddd5„Z7	 	 	 	 	 	 ded6„Z8dZd7„Z9	 	 dfd8„Z:	 	 	 	 	 	 dgd9„Z;	 	 dhd:„Z<dGd;„Z=	 	 	 	 	 	 did<„Z>dGd=„Z?dUd>„Z@	 	 	 	 djd?„ZAdkd@„ZBdldA„ZCdGdB„ZDˆ xZES )mrJ   zdict[Dep, int]Ú_Scheduler__dep_size_hint_cachec                óf   — t        d«      5  | j                  |«       d d d «       y # 1 sw Y   y xY w)NzScheduler.__init__)r   Ú_init©rV   r  s     rX   r¶   zScheduler.__init__¿  s,   € ÜÐ.Ó/ñ 	Ø�J‰J�uÔ÷	÷ 	ñ 	ús   Œ'§0c           
     ó¦  •‡ — t         ‰‰ �  «        i ‰ _        ‰ t        j                  _        i ‰ _        t        t        «      ‰ _	        t        j                  «       ‰ _        t        t           «       ‰ _        t        g t        j                  j                   j#                  «       ¢t        j                  j$                  j#                  «       ¢t        j                  j&                  j#                  «       ¢«      ‰ _        |D �cg c]  }‰ j+                  |«      ‘Œ c}‰ _        ‰ j/                  «        ‰ j(                  j1                  t        j                  j$                  j#                  «       «       ‰ j,                  D ]  }|j3                  «        Œ ‰ j5                  «       ‰ _        ‰ j,                  D �ci c]  }|j9                  «       |“Œ c}‰ _        ‰ j,                  D ��ci c](  }|j=                  «       D ]  }|j9                  «       |“Œ Œ* c}}‰ _        ‰ j:                  jA                  «       ‰ _!        i ‰ _"        i ‰ _#        tI        jJ                  ‰ j,                  ‰ j>                  ‰ jB                  «      ‰ _        ‰ jM                  «        ‰ jO                  ‰ j,                  «      ‰ _        ‰ jQ                  «        ‰ j,                  D �ci c]  }|j9                  «       |“Œ c}‰ _!        ‰ jS                  «        tT        xjV                  tY        ‰ j,                  «      z  c_+        ddl-m.}m/}  |‰ j,                  «       tY        ‰ j,                  «      ‰ _0        ‰ jc                  «        ‰ jO                  ‰ j,                  «      ‰ _        t        td        t        t        f      «       ‰ _3        th        jj                  �$ti        jj                  ‰ j,                  «      ‰ _        ‰ jm                  ‰ j,                  «      ‰ _        ‰ jo                  «        ‰ jq                  «        th        jr                  r‰ ju                  d ¬«       th        jv                  r‰ddl<m;}  |‰ j,                  ‰ j>                  ‰ jB                  t        t        j                  j                   j#                  «       «      t        t        j                  j{                  «       «      «      ‰ _        th        j|                  r$tI        j~                  ‰ j,                  «      ‰ _        ‰ j�                  «        ‰ jƒ                  «         |‰ j,                  «       t        j„                  j‡                  ‰ j,                  «       ‰ j‰                  «        t        t           «       ‰ _E        i ‰ _F        t�        d«      j‘                  ˆ fd„«       y c c}w c c}w c c}}w c c}w )Nr   )Úlog_ir_post_fusionÚlog_ir_pre_fusion)Únum_ck_nodesr   )Úreorder_for_peak_memoryÚgraph_statsc                 ó^   •— ‰ j                   ‰ j                  t        ‰ j                  «      dœS )N)Úgraph_idÚnum_nodes_before_fusionÚnum_nodes_after_fusion)Úpost_grad_graph_idÚnum_orig_nodesrk   r  r^   s   €rX   r´   z!Scheduler._init.<locals>.<lambda>1  s'   ø€ Ø ×3Ñ3Ø+/×+>Ñ+>Ü*-¨d¯j©j«/ñ€ rZ   )Ir_  r¶   r°  rD   r|   rK   Úbackendsr  Ú_post_grad_graph_counterr¾  r  ÚcountÚ_graph_partition_counterr   r™   rˆ  rã  ÚkeysÚ	constantsÚtorchbind_constantsr'  Úcreate_scheduler_noder  Úupdate_zero_dim_cpu_tensorr
  r  Úget_donated_buffersr‚   rU   r2  r»   rƒ   Úcopyr9  r  Úmutation_renamesr   Údecide_global_ordering_of_commsÚcompute_dependenciesÚtopological_sort_scheduleÚdead_node_eliminationÚcompute_ancestorsr    Úir_nodes_pre_fusionrk   Útorch._inductor.debugrµ  r¶  r¿  Úcreate_foreach_nodesrí  Úlogged_slow_fusionr   Ú_pre_fusion_custom_passr~  r“  Úfinalize_multi_template_buffersÚcombo_kernelsÚcreate_combo_kernel_nodesr¸  ÚmemoryÚget_output_namesÚ reorder_for_compute_comm_overlapÚ$reorder_compute_and_comm_for_overlapÚprocess_grouped_nodesÚcompute_last_usager?  Úgraph_diagramÚdebug_draw_graphÚbuffer_names_to_freeÚorigin_to_indexr   Úadd_row)	rV   r  rO  rL   r¿   rµ  r¶  r¸  rþ  s	   `       €rX   r²  zScheduler._initÃ  sT  ù€ Ü‰ÑÔØ%'ˆÔ"Ø Œ�‰ÔØ<>ˆŒÜ"&Ô'?Ó"@ˆÔÜ(1¯©Ó(9ˆÔ%ä$.¬s¡OÓ$5ˆÔ!Ü&0ðÜ—‘×%Ñ%×*Ñ*Ó,ðä—‘×"Ñ"×'Ñ'Ó)ðô —‘×,Ñ,×1Ñ1Ó3ðó'
ˆÔ#ð >CÖC¸�d×0Ñ0°Õ3ÒCˆŒ
Ø×'Ñ'Ô)à×#Ñ#×*Ñ*¬1¯7©7×+<Ñ+<×+AÑ+AÓ+CÔDØ—J‘Jò 	ˆDØ�O‰OÕð	ð ×$Ñ$Ó&ð 	Ô#ð &*§Z¡Zö;
Ø !ˆA�J‰J‹L˜!‰Oò;
ˆÔð -1¯J©J÷8
Ø$(À$×BRÑBRÓBTò8
Ø;>ˆC�L‰L‹N˜CÑð8
Øó8
ˆÔð AE×@QÑ@Q×@VÑ@VÓ@XˆÔð 35ˆÔð 13ˆÔô ×:Ñ:Ø�J‰JØ×ÑØ×#Ñ#ó
ˆŒ
ð 	×!Ñ!Ô#Ø×3Ñ3°D·J±JÓ?ˆŒ
Ø×"Ñ"Ô$Ø<@¿J¹JÖ"G°q 1§:¡:£<°¡?Ò"GˆÔØ×ÑÔ ä×#Ò#¤s¨4¯:©:£Ñ6Õ#ßOá˜$Ÿ*™*Ô%Ü! $§*¡*›oˆÔØ×!Ñ!Ô#Ø×3Ñ3°D·J±JÓ?ˆŒ
Ü",¬U´3¼°8©_Ñ"=Ó"?ˆÔÜ×)Ñ)Ð5Ü×7Ñ7¸¿
¹
ÓCˆDŒJØ—_‘_ T§Z¡ZÓ0ˆŒ
Ø×ÑÔØ×,Ñ,Ô.Ü×ÒØ×*Ñ*¸Ð*Ô=ô ×)Ò)Ý7á0Ø—
‘
Ø× Ñ Ø×'Ñ'Üœ1Ÿ7™7×/Ñ/×4Ñ4Ó6Ó7Üœ1Ÿ7™7×3Ñ3Ó5Ó6óˆDŒJô ×2Ò2Ü×CÑCÀDÇJÁJÓOˆDŒJØ×"Ñ"Ô$Ø×ÑÔ!Ù˜4Ÿ:™:Ô&Ü	�‰×Ñ˜dŸj™jÔ)Ø×ÑÔô %/¬s¡OÓ$5ˆÔ!ð :<ˆÔä˜Ó'×/Ñ/óõ	
ùòy Dùò;
ùó8
ùòB #Hs   ÄV>Æ8WÇ'-WËWc                ó  — i }t         j                  j                  D ]d  }t        t         j                  j                  |   t        j
                  «      sŒ9t        | t         j                  j                  |   d ¬«      ||<   Œf |S )N)rN   )rD   r|   Úgraph_inputs_originalry   r   ÚDonatedBufferr¨   )rV   Úname_to_donated_bufr]   s      rX   rÉ  zScheduler.get_donated_buffers8  sp   € Ø ÐÜ—G‘G×1Ñ1ò 	ˆDÜœ!Ÿ'™'×7Ñ7¸Ñ=¼r×?OÑ?OÕPÜ,BØÜ—G‘G×1Ñ1°$Ñ7Ø $ô-Ð# DÒ)ð	ð #Ð"rZ   c                ó6   — t         j                  j                  S rT   ©rD   r|   Úcurrent_devicer^   s    rX   rê  zScheduler.current_deviceC  s   € ä�w‰w×%Ñ%Ð%rZ   c                ó.   — |t         j                  _        y rT   ré  r_  s     rX   rê  zScheduler.current_deviceG  s   € à!'Œ�‰ÕrZ   c                ó€   — t         j                  j                  dd«      dk(  rddlm}  || j
                  d¬«       yy)z,Generate an image of the graph for debuggingÚINDUCTOR_WRITE_SCHEDULER_GRAPHNÚ1r   )Údraw_buffersT)Úprint_graph)ÚosÚenvironr  r?  rï  r  )rV   rï  s     rX   rà  zScheduler.debug_draw_graphK  s1   € ä�:‰:�>‰>Ð:¸DÓAÀSÒHÝ+á˜Ÿ™°Ö6ð IrZ   c                óº   — t         j                  t        j                  «      r8t         j	                  d|«       | j
                  D ]  }|j                  «        Œ y y )Nz%s:)rÖ   ÚisEnabledForÚloggingÚINFOrï   r  rð   )rV   ÚlabelrL   s      rX   Údebug_print_nodeszScheduler.debug_print_nodesR  sF   € Ü×ÑœGŸL™LÔ)Ü�H‰H�U˜EÔ"ØŸ
™
ò #�Ø× Ñ Õ"ñ#ð *rZ   c                ó6  — |j                  «       €J d«       ‚|j                  «       rt        | |«      S t        |t        j
                  t        j                  f«      rt        | |«      S t        |t        j                  «      rt        | |«      S t        |«      ‚)Nz2All nodes passed to scheduling must have an origin)r   Úis_no_opr‹  ry   r   r,   rv  rM  rö  rß  r  r  s     rX   rÇ  zScheduler.create_scheduler_nodeX  s‡   € Ø×ÑÓ!Ð-ð 	
Ø@ó	
Ð-ð �=‰=Œ?Ü)¨$°Ó5Ð5Ü˜œr×0Ñ0´"×2CÑ2CÐDÔEÜ   tÓ,Ð,Ü˜œbŸo™oÔ.Ü,¨T°4Ó8Ð8ä% dÓ+Ð+rZ   c                ó¤  — t        t           «       }g }| j                  j                  «       }t        j
                  j                  j                  «       D ]«  }|D �cg c]%  }||v rt        | j                  |   t        «      s|‘Œ' }}|sŒ6|j                  |«       |D �cg c]  }| j                  |   ‘Œ }}t        j                  dkD  }t        | |d|¬«      }|j                  |«       |D ]  }|| j                  |<   Œ Œ­ | j                   D �	cg c]  }	|	j#                  «       |vsŒ|	‘Œ c}	t%        |«      z   | _        y c c}w c c}w c c}	w )Nr   F©rE  rH  )r   r™   r9  rÄ  rD   r|   Úlistsr’   ry   r2  r‹  r
  r   Úcombo_kernels_autotuner+  r¡  r  rU   r‘   )
rV   Úremoved_node_namesÚfe_nodesÚkept_node_namesÚnamesr]   rË  rH  Úfe_noderL   s
             rX   rÓ  zScheduler.create_foreach_nodese  sS  € Ü'¬™_Ó.ÐØˆØ×1Ñ1×6Ñ6Ó8ˆä—W‘W—]‘]×)Ñ)Ó+ò 	8ˆEð "öàØ˜?Ñ*Ü" 4×#4Ñ#4°TÑ#:Ô<RÔSò ðˆEð ñ àà×%Ñ% eÔ,Ø:?Ö@°$�d×'Ñ'¨Ó-Ð@ˆFÐ@ä$×;Ñ;¸aÑ?ˆOÜ0ØØØ*/Ø /ô	ˆGð �O‰O˜GÔ$àò 8�Ø07�×'Ñ'¨Ò-ñ8ð1	8ð8 "ŸZ™Zö
Ø¨4¯=©=«?ÐBTÒ+TŠDò
ä�‹Nñˆ�
ùò5ùò Aùò
s   Á*EÂ!EÄEÄ*Ec                óÖ  ‡ ‡‡‡ — t        d«      } G ˆfd„dt        |   «      Št        j                  ‰«      Š‰ j                  D ]’  }|j                  «       D ]}  }|j                  «       }|j                  «       D ]X  }|‰v r=|‰v r9‰|   }‰|   }||z   }‰j                  «       D ]  }	‰|	   |u s‰|	   |u sŒ|‰|	<   Œ ŒD|‰v r	‰|   ‰|<   ŒQ‰|   ‰|<   ŒZ Œ Œ” dˆ ˆ fd„Š 	 	 d	 	 	 	 	 	 	 	 	 dˆˆ fd„}
i }t        j                  j                  j                  «       D ]6  \  }}t        |t        j                  «      sŒ!|j                   D ]  }d||<   Œ	 Œ8 ‰ j                  D �]¼  }t"        j%                  d|j&                  «       |j&                  €J ‚t)        |j&                  j+                  «       d„ ¬	«      }|D ]6  }t        |t        j,                  «      sJ ‚||vsŒ$|j                  «       ||<   Œ8 t)        |j&                  j/                  «       d
„ ¬	«      }|D ]d  }||v sJ |› d|› �«       ‚||   x}€Œ‰ j0                  |   j                  «       D ]*  }|j3                  t5        |j                  «       «      «       Œ, Œf t7        |j8                  j:                  «      dk(  rGt=        t?        |j8                  j:                  «      «      x}rt        |t@        «      r|jB                  }nd}|j                  «       D �]  }t7        |jE                  «       «      dk  sJ ‚|jE                  «       D ]Ý  } ‰ |«      } |
||«       |j3                  t5        ||¬«      «       ‰|   j                  D ]œ  }|j                  «       |j                  «       k(  rŒ%t        |j&                  tF        «      sJ ‚|j&                  jI                  «       D ]?  } ‰ |«      }|j3                  tK        ||j                  «       ¬«      «        |
||d¬«       ŒA Œž Œß �Œ |j8                  jL                  D ]6  }t        |tJ        «      rŒ |
|jN                  ||jQ                  |«      «       Œ8 |jS                  ‰ jT                  «       |j                  «       D ]Ž  }|jE                  «       D ]y  }|j                  «       ‰ jT                   ‰ |«      <   |j                  «       ‰ jT                  |<   ‰ jV                  jY                  ||«      ‰ jV                  |j                  «       <   Œ{ Œ� �Œ¿ t        j                  j[                  «       D ]3  }t"        j%                  d|«        |
|t]        t5        |«      «      «       Œ5 t        j                  j^                  D ]‘  }|j/                  «       D ]|  }||v sJ |› d|j                  «       › �«       ‚||   x}sŒ)‰ j0                  |   jI                  «       D ]4  }t"        j%                  d||«        |
|t]        t5        |«      «      «       Œ6 Œ~ Œ“ ‰ jT                  D ]›  }|t        j                  j                  v rE |
|t]        t5        |«      «      «       t        j                  j`                  jc                  |«       Œd|t        j                  jd                  v sŒ� |
|t]        t5        |«      «      «       Œ� tg        t        j                  j                  j                  «       «      D ��ci c]  \  }}||“Œ
 }}}t        j                  j`                  D �cg c]  }||   ‘Œ	 c}t        j                  _4        ‰ j                  D ]C  }|j                  «       D ].  }|jk                  ‰|j                  «          j                  «       Œ0 ŒE ‰ jl                  D ]-  }‰ jl                  |   jk                  ‰|   j                  «       Œ/ yc c}}w c c}w )zi
        Create dependency edges between nodes, handling aliasing and
        mutation properly.
        ÚTc                  ó>   •— e Zd ZdZ	 	 d	 	 	 	 	 dd„Zdd„Zd	ˆ fd„Zy)
ú1Scheduler.compute_dependencies.<locals>.DedupListan  
            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                ó@   — |xs g | _         |xs
 t        «       | _        y rT   )Úitemsr   Ú
membership)rV   r	  r
  s      rX   r¶   z:Scheduler.compute_dependencies.<locals>.DedupList.__init__›  s   € ð
 #š[ b�”
Ø",Ò"<´
³�•rZ   c                óŽ   — || j                   v ry | j                  j                  |«       | j                   j                  |«       y rT   )r
  r	  r¡  r!  )rV   Ú	node_users     rX   r¡  z8Scheduler.compute_dependencies.<locals>.DedupList.append£  s5   € Ø §¡Ñ/ØØ—
‘
×!Ñ! )Ô,Ø—‘×#Ñ# IÕ.rZ   c                óà   •— t        j                  | j                  |j                  «      }| j                  |j                  D �cg c]  }|| j                  vsŒ|‘Œ c}z   } ‰||«      S c c}w rT   )r   rÜ  r
  r	  )rV   rª  Únew_membershipr“  Ú	new_itemsÚ	DedupLists        €rX   Ú__add__z9Scheduler.compute_dependencies.<locals>.DedupList.__add__©  sc   ø€ Ü!+×!1Ñ!1°$·/±/À5×CSÑCSÓ!T�Ø ŸJ™JØ$Ÿ{™{ö*Ø¨a°t·±Ò.F’Aò*ñ �	ñ ! ¨NÓ;Ð;ùò*s   ÁA+ÁA+rÒ  )r	  zOptional[list[T]]r
  zOptional[OrderedSet[T]]r˜   r�   )r  r  r˜   r�   )rª  úDedupList[T]r˜   r  )rf   r¡   r¢   r(  r¶   r¡  r  )r  s   €rX   r  r  ‘  s;   ø„ ñð ,0Ø6:ð=à(ð=ð 4ð=ð ó	=ó/ö<rZ   r  c                óN   •— | ‰j                   v r ‰‰j                   |    «      S | S rT   )rË  )rO  r÷   rV   s    €€rX   r÷   z.Scheduler.compute_dependencies.<locals>.renameË  s,   ø€ Ø�D×)Ñ)Ñ)Ù˜d×3Ñ3°AÑ6Ó7Ð7ØˆHrZ   c                óP   •— ‰ ‰| «         j                  t        |||«      «       y rT   )r¡  r¤  )Úused_by_namer  rq  r¦  Úname_to_usersr÷   s       €€rX   Úadd_userz0Scheduler.compute_dependencies.<locals>.add_userÐ  s)   ø€ ð ™& Ó.Ñ/×6Ñ6Ü˜ K°Ó9õrZ   Nzscheduling %sc                ó   — | j                   S rT   r  rñ  s    rX   r´   z0Scheduler.compute_dependencies.<locals>.<lambda>ë  ó
   € ÀAÇFÁF€ rZ   rF  c                ó   — | j                   S rT   r  rñ  s    rX   r´   z0Scheduler.compute_dependencies.<locals>.<lambda>ö  r  rZ   z not in r   )rÌ  )Úmutating_bufT)r¦  zscheduling output %sz+scheduling output %s for unbacked symint %s)rO  r™   r˜   r™   )FF)
r  r™   r  r¥  rq  rŸ   r¦  rŸ   r˜   r�   )7r   r   rá  r   r  r»   rU   rh   rÄ  rD   r|   rã  r	  ry   r·  rN  Úfree_symbolsrÖ   r?  rL   rK  Úget_unbacked_symbol_defsÚSymbolÚget_unbacked_symbol_usesr2  rÿ   r(   rk   r¬   rÒ   r  rÅ  r'   rÌ  rj   rG   rH  r)   rÓ   r]   rq  rú   rË  r  r  rÚ  r‹   Úgraph_outputsÚmutated_inputsr!  rÅ  r  Úmutated_input_idxsr“   r‚   )!rV   r  rL   Úbuf1Ú	buf1_nameÚ	buf2_nameÚlist1Úlist2ÚcombinedrG  r  Úunbacked_symbol_to_origin_noder]   ÚvalÚfsÚunbacked_symbol_defsrÃ  Úunbacked_symbol_usesr<  r¿   rþ   Ú	node_modeÚalt_namero   Ú
other_namer‘  rX  rÙ   rÆ  Ú	inp_namesr  r  r÷   s!   `                             @@@rX   rÍ  zScheduler.compute_dependencies‰  sÕ  û€ ô �C‹Lˆö	<œ ™
ô 	<ô> @K×?VÑ?VØó@
ˆð —J‘Jò 	LˆDØ×(Ñ(Ó*ò L�Ø ŸM™M›O�	Ø!%×!1Ñ!1Ó!3ò L�IØ  MÑ1°iÀ=Ñ6Pà -¨iÑ 8˜Ø -¨iÑ 8˜Ø#(¨5¡=˜Ø#0×#5Ñ#5Ó#7ò >˜Cà -¨cÑ 2°eÑ ;Ø#0°Ñ#5¸Ò#>à5= ¨cÒ 2ñ>ð # mÑ3Ø3@ÀÑ3K˜ iÒ0à3@ÀÑ3K˜ iÒ0ñLñLð	Lö(	ð !&Ø!ð		Øð	à;ð	ð ð	ð ð		ð
 ö	ð MOÐ&ô
 Ÿ™×-Ñ-×3Ñ3Ó5ò 	>‰IˆD�#Ü˜#œuŸz™zÕ*Ø×*Ñ*ò >�BØ9=Ð2°2Ò6ñ>ð	>ð
 —J‘Jó J	ˆDÜ�I‰I�o t§y¡yÔ1ð —9‘9Ð(Ð(Ð(Ü#)Ø—	‘	×2Ñ2Ó4Ñ:Jô$Ð ð *ò H�Ü! !¤U§\¡\Ô2Ð2Ð2ð Ð:Ò:Ø8<¿¹»Ð2°1Ò5ðHô $*Ø—	‘	×2Ñ2Ó4Ñ:Jô$Ð ð *ò C�ØÐ:Ñ:ð Ø�c˜Ð"@Ð!AÐBóÐ:ð 8¸Ñ:Ð:�AÑGØ#×0Ñ0°Ñ3×?Ñ?ÓAò C˜Ø×)Ñ)¬'°#·,±,³.Ó*AÕBñCðCô �D×$Ñ$×+Ñ+Ó,°Ò1Ü ¤ d×&6Ñ&6×&=Ñ&=Ó!>Ó?Ð?�SÐ?Ü˜s¤IÔ.àŸH™H‘	à �	ð ×'Ñ'Ó)ó E�ä˜3×,Ñ,Ó.Ó/°1Ò4Ð4Ð4Ø #× 1Ñ 1Ó 3ò E�HÙ% hÓ/�Há˜X tÔ,Ø×%Ñ%¤g¨h¸YÔ&GÔHØ -¨hÑ 7× =Ñ =ò E˜ØŸ=™=›?¨d¯m©m«oÒ=Ø$ä)¨$¯)©)Ô5FÔGÐGÐGØ*.¯)©)×*DÑ*DÓ*Fò E˜Já)/°
Ó);˜JØ ×-Ñ-Ü '¨
ÀÇÁÃÔ Pôñ % Z°¸tÖDñEñEòEðEð, ×(Ñ(×.Ñ.ò F�Ü! $¬Õ0Ù˜TŸY™Y¨¨d×.>Ñ.>¸tÓ.DÕEðFð ×%Ñ% 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Ò;ñòðIJ	ôZ Ÿ™×0Ñ0Ó2ò 	>ˆHÜ�I‰IÐ,¨hÔ7Ù�Xœz¬'°(Ó*;Ó<Õ=ð	>ô
 —7‘7×(Ñ(ò 
	JˆCØ×1Ñ1Ó3ò 	J�ØÐ:Ñ:ð Ø�c˜Ð"@×"EÑ"EÓ"GÐ!HÐIóÐ:ð 7°qÑ9Ð9�1Ñ9Ø$(×$5Ñ$5°aÑ$8×$IÑ$IÓ$Kò J˜ÜŸ	™	ØIÈ8ÐUVôñ ! ¬:´g¸hÓ6GÓ+HÕIñ	Jñ	Jð
	Jð ×)Ñ)ò 	:ˆDØ”q—w‘w×+Ñ+Ñ+Ù˜œz¬'°$«-Ó8Ô9Ü—‘×&Ñ&×*Ñ*¨4Õ0ØœŸ™×*Ñ*Ò*á˜œz¬'°$«-Ó8Õ9ð	:ô ,5´Q·W±W×5IÑ5I×5NÑ5NÓ5PÓ+Q÷
Ù'˜E 4ˆD�%‰Kð
ˆ	ñ 
ô )*¯©×(>Ñ(>ö&
Ø $ˆI�d‹Oò&
Œ�‰Ô"ð
 —J‘Jò 	CˆDØ×'Ñ'Ó)ò C�Ø—‘˜m¨C¯L©L«NÑ;×AÑAÕBñCð	Cð ×/Ñ/ò 	SˆDØ×'Ñ'¨Ñ-×7Ñ7¸ÀdÑ8K×8QÑ8QÕRñ	Sùó
ùò&
s   Ü_ Ü/_&c                óZ  ‡	— g }t        | j                  «      D �]Ð  }dd„Š	d}|j                  «       D ]€  }t        ˆ	fd„|j                  D «       «      }|r\t
        j                  d|j                  «       «       t        j                  j                  j                  |j                  «       «       Œd}Œ‚ |j                  «        xr | }|s|j                  |«       ŒÇt
        j                  d|j                  «       «       t        j                  j                  j                  |j                  «       «       |j                  j                   D ]–  }|j"                  | j$                  v sŒ| j$                  |j"                     j                  }|D �cg c]0  }|j&                  j                  «       |j                  «       k7  sŒ/|‘Œ2 c}| j$                  |j"                     _        Œ˜ �ŒÓ t)        t        |«      «      | _        | j                  D ]  }|j+                  «        Œ yc c}w )	z0
        Remove any nodes without users
        c                ór   — | j                   xs* | j                  «       t        j                  j                  v S rT   )r¦  rU   rD   r|   r-  )ro   s    rX   Úcan_eliminate_userz;Scheduler.dead_node_elimination.<locals>.can_eliminate_userd	  s&   € Ø—|‘|ÒT t§}¡}£¼!¿'¹'×:TÑ:TÐ'TÐTrZ   Fc              3  ó.   •K  — | ]  } ‰|«      –— Œ y ­wrT   r¦   )r  Úur4  s     €rX   r  z2Scheduler.dead_node_elimination.<locals>.<genexpr>i	  s   øè ø€ Ò#M¸aÑ$6°q×$9Ñ#Mùó   ƒzremoved dead buffer: %sTzremoved dead operation: %sN)ro   r¤  r˜   rŸ   )r¶  r  r»   rQ  rQ   rÖ   r?  rU   rD   r|   r‰  r!  rs  r¡  r-  r¬   rÓ   r]   rƒ   rL   r‘   r6  )
rV   Úupdated_nodesrL   Úactive_buffersr¿   Úcan_eliminater‘  rQ   r6  r4  s
            @rX   rÏ  zScheduler.dead_node_eliminationZ	  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ò=˜×(Ñ(¨¯©Ñ3Õ9òð-	ô8 œ( =Ó1Ó2ˆŒ
ð —J‘Jò 	#ˆDØ× Ñ Õ"ñ	#ùò=s   Æ0H(ÇH(c                óº   ‡‡‡‡— t        t           «       Št        «       Šg Šdˆˆˆˆfd„Š|D ]  }|j                  «       D ]  }|‰|<   Œ	 Œ |D ]
  } ‰|«       Œ ‰S )z?
        Ensure nodes is in topologically sorted order
        c                óÖ   •— | ‰vrd‰j                  | «       t        | j                  d„ ¬«      D ]&  }|j                  ‰vrŒ ‰‰|j                     «       Œ( ‰j	                  | «       y y )Nc                ó   — | j                   S rT   r  )Úds    rX   r´   zDScheduler.topological_sort_schedule.<locals>.visit.<locals>.<lambda>‘	  s
   € ÀaÇfÁf€ rZ   rF  )r!  rK  r­   r]   r¡  )rO  rþ   r2  rn   ÚseenÚvisits     €€€€rX   r@  z2Scheduler.topological_sort_schedule.<locals>.visitŽ	  se   ø€ Ø˜‰}Ø—‘˜”Ü! !×"6Ñ"6Ñ<LÔMò 2�Cà—x‘x |Ñ3Ø Ù˜, s§x¡xÑ0Õ1ð	2ð
 —‘˜aÕ ð rZ   )rO  rG   r˜   r�   )r   rG   r«  rH  )rV   r  rL   r]   r2  rn   r?  r@  s       @@@@rX   rÎ  z#Scheduler.topological_sort_schedule„	  sy   û€ ô Ô+Ñ,Ó.ˆÜ59³VˆØ*,ˆ÷	!ð 	!ð ò 	*ˆDØ×-Ñ-Ó/ò *�Ø%)�˜TÒ"ñ*ð	*ð ò 	ˆDÙ�$�Kð	àˆrZ   c                ó@  ‡ — t        t           «       }t        |t        t        t
        t        f«      r-|j                  D ]  }|j                  |j                  «       Œ nt        dt        |«      › d�«      ‚ˆ fd„|D «       }t        t        ˆ fd„|D «       «      «      S )Nz+get_unmet_dep_nodes is not implemented for ú.c              3  óX   •K  — | ]!  }‰j                   |   j                  «       –— Œ# y ­wrT   )rƒ   rY   r(  s     €rX   r  z1Scheduler._get_unmet_dep_nodes.<locals>.<genexpr>°	  s%   øè ø€ ÒXÀc˜×)Ñ)¨#Ñ.×?Ñ?×AÑXùs   ƒ'*c              3  ó<   •K  — | ]  }‰j                   |   –— Œ y ­wrT   ©r9  )r  rO  rV   s     €rX   r  z1Scheduler._get_unmet_dep_nodes.<locals>.<genexpr>±	  s   øè ø€ ÒQ¸a˜t×6Ñ6°qÕ9ÑQùs   ƒ)r   r™   ry   rM  rß  r‹  râ  r­   r!  r]   ÚRuntimeErrorre   r‘   )rV   rî  Ú
unmet_depsrþ   Úunmet_dep_opss   `    rX   Ú_get_unmet_dep_nodeszScheduler._get_unmet_dep_nodesŸ	  s”   ø€ Ü¤‘_Ó&ˆ
ÜØäÜ)Ü&Ü"ð	ô
ð ×/Ñ/ò )�Ø—‘˜sŸx™xÕ(ñ)ô Ø=¼dÀ5»k¸]È!ÐLóð ó YÈZÔXˆÜ”JÓQÀ=ÔQÓQÓRÐRrZ   c                óz  — g }t         j                  | j                  d«      }i }| j                  D ]P  }| j                  |«      }t	        |«      ||<   |D ]*  }|j                  |g «      }|j                  |«       |||<   Œ, ŒR |j                  «       D ��	cg c]  \  }}	|	dk(  sŒ|‘Œ }
}}	|
rx|j                  |
«       |
D ]7  }|j                  |g «      D ]  }||xx   dz  cc<   Œ |j                  |«       Œ9 |j                  «       D ��	cg c]  \  }}	|	dk(  sŒ|‘Œ }
}}	|
rŒx|rJ d«       ‚|S c c}	}w c c}	}w )zU
        Sort nodes by their topological order, return a list of node lists.
        r   r   zTopological sort failed!)	r«  Úfromkeysr  rI  rk   r  r¡  r	  r   )rV   r   r  ÚchildrenrL   r$  rþ   ÚcrO  ÚvÚzero_deg_nodesro   s               rX   rZ  z!Scheduler._topological_sort_nodes³	  sF  € ð ˆÜ—‘˜dŸj™j¨!Ó,ˆØ#%ˆØ—J‘Jò 	"ˆDØ×,Ñ,¨TÓ2ˆDÜ˜d›)ˆE�$‰KØò "�Ø—L‘L  bÓ)�Ø—‘˜”Ø !�˜’ñ"ð	"ð ).¯©«×@¡  1¸¸a»š!Ð@ˆÑ@ÙØ�L‰L˜Ô(Ø#ò �Ø$ŸL™L¨¨BÓ/ò %�DØ˜$“K 1Ñ$”Kð%à—	‘	˜!•ðð -2¯K©K«M×D¡D A q¸QÀ!»VšaÐDˆNÑDò ñ Ð4Ð4Ó4ˆyØˆùó Aùó Es   ÂD1Â%D1ÄD7ÄD7c                óx  — i }| j                   D ]~  }t        t           «       }|j                  D ]B  }| j                  |j
                     j                  «       }|j                  |«       |||   z  }ŒD |||j                  «       <   ||_	        Œ€ t        | j                   «      D ]  \  }}||_        ||_        Œ y)z.
        Populate each node.ancestors
        N)r  r   r™   r­   rƒ   r]   rY   r!  rU   r¸   r  r®   r¯   )rV   Úname_to_ancestorsrL   r¸   rþ   Údep_node_namer   s          rX   rÐ  zScheduler.compute_ancestorsÍ	  s½   € ð
 9;ÐØ—J‘Jò 	'ˆDÜ"¤3™Ó)ˆIØ×.Ñ.ò >�Ø $× 0Ñ 0°·±Ñ :× KÑ KÓ M�Ø—‘˜mÔ,ØÐ.¨}Ñ=Ñ=‘	ð>ð 2;Ð˜dŸm™m›oÑ.Ø&ˆD�Nð	'ô % T§Z¡ZÓ0ò 	#‰KˆE�4Ø"ˆDŒNØ"ˆD�Nñ	#rZ   c                óH  — | j                   D ]“  }t        j                  sŒt        |t        t
        f«      r#|j                  «       st        j                  dk7  rŒN|j                  «       D ]3  }t        |t        «      r|j                  «       rŒ$|j                  «        Œ5 Œ• y )NÚhalide)r  r   r{  ry   rM  râ  r?   Úcpu_backendrC  ri  r“  )rV   rL   rî  s      rX   r“  zScheduler.merge_loopsà	  s†   € Ø—J‘Jò 	$ˆDÜ×4Ò4Øô ˜d¤]Ô4FÐ$GÔHØ—K‘K”M¤f×&8Ñ&8¸HÒ&DàØŸ™Ó)ò $�ä! %¬Ô7¸5×;LÑ;LÔ;NØà×!Ñ!Õ#ñ$ñ	$rZ   c                ój  — t        d«      5  t        d«      D ]ƒ  }t        |«      }t        j	                  d|dz   |«       | j                  |«      }t        |«      }t        j	                  d|dz   ||«       ||k(  s|dk(  sŒjt        j	                  d|dz   «        n |cddd«       S # 1 sw Y   yxY w)zB
        Combine eligible nodes into FusedSchedulerNodes.
        zScheduler.fused_nodesé
   z/===== attempting fusion (%d/10): %d nodes =====r   z=completed fusion round (%d/10): fused %d nodes into %d nodes
z+===== fusion complete (%d iterations) =====N)r   r[  rk   r>  r?  Úfuse_nodes_once)rV   r  r  Úold_lenÚnew_lens        rX   r~  zScheduler.fuse_nodesû	  sÃ   € ô Ð1Ó2ñ 	Ü˜2“Yò �Ü˜e›*�Ü× Ñ ØEØ˜‘EØôð
 ×,Ñ,¨UÓ3�Ü˜e›*�Ü× Ñ ØTØ˜‘EØØô	ð ˜gÒ%¨°A«Ü×$Ñ$ØEÀqÈ1Áuôñ ð'ð( ÷+	÷ 	ò 	ús   ŒA5B)ÂB)Â)B2c                óœ   — g }| j                   D ]4  }|j                  t        |t        «      r|j	                  «       n|g«       Œ6 || _         y)zA
        Unpack GroupedSchedulerNode into regular nodes.
        N)r  r#  ry   rä  r  )rV   Ú	new_nodesrL   s      rX   rÝ  zScheduler.process_grouped_nodes
  sJ   € ð .0ˆ	Ø—J‘Jò 	ˆDØ×ÑÜ!+¨DÔ2FÔ!G�—‘”ÈdÈVõð	ð ˆ�
rZ   c                óâ   — t        |«      dkD  sJ ‚|d   j                  «       }|| _        | j                  |«      }t	        ddd¬«      5  |j                  |«      cddd«       S # 1 sw Y   yxY w)úƒ
        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)Úlog_pt2_compile_eventÚdynamo_compile_column_usN)rk   r[  rê  ry  r   r_  )rV   r  r`  Úbackends       rX   r_  zScheduler.benchmark_fused_nodes!
  st   € ô �5‹z˜AŠ~Ðˆ~Ø�q‘×$Ñ$Ó&ˆØ$ˆÔØ×"Ñ" 6Ó*ˆÜØ#Ø"&Ø%Dô
ñ 	8ð
 ×0Ñ0°Ó7÷	8÷ 	8ò 	8ús   Á
A%Á%A.c                óÞ   — t        |«      dkD  sJ ‚|d   j                  «       }|| _        | j                  |«      }t	        d«      5  |j                  ||«      cddd«       S # 1 sw Y   yxY w)r^  r   r_  N)rk   r[  rê  ry  r   Úgenerate_kernel_code_from_nodes)rV   r  Úbenchmark_kernelr`  rc  s        rX   re  z)Scheduler.generate_kernel_code_from_nodes3
  sq   € ô �5‹z˜AŠ~Ðˆ~Ø�q‘×$Ñ$Ó&ˆØ$ˆÔØ×"Ñ" 6Ó*ˆÜÐ1Ó2ñ 	TØ×:Ñ:¸5ÐBRÓS÷	T÷ 	Tò 	Tús   ÁA#Á#A,c                ó–   — || _         | j                  |«      }t        d«      5  |j                  |«      cddd«       S # 1 sw Y   yxY w)r^  r_  N)rê  ry  r   Úbenchmark_codegened_module)rV   Úmoduler`  rc  s       rX   rh  z$Scheduler.benchmark_codegened_moduleA
  sH   € ð %ˆÔØ×"Ñ" 6Ó*ˆÜÐ1Ó2ñ 	>Ø×5Ñ5°fÓ=÷	>÷ 	>ò 	>ús	   ¤?¿Ac                óÌ  — 	 	 	 	 	 	 dd„}t        | j                  «      D �]A  \  }}t        |t        «      sŒt        |j                  t
        j                  «      sŒ=|j                  }t        j                  j                  s|j                  «       \  }}nt        d„ |j                  D «       «      }t        |t        j                  j
                  j                  «      r|j                  j!                  |«       ŒÝ|j#                  «       }|j$                  }t        |t
        j&                  «      sJ ‚|j$                  }	t        |	t
        j(                  «      sJ ‚|j*                  |	_         |||	«       | j-                  |	«      }
|
| j                  |<   |
| j.                  |j1                  «       <   |
| j2                  |j1                  «       <   t5        |
j7                  «       |j7                  «       «      D ]3  \  }}|| j8                  |j1                  «       <   |j:                  |_        Œ5 |j<                  |
_        |j>                  |
_        |j@                  |
_         �ŒD y )Nc                óÄ  — |j                  «       }| j                  «       }t        |t        «      rt        |t        «      sJ ‚|j                  «       }| j                  «       }t        |t        «      rt        |t        «      sJ ‚t        j
                  j                  |= ||_        t        j
                  j                  |= ||_	        t        j
                  j                  j                  | «      }t        j
                  j                  j                  |«       |t        j
                  j                  |<   |t        j
                  j                  |<   t        j
                  j                  j                  | «      }t        j
                  j                  j                  |«       |t        j
                  j                  |<   |t        j
                  j                  |<   y rT   )rU   ry   r™   r<  rD   r|   r"  r]   Ú
name_to_opÚoperation_nameÚbuffersrÆ  ÚremoveÚ
operations)Ú	orig_noderJ  Úreplaced_buf_nameÚorig_buf_nameÚreplaced_op_nameÚorig_op_nameÚorigs          rX   Úreplace_operation_bufferzKScheduler.finalize_multi_template_buffers.<locals>.replace_operation_bufferN
  sW  € ð !)× 1Ñ 1Ó 3ÐØ%×.Ñ.Ó0ˆMÜ˜m¬SÔ1´jÐARÔTWÔ6XÐXÐXà'×:Ñ:Ó<ÐØ$×7Ñ7Ó9ˆLÜ˜l¬CÔ0´ZÐ@PÔRUÔ5VÐVÐVä—‘×&Ñ&Ð'8Ð9Ø)ˆHŒMä—‘×"Ñ"Ð#3Ð4Ø&2ˆHÔ#ä—7‘7—?‘?×(Ñ(¨Ó3ˆDÜ�G‰G�O‰O×"Ñ" 8Ô,Ø$,ŒA�G‰G�O‰O˜DÑ!Ø4<ŒA�G‰G×"Ñ" =Ñ1ä—7‘7×%Ñ%×+Ñ+¨IÓ6ˆDÜ�G‰G×Ñ×%Ñ% hÔ/Ø'/ŒA�G‰G×Ñ˜tÑ$Ø/7ŒA�G‰G×Ñ˜|Ò,rZ   c              3  ó|   K  — | ]4  }t        |t        j                  j                  j                  «      r|–— Œ6 y ­wrT   )ry   rã   rä   Úselect_algorithmÚExternKernelCaller)r  Útimings     rX   r  z<Scheduler.finalize_multi_template_buffers.<locals>.<genexpr>r
  s6   è ø€ ò à &Ü)Ø &Ü %§¡× @Ñ @× SÑ Sô ô #ñùs   ‚:<)rq  zir.MultiTemplateBufferrJ  zir.OperationBufferr˜   r�   )!r  r  ry   rM  rL   r   ÚMultiTemplateBufferr   Útest_configsÚ%force_extern_kernel_in_multi_templateÚget_min_choicer  Úchoice_timingsrã   rä   ÚTritonTemplateCallerBaseÚfinalize_as_triton_callerÚoutput_noderà   Ú
StorageBoxÚOperationBufferrg   rÇ  r2  rU   r9  r¬  r»   rƒ   rQ   r®   r¯   r¹   )rV   rw  r  rL   Ú
multi_nodeÚmin_node_unfusedrõ  Úout_tensorboxÚout_storageÚ
out_bufferÚnew_scheduler_nodeÚnew_outÚold_outs                rX   rÖ  z)Scheduler.finalize_multi_template_buffersM
  s  € ð	8Ø-ð	8Ø9Kð	8àó	8ô6 ! §¡Ó,ó 0	@‰GˆAˆtÜ˜$¤Õ.´:Ø—	‘	œ2×1Ñ1õ4ð "ŸY™Y�
Ü×*Ñ*×PÒPØ*4×*CÑ*CÓ*EÑ'Ð$¡aä'+ñà*4×*CÑ*Côó	(Ð$ô Ø$Ü—O‘O×&Ñ&×?Ñ?ôð —I‘I×7Ñ7Ð8HÔIØà 0× <Ñ <Ó >�Ø+×0Ñ0�Ü! +¬r¯}©}Ô=Ð=Ð=Ø(×-Ñ-�
Ü! *¬b×.@Ñ.@ÔAÐAÐAà$.×$5Ñ$5�
Ô!Ù(¨°ZÔ@Ø%)×%?Ñ%?À
Ó%KÐ"à 2�—
‘
˜1‘Ø5G�×!Ñ! $§-¡-£/Ñ2Ø;M�×'Ñ'¨¯©«Ñ8ä(+Ø&×2Ñ2Ó4°d×6FÑ6FÓ6Hó)ò 2Ñ$�G˜Wð <C�D×$Ñ$ W×%5Ñ%5Ó%7Ñ8Ø$+§M¡M�G•Mð	2ð 04¯~©~Ð"Ô,Ø/3¯~©~Ð"Ô,Ø04·±Ð"Ö-ña0	@rZ   c                ó&   — t        d„ |D «       «      S )Nc              3  óö   K  — | ]q  }t        |j                  d «      xrU |j                  duxrE t        |j                  j                  d«      xr# |j                  j                  j                  dk(  –— Œs y­w)rà   NÚscatter_moderÍ  )r   rL   rà   r�  rN  s     rX   r  z,Scheduler._any_atomic_add.<locals>.<genexpr>œ
  so   è ø€ ò 
ð
 ô	 �A—F‘F˜FÓ#ò 9Ø—‘˜dÐ"ò9ä˜Ÿ™Ÿ™ ^Ó4ò9ð —‘—‘×(Ñ(¨LÑ8ó9ñ
ùs   ‚A7A9)r  ©rV   Ú	node_lists     rX   Ú_any_atomic_addzScheduler._any_atomic_add›
  s   € Üñ 
ð
 ô
ó 
ð 	
rZ   c           	     ó®  ‡ ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡— t        d„ ‰‰fD «       «      }t        j                  s|sy‰j                  «       r(t	        ‰j                  «       t        j                  «      r ‰j                  «       s‰j                  «       ry‰j                  «       }|d   j                  «       Š‰sJ ‚‰j                  dk(  ry‰j                  «       }t        t        j                  ||«      «      }‰ j                  |«      ryddlmŠ t%        ‰‰«      Š|d   j                  «       Š‰€J ‚dˆˆfd„Št&        j(                  j*                  j-                  «       Š	 	 	 	 dˆˆ fd„}|�r´t        d	„ ‰‰fD «       «      �rŸ‰j                  «       duŠ‰r‰j                  «       n‰j                  «       Št	        ‰t        j.                  «      sJ ‚‰j0                  }‰j3                  «       \  }	Š‰j3                  «       \  }	Š‰r‰ j5                  |«      n‰ j5                  |«      \  Š}
g Šd}t7        |j9                  «       d
„ ¬«      D ]µ  \  }}t	        |t&        j(                  j                  j:                  «      sŒ5‰s&t=        |d«      r|j>                  ‰j>                  k7  rŒ]|‰‰z   k\  r nQ|dz  }|t        j@                  kD  r n7‰jC                  |«      5  ‰jE                  |g ||«      ¢­«       ddd«       Œ· tG        ‰«      dk(  rydˆˆˆˆˆˆˆˆ fd„}|S  ||«      Š ||«      Š ||«      Šdˆˆˆˆˆˆˆ ˆfd„}|S # 1 sw Y   �ŒxY w)ú‡
        If config.benchmark_fusion is False, always return True.
        Otherwise, return True if fusion can brings speedup.
        c              3  ó�   K  — | ]>  }|j                  «       xr( t        |j                  «       t        j                  «      –— Œ@ y ­wrT   )ri  ry   r  r   r|  rN  s     rX   r  z.Scheduler.speedup_by_fusion.<locals>.<genexpr>¬
  sE   è ø€ ò  
ð ð �M‰M‹Oò JÜ˜1×.Ñ.Ó0´"×2HÑ2HÓIóJñ 
ùs   ‚AATr   r^  ©ÚCompilationErrorNc           
     ót  •— t         j                  t        j                  «      r”| ||z   k  rFt         j	                  d‰j                  «       ‰j                  «       t        ||z   | z  d›«      «       y t         j	                  d‰j                  «       ‰j                  «       t        | ||z   z  d›«      «       y y )Nz9can fuse (benchmark): fusing %s with %s cause %sx speedupú.3fz=cannot fuse (benchmark): fusing %s with %s cause %sx slowdown)r>  rô  rõ  ÚDEBUGr?  rH  r4   r5   )Úms_fusedÚms1Úms2r8  r9  s      €€rX   Ú
log_fusionz/Scheduler.speedup_by_fusion.<locals>.log_fusionÕ
  s¦   ø€ Ü×&Ñ&¤w§}¡}Ô5Ø˜c C™iÒ'Ü×$Ñ$ØSØ×.Ñ.Ó0Ø×.Ñ.Ó0Ü" s¨S¡y°HÑ&<¸SÐ%AÓCõ	ô ×$Ñ$ØWØ×.Ñ.Ó0Ø×.Ñ.Ó0Ü  H°°c±	Ñ$:¸3Ð#?ÓAõ	ð 6rZ   c                óÒ   •— ‰j                  | d¬«      }t        j                  |«      }‰j                  «       sd }||fS ‰j	                  d|¬«      }t        |t        «      sJ ‚||fS )NT)rf  Útriton_)Úkernel_nameÚsource_code)re  r   ÚloadÚuse_process_poolÚtritonry   r   )r  Úsrc_codeÚmodÚfutÚasync_compilerV   s       €€rX   Úcompile_kernelz3Scheduler.speedup_by_fusion.<locals>.compile_kernelè
  s   ø€ ð ×;Ñ;Ø¨ð <ó ˆHô ×"Ñ" 8Ó,ˆCØ ×1Ñ1Ô3Ø�ð
 ˜�:Ðð $×*Ñ*°yÈhÐ*ÓW�Ü! #¤|Ô4Ð4Ð4à˜�:ÐrZ   c              3  ó@   K  — | ]  }|j                  «       d u–— Œ y ­wrT   r  rN  s     rX   r  z.Scheduler.speedup_by_fusion.<locals>.<genexpr>ú
  s#   è ø€ ò %
Ø23ˆA×ÑÓ!¨Ô-ñ%
ùs   ‚c                ó   — | d   S r1  r¦   rñ  s    rX   r´   z-Scheduler.speedup_by_fusion.<locals>.<lambda>  s
   € °a¸±d€ rZ   rF  Úallowed_prologue_inpsr   Fc            	     ó  •— t        d«      } d }i }‰D ]V  \  }}}	 |�|j                  «        ‰j                  |«      5  ‰j                  |‰	«      \  }}|||<   || k  r|} |}d d d «       ŒX  ‰| ‰‰«       | ‰‰z   k  r|�‰j                  |«       |‰_        yy# t        $ rQ}t        j	                  t
        j                  «      r$t        j                  d‰
sdndt        |«      «       Y d }~ŒÜd }~ww xY w# 1 sw Y   ŒíxY w)NÚinfzException in compiling %s: %sr   r"  TF)r2  rn   rÕ   r>  rô  rõ  r›  r?  r™   Úswap_as_triton_callerrh  r‚  Ú_choice_timings)Úmin_ms_fusedÚms_fused_choiceÚnew_timingsÚchoiceÚfutureÚ	mod_fusedr  rœ  Úpathr`  Úepilogue_fusionÚfuture_choicesrŸ  r�  rž  r†  rV   s            €€€€€€€€rX   Úbenchmark_when_readyz9Scheduler.speedup_by_fusion.<locals>.benchmark_when_ready1  s$  ø€ Ü$ U›|�Ø"&�à �à1?ò 5Ñ-�F˜F Ið!Ø!Ð-Ø"ŸM™MœOð $×9Ñ9¸&ÓAñ 5Ø)-×)HÑ)HØ% vó*™˜ $ð /7˜ FÑ+Ø# lÒ2Ø+3˜LØ.4˜O÷5ð 5ð5ñ0 ˜<¨¨cÔ2à 3¨¡9Ò-°/Ð2MØ×8Ñ8¸ÔIØ1<�JÔ.Øà øô1 %ò !Ü%×2Ñ2´7·=±=ÔAÜ&×,Ñ,Ø ?Ù2A¡
ÀzÜ # A£ôô
 !ûð!ú÷5ð 5ús#   ›B¾$C7Â	C4Â#AC/Ã/C4Ã7D 	c                 óâ  •‡‡‡‡‡‡— ddl m}  	 ‰d   ‰d   ‰d   fD ]  }|€Œ|j                  «        Œ ‰j                  ‰d   ‰
«      \  ŠŠt	        j
                  ‰«      r	 ‰d«       y‰j                  ‰d   ‰
«      \  ŠŠt	        j
                  ‰«      r	 ‰d«       y‰j                  ‰d   ‰
«      \  ŠŠt	        j
                  ‰«      r	 ‰d«       y ‰‰‰‰«       t        d«      rW‰‰‰z   k\  rO‰‰f‰j                  vr?‰j                  j                  ‰‰f«       t        d«      j                  ˆˆˆˆˆˆfd	„«       ‰‰‰z   k  S # | $ r Y y‰	$ r}d
t        |«      v rY d }~y‚ d }~ww xY w)Nr   )ÚNoTritonConfigsErrorr   z%register spilling of the first kernelFz&register spilling of the second kernelz%register spilling of the fused kernelÚslow_fusionc            	     ó$   •— ‰‰ ‰‰‰‰‰‰ ‰z   z  dœS )N)Úkernel1_pathÚkernel1_latencyÚkernel2_pathÚkernel2_latencyÚfused_kernel_pathÚfused_kernel_latencyÚslow_down_ratior¦   )r�  rž  rœ  Úpath1Úpath2Ú
path_fuseds   €€€€€€rX   r´   zKScheduler.speedup_by_fusion.<locals>.benchmark_when_ready.<locals>.<lambda>�  s(   ø€ Ø05Ø36Ø05Ø36Ø5?Ø8@Ø3;¸sÀS¹yÑ3Iñ%€ rZ   úLoop-carried variableT)Ú)torch._inductor.runtime.triton_heuristicsr¾  rn   rh  ÚmathÚisinfr   rÔ  r!  r   rã  r™   )r¾  r©  r  r�  rž  rœ  rÈ  rÉ  rÊ  r˜  r`  Úfuture_and_mod_l1Úfuture_and_mod_l1_fusedÚfuture_and_mod_l2rŸ  rV   r@  s      @@@@@@€€€€€€€€rX   r¼  z9Scheduler.speedup_by_fusion.<locals>.benchmark_when_ready`  s˜  þ€ õð;ð *¨!Ñ,Ø)¨!Ñ,Ø/°Ñ2ð ò )˜ð
 ™?ØŸJ™J�Lð)ð "&×!@Ñ!@Ø)¨!Ñ,¨fó"‘J�C˜ô —z‘z #”ÙÐCÔDØ$à!%×!@Ñ!@Ø)¨!Ñ,¨fó"‘J�C˜ô —z‘z #”ÙÐDÔEØ$à+/×+JÑ+JØ/°Ñ2°Fó,Ñ(�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 Á+5E Â!5E ÃA3E ÅE.ÅE.ÅE)Å(E)Å)E.)rœ  r2  r�  r2  rž  r2  r˜   r�   )r  rÞ  r˜   z)tuple[Optional[LambdaFuture], ModuleType]rž   )$r  r   Úbenchmark_fusionri  ry   r  r   ÚTritonTemplateBufferrm  rC  r[  re   r‘   r  r  r“  Útriton.compiler.errorsr˜  r7  rã   rä   rª  ÚAsyncCompiler|  r€  r  r_  rK  r	  r�  r   r®  Ú max_epilogue_benchmarked_choicesr±  r¡  rk   )rV   r8  r9  Úis_multi_templateÚnode_list_1Únode_list_2Únode_list_fusedr«  r€  rõ  rÉ  Útriton_choicesr¶  Úunfused_timer¼  r˜  rª  r`  rº  rÏ  rÐ  rÑ  r»  rŸ  r�  rž  r†  r@  s   ```            @@@@@@@@@@@@@rX   Úspeedup_by_fusionzScheduler.speedup_by_fusion¤
  s]  ÿÿ€ ô  ñ  
ð ˜U�^ô 
ó 
Ðô
 ×&Ò&Ñ/@Øð ×ÑÔÜ˜u×6Ñ6Ó8¼"×:QÑ:QÔRØ×ÑÔ!Ø×ÑÔ!ð à—o‘oÓ'ˆØ˜Q‘×*Ñ*Ó,ˆÙˆˆvð �;‰;˜%ÒØà—o‘oÓ'ˆÜœyŸ™¨{¸KÓHÓIˆð
 ×Ñ Ô0Øå;ä˜˜uÓ%ˆà  Ñ#×.Ñ.Ó0ˆØÐ!Ð!Ð!ö	ô" Ÿ™×5Ñ5×BÑBÓDˆð	Ø.ð	à6ö	ò$ ¤ñ %
Ø8=¸u°~ô%
õ "
ð $×5Ñ5Ó7¸tÐCˆOñ #ð ×'Ñ'Ô)à×,Ñ,Ó.ð ô
 ˜j¬"×*@Ñ*@ÔAÐAÐAØ'×6Ñ6ˆNØ×.Ñ.Ó0‰FˆAˆsð  ×.Ñ.Ó0‰FˆAˆsñ #ð ×*Ñ*¨;Ô7à×/Ñ/°Ó<ñ ˆC�ð TVˆNØˆNÜ(.Ø×$Ñ$Ó&©Nô)ò VÑ$�˜ô " &¬%¯/©/×*<Ñ*<×*UÑ*UÔVØñ (Ü Ð(?Ô@Ø×4Ñ4¸
×8XÑ8XÒXàà 3¨¡9Ò,Ùà !Ñ#�Ø!¤F×$KÑ$KÒKÙà×5Ñ5°fÓ=ñ VØ"×)Ñ)¨6Ð*T±NÀ?Ó4SÑ*TÔU÷Vð Vð3Vô8 �>Ó" aÒ'Ø÷%!ô %!ðN (Ð'ñ !/¨{Ó ;ÐÙ .¨{Ó ;ÐÙ&4°_Ó&EÐ#÷@ô @ðD (Ð'÷oVñ Vús   ËM
Í
M	c                ó<   — | j                   |j                  «          S )z0Look up the node in Scheduler name_to_fused_node)r9  r?  r  s     rX   r{  zScheduler.get_fused_node¤  s   € à×&Ñ& t×':Ñ':Ó'<Ñ=Ð=rZ   c                óÞ  ‡ ‡‡‡— t        |«      Št        j                  t        j                  «      rBt        j                  d«       ‰D ](  }t        j                  d|j                  «       z   «       Œ* i Š	 	 	 	 	 	 dˆˆ fd„Š	 	 	 	 	 	 dˆˆˆ fd„}‰ j                  |«      D ]�  \  }} |||«       ‰ j                  |«      }‰ j                  |«      }‰ j                  ||«      sŒD‰ j                  ||«      rŒW‰ j                  ||«      }t        |«      r|||f‰|<   |||f‰|<   Œ…|sŒˆ ‰||«       Œ’ t        «       }‰j                  «       D ]j  \  }}	}
||v rŒ|j                  |«       ‰ j                  |	«      |	u sJ ‚‰ j                  |
«      |
u sJ ‚ |«       sŒO‰ j                  |	|
«      rŒb ‰|	|
«       Œl t        ‰d„ ¬«      }‰ j!                  |«      }‰ j#                  |«       |S )	a  
        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  c                óö  •— t         j                  d| j                  «       |j                  «       «       | j                  «       }|j                  «       |k(  sJ ‚‰j	                  |«      j                  | |«      }‰j                  | «       ‰j                  |«       ‰j                  |«       ‰j                  j                  |j                  «       D �ci c]  }|j                  «       |“Œ c}«       |S c c}w )Nzfusing %s with %s)r>  r?  rU   r[  ry  rë  ro  r!  r9  r
  rC  )r8  r9  r`  Únode3rO  rI  rV   s        €€rX   Úfuse_two_nodesz1Scheduler.fuse_nodes_once.<locals>.fuse_two_nodes¿  sÑ   ø€ ô ×ÑÐ0°%·.±.Ó2BÀEÇNÁNÓDTÔUà×%Ñ%Ó'ˆFØ×#Ñ#Ó%¨Ò/Ð/Ð/Ø×$Ñ$ VÓ,×1Ñ1°%¸Ó?ˆEØ×Ñ˜uÔ%Ø×Ñ˜uÔ%Ø�O‰O˜EÔ"Ø×#Ñ#×*Ñ*Ø.3¯o©oÓ.?Ö@¨�—‘“˜uÑ$Ò@ôð ˆLùò As   ÃC6c                ó  •— ‰j                  | «      ‰v s‰j                  |«      ‰v rä‰j                  ‰j                  | «      ‰j                  ‰j                  |«      d «      «      }|€J ‚|\  }}}‰j                  |d «       ‰j                  |d «       ‰j                  |«      |u sJ ‚‰j                  |«      |u sJ ‚ |«       r‰j                  | |«      rŒØ ‰||«       ‰j                  | «      ‰v rŒÏ‰j                  |«      ‰v rŒãy y rT   )r{  r  r   Úwill_fusion_create_cycle)	r8  r9  Úpending_fusionÚ
is_speedupÚ	node_key1Ú	node_key2râ  Úpending_fusionsrV   s	         €€€rX   Úresolve_pending_fusionsz:Scheduler.fuse_nodes_once.<locals>.resolve_pending_fusionsÏ  s  ø€ ð ×#Ñ# EÓ*¨oÑ=Ø×&Ñ& uÓ-°Ñ@à!0×!4Ñ!4Ø×'Ñ'¨Ó.Ø#×'Ñ'¨×(;Ñ(;¸EÓ(BÀDÓIó"�ð &Ð1Ð1Ð1à3AÑ0�
˜I yØ×#Ñ# I¨tÔ4Ø×#Ñ# I¨tÔ4à×*Ñ*¨9Ó5¸ÑBÐBÐBØ×*Ñ*¨9Ó5¸ÑBÐBÐBá!”| t×'DÑ'DÀUÈEÔ'RØá˜y¨)Ô4ð' ×#Ñ# EÓ*¨oÒ=Ø×&Ñ& uÓ-°Ô@rZ   c                ó   — | j                   S rT   rà  rñ  s    rX   r´   z+Scheduler.fuse_nodes_once.<locals>.<lambda>  s
   € °!·+±+€ rZ   rF  )r8  rG   r9  rG   r˜   rG   rC  )r   r>  rô  rõ  r›  r?  rí   Úget_possible_fusionsr{  r:  rä  rÝ  Úcallabler’   r!  rK  rÎ  r:  )rV   r  rL   rê  r8  r9  ÚspeedupÚseen_pair_speedup_fnÚis_speedup_fnrç  rè  râ  rI  ré  s   `          @@@rX   rX  zScheduler.fuse_nodes_once¨  s*  û€ ô ! Ó'ˆÜ×"Ñ"¤7§=¡=Ô1Ü×ÑÐ;Ô<Ø#ò @�Ü× Ñ  ¨×(<Ñ(<Ó(>Ñ!>Õ?ð@ð ð 	ð
	Ø$ð	Ø->ð	àö	ð 	5Ø$ð	5Ø->ð	5à÷	5ð2 !×5Ñ5°eÓ<ò 	-‰LˆE�5ñ $ E¨5Ô1Ø×'Ñ'¨Ó.ˆEØ×'Ñ'¨Ó.ˆEà�}‰}˜U EÕ*°4×3PÑ3PØ�uõ4ð ×0Ñ0°¸Ó>�Ü˜GÔ$Ø.5°u¸eÐ-D�O EÑ*Ø.5°u¸eÐ-D�O EÑ*ØáØá˜u eÕ,ð)	-ô, @J»|ÐØ3B×3IÑ3IÓ3Kò 	5Ñ/ˆM˜9 iØÐ 4Ñ4Øà ×$Ñ$ ]Ô3à×&Ñ& yÓ1°YÑ>Ð>Ð>Ø×&Ñ& yÓ1°YÑ>Ð>Ð>á� t×'DÑ'DØ˜9õ(ñ ˜y¨)Õ4ð	5ô �{Ñ(=Ô>ˆØ×.Ñ.¨uÓ5ˆØ×!Ñ! %Ô(ØˆrZ   c                ó  — t        | j                  «      }d}t        | j                  «      }t        j	                  d|«       t        t        j                  | «      «      D �]  \  }}t        j                  |«      }t        |«      dk  rŒ+|�||kD  r nî| j                  |«      st        j	                  d|«       Œ\|dz  }t        j                  dkD  }t        |d   j                  |d|¬«      }t        j                  d	t        |«      |«       |D ]  }	|j                  |	«       Œ |j                  |«       | j                   j#                  |j%                  «       D �
ci c]  }
|
j'                  «       |“Œ c}
«       �Œ! t)        |d
„ ¬«      | _        | j+                  | j                  «      | _        t        j                  d||t        | j                  «      «       | j-                  | j                  «       yc c}
w )z'
        Groups parallel nodes
        r   z2ComboKernels: Generating with num_ck_nodes = %d...rÏ  Nz)ComboKernels: Not speeding up %d-th groupr   Trü  z0ComboKernels: Combining %d nodes for %d-th groupc                ó   — | j                   S rT   rà  rñ  s    rX   r´   z5Scheduler.create_combo_kernel_nodes.<locals>.<lambda>8  s
   € °q·{±{€ rZ   rF  zEGenerated ComboKernel nodes: %d ComboKernels, totally %d -> %d nodels)r   r  rk   rÖ   r?  r  r+  rh  rW  Úspeedup_by_combo_kernelr   rþ  rK   rï   ro  r!  r9  r
  rC  rU   rK  rÎ  r:  )rV   r·  rI  rÂ  Únum_nodes_origÚnumr’  rH  rØ  rL   rO  s              rX   rØ  z#Scheduler.create_combo_kernel_nodes  sÀ  € ô ! §¡Ó,ˆØˆÜ˜TŸZ™Z›ˆÜ�	‰	ÐFÈÔUÜ'Ü&×DÑDÀTÓJó
ó 	‰NˆC�ô 3×CÑCÀIÓNˆIÜ�9‹~ Ò!ØØÐ'¨E°LÒ,@ÙØ×/Ñ/°	Ô:Ü—	‘	ÐEÀsÔKØØ�Q‰JˆEÜ$×;Ñ;¸aÑ?ˆOÜ4Ø˜!‘×&Ñ&ØØ*.Ø /ô	ˆKô �H‰HØBÜ�I“Øôð
 "ò )�Ø×"Ñ" 4Õ(ð)à�O‰O˜KÔ(Ø×#Ñ#×*Ñ*Ø4?×4IÑ4IÓ4KÖL¨q�—‘“˜{Ñ*ÒLöð7	ô< ˜KÑ-BÔCˆŒ
Ø×3Ñ3°D·J±JÓ?ˆŒ
Ü�‰ØSØØÜ�—
‘
‹Oô		
ð 	×!Ñ! $§*¡*Õ-ùò Ms   Å!G=
c                óH   — |D ]  }|j                  | j                  «       Œ y rT   )r:  r9  )rV   r  rL   s      rX   r:  zScheduler.prune_redundant_depsB  s%   € Øò 	?ˆDØ×%Ñ% d×&=Ñ&=Õ>ñ	?rZ   c                óÈ  ‡ ‡	‡
— g Š	t        t        t        t        f      «       Š
dˆ	ˆ
ˆ fd„}t        j                  t
        «      }|D ]=  }‰ j                  |«      rŒ|j                  «       D ]  }||   j                  |«       Œ Œ? |j                  «       D ]
  } ||«       Œ t        j                  rat        j                  t
        «      }|D ]&  }t        |dd«      }|sŒ||   j                  |«       Œ( |j                  «       D ]
  } ||«       Œ ‰ j                  ‰	«      Š	‰	j                  ‰ j                  d¬«       t         j#                  dt%        ‰	«      «       ‰	S )z^
        Helper to find all legal fusion opportunities, sorted by self.score_fusion()
        c                óP  •— t        | «      D ]—  \  }}| |dz   d  D ]‡  }||f}|‰v rŒ‰j                  |«       ‰j                  ||«      r‰j                  |«       ŒA|j	                  «       s|j                  «       sŒb‰j                  ||«      sŒu‰j                  ||f«       Œ‰ Œ™ y r1  )r  r!  r:  r¡  ri  rm  )r  Únode1_indexr8  r9  rG  Úpossible_fusionsr?  rV   s        €€€rX   Úcheck_all_pairsz7Scheduler.get_possible_fusions.<locals>.check_all_pairsO  s±   ø€ Ü&/°Ó&6ò @Ñ"�˜UØ" ;°¡?Ð#4Ð5ò @�EØ  %˜.�CØ˜d‘{Ø Ø—H‘H˜S”Mà—}‘} U¨EÔ2Ø(×/Ñ/°Õ4Ø×+Ñ+Ô-°×1AÑ1AÕ1CÈÏÉØ˜uõJð )×/Ñ/°¸°Õ?ñ@ñ@rZ   rª   NT)rG  Úreversezfound %d possible fusions©r  r4  r˜   r�   )r   rí  rG   rá  r   r‘   Úunfusable_noder  r¡  r’   r   Úaggressive_fusionrÑ   Ú*get_possible_fusions_with_highest_priorityrž  Úscore_fusion_keyr>  r?  rk   )rV   r  rû  Úbuffer_names_groupingrL   r¿   Únode_groupingÚgroup_groupingrª   rú  r?  s   `        @@rX   rì  zScheduler.get_possible_fusionsF  sh  ú€ ð ÐÜœ%Ô 1Ô3DÐ DÑEÑFÓHˆ÷	@ô  !,× 7Ñ 7¼Ó =ÐØò 	8ˆDØ×"Ñ" 4Ô(ØØ×-Ñ-Ó/ò 8�Ø% cÑ*×1Ñ1°$Õ7ñ8ð	8ð
 3×9Ñ9Ó;ò 	+ˆMÙ˜MÕ*ð	+ô ×#Ò#Ü(×4Ñ4´TÓ:ˆNØò 7�Ü  g¨tÓ4�ÚØ" 5Ñ)×0Ñ0°Õ6ð7ð "0×!6Ñ!6Ó!8ò /�Ù Õ.ð/ð  ×JÑJØó
Ðð 	×Ñ $×"7Ñ"7ÀÐÔFÜ×ÑÐ4´cÐ:JÓ6KÔLØÐrZ   c                óÒ  ‡ ‡‡‡‡— t        t           «       Šdˆˆˆˆ ˆfd„Š|j                  «       j                  j	                  «       |j                  «       j                  j	                  «       z  Š|j
                  j                  j	                  «       |j
                  j                  j	                  «       z  ‰z
  Št        ˆˆ fd„‰D «       «      }|r t        ||«      d«       |S )z~
        Finds whether there's a path from node1 to node2 (or vice-versa)
        caused indirectly by other fusions.
        c                ó  •— t        | t        «      rq| ‰vrm‰j                  | «       | j                  «       j	                  ‰«      ryt        ‰| j                  z  «      xs" t        ˆˆfd„| j                  ‰z
  D «       «      S y)NFc              3  óH   •K  — | ]  } ‰‰j                   |   «      –— Œ y ­wrT   rE  ©r  rO  Ú
found_pathrV   s     €€rX   r  zIScheduler.will_fusion_create_cycle.<locals>.found_path.<locals>.<genexpr>“  s+   øè ø€ ò Hàñ # 4×#:Ñ#:¸1Ñ#=×>ñHùó   ƒ")ry   râ  r!  rD  ÚissubsetrŸ   r¸   r  )rL   Úcombined_ancestorsÚcombined_namesr	  rV   Úvisiteds    €€€€€rX   r	  z6Scheduler.will_fusion_create_cycle.<locals>.found_path‚  s�   ø€ ä˜$Ô 2Ô3¸ÀGÑ8KØ—‘˜DÔ!Ø×+Ñ+Ó-×6Ñ6Ð7IÔJð !ô   °·±Ñ ?Ó@ò ÄCô Hà!%§¡Ð2DÑ!DôHó Eð ð rZ   c              3  óH   •K  — | ]  } ‰‰j                   |   «      –— Œ y ­wrT   rE  r  s     €€rX   r  z5Scheduler.will_fusion_create_cycle.<locals>.<genexpr>¡  s!   øè ø€ ÒW¸q‘J˜t×6Ñ6°qÑ9×:ÑWùr
  zwill create cycle©rL   rG   r˜   rŸ   )r   râ  rD  Ú_dictrÄ  r¸   r  r7  )rV   r8  r9  Úcycler  r  r	  r  s   `   @@@@rX   rä  z"Scheduler.will_fusion_create_cyclex  sÇ   ü€ ô Ô/Ñ0Ó2ˆ÷	ñ 	ð2 ×%Ñ%Ó'×-Ñ-×2Ñ2Ó4Ø×'Ñ'Ó)×/Ñ/×4Ñ4Ó6ñ7ð 	ð
 �O‰O×!Ñ!×&Ñ&Ó(¨5¯?©?×+@Ñ+@×+EÑ+EÓ+GÑGØñÐô ÔWÐDVÔWÓWˆÙØ#ŒI�e˜UÓ#Ð$7Ô8ØˆrZ   c                ó�  ‡ ‡— ddl mŠ 	 	 	 	 dˆ fd„} ||«      } ||«      }t        ˆfd„|D «       «      }t        ˆfd„|D «       «      }|j                  |«      }d}	|D ]  }
	 |	t	        |
d   «      z  }	Œ ‰ j                  ||«      }t        j                  j                  j                  |	d	|z  «      ry
y# t
        $ r Y  yw xY w)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 ndoes. 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                ó0  •— g }| j                   j                  D ]y  }‰j                  j                  |j                  «      }|sŒ+t        |j                  «      dk(  sŒD|j                  j                  «       sŒ_|j                  |j                  «       Œ{ |S r1  )
r¬   rÓ   rƒ   r  r]   rk   rQ   rL   Úhas_tensor_outputr¡  )rL   r¾   r5  r¿   rV   s       €rX   Ú_find_single_user_inputszKScheduler.can_fusion_increase_peak_memory.<locals>._find_single_user_inputs½  sw   ø€ ð ˆFØ×&Ñ&×,Ñ,ò ,�Ø×&Ñ&×*Ñ*¨2¯7©7Ó3�Úœ3˜sŸy™y›>¨QÓ.°3·8±8×3MÑ3MÕ3OØ—M‘M #§(¡(Õ+ð,ð ˆMrZ   c              3  ó.   •K  — | ]  } ‰|«      –— Œ y ­wrT   r¦   ©r  r¿   r  s     €rX   r  z<Scheduler.can_fusion_increase_peak_memory.<locals>.<genexpr>Ë  ó   øè ø€ Ò#S¸cÑ$4°S×$9Ñ#Sùr7  c              3  ó.   •K  — | ]  } ‰|«      –— Œ y ­wrT   r¦   r  s     €rX   r  z<Scheduler.can_fusion_increase_peak_memory.<locals>.<genexpr>Ì  r  r7  r   rÏ  Fé    T)rL   rG   r˜   zlist[ir.Buffer])r�  r  r   Úintersectionr›   ró  Úscore_fusion_memoryrD   r|   rÁ  Ústatically_known_gt)rV   r8  r9  r  Úlhs_dep_nodesÚrhs_dep_nodesÚlhs_reuse_keysÚrhs_reuse_keysÚcommon_reuse_keysÚmemory_overheadrG  Ú	bw_savingr  s   `           @rX   Úcan_fusion_increase_peak_memoryz)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°EÓ:ˆ	ô �7‰7×Ñ×/Ñ/°ÀÀiÁÔPØØøô ò âðús   Á$B8Â8	CÃCc                ó¤   — t        t        |j                  |j                  z
  «      t        |j                  |j                  z
  «      «      }|dkD  S )aB  
        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 heurisitic 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¯   )rV   r8  r9  Úproximity_scores       rX   Úare_long_distant_nodesz Scheduler.are_long_distant_nodesß  sE   € ô* Ü�—‘ %§/¡/Ñ1Ó2Ü�—‘ %§/¡/Ñ1Ó2ó
ˆð  Ñ#Ð#rZ   c                óþ  — i }|j                   j                  «       D �ci c]  }|j                  |“Œ }}|j                   j                  «       D �ci c]  }|j                  |“Œ }}|D �]}  }t        j                  j                  |«      }	||   }
||   }t        |
t        «      rt        |t        «      sdt        |
«      › dt        |«      › �||<   Œk|
j                  «       |j                  «       k7  r(d|
j                  «       › d|j                  «       › �||<   Œ´t        |
j                  «      t        |j                  «      k7  rd||<   Œå|
j                  «       }|j                  «       }||k7  rd|› d|› �||<   �Œ|
j                  «       |j                  «       k(  rd|
› d|› �||<   �ŒEd}t        |	t        j                  «      sd|	j                   › �}d	|
› d|› d
|› �||<   �Œ€ t#        |«      S c c}w c c}w )z}
        Try to decide reasons why fusion fail due to no shared memory even though
        there are common buffers.
        znot MemoryDep: z v.s. zdifferent numel: Ú	broadcastzdifferent offset: zMismatch loop orders: rÛ   zLayout: zUnknown reason: z. )r¬   r|  r]   rD   r|   rÔ  ry   r'   re   rî  rC   rÇ  Ú
get_offsetÚnormalize_with_stride_orderr   r×  rg   r™   )rV   r8  r9  Úcommon_buf_namesÚreasonsrþ   Únode1_name2depÚnode2_name2deprX  r¿   Úlhs_depÚrhs_depÚlhs_offÚrhs_offÚ
layout_strs                  rX   Údecide_fusion_fail_reasonz#Scheduler.decide_fusion_fail_reasonú  s  € ð ˆØ38×3DÑ3D×3UÑ3UÓ3WÖX¨C˜#Ÿ(™( C™-ÐXˆÐXØ38×3DÑ3D×3UÑ3UÓ3WÖX¨C˜#Ÿ(™( C™-ÐXˆÐXà(ó ,	ˆHÜ—'‘'×$Ñ$ XÓ.ˆCØ$ XÑ.ˆGØ$ XÑ.ˆGä˜g¤yÔ1¼ÀGÌYÔ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Ø'¨¯
©
 |Ð4�
à" 7 )¨6°'°¸"¸Z¸LÐIð �HÓðU,	ô\ �7‹|Ðùòc YùÚXs   ŸG5ÁG:c                óÒ  — t         j                  rt        d„ ||fD «       «      ry|j                  j	                  «       }|j                  j	                  «       }||z  }|sy|j                  j                  «       D �ci c]  }|j                  |“Œ }}|j                  j                  «       D �ci c]  }|j                  |“Œ }}g }	|D ]y  }
||
   }||
   }|j                  «       |j                  «       k(  sŒ/|	j                  t        j                  j                  j                  |j                  «       d¬«      ||f«       Œ{ t        |	«      dk(  ryt        |	d„ ¬«      \  }}}t!        |t"        «      rt!        |t"        «      sy|j$                  |j$                  k7  r3|j'                  «       |j'                  «       k(  r| j)                  |«      S y|j+                  «       s|j-                  ||«       nV|j+                  «       s|j-                  ||«       n3t.        j1                  d|j3                  «       |j3                  «       «       | j5                  ||«      S c c}w c c}w )zð
        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 compatibile with node1 if that's more efficient.
        c              3  ó<   K  — | ]  }|j                  «       –— Œ y ­wrT   )ra  rN  s     rX   r  z>Scheduler.shared_data_after_reordering_loop.<locals>.<genexpr>C  s   è ø€ ò 8
ØˆA�H‰H�Jñ8
ùrB  r   r¿  c                ó   — | d   S rû  r¦   rñ  s    rX   r´   z=Scheduler.shared_data_after_reordering_loop.<locals>.<lambda>g  s
   € ÀÀ1Á€ rZ   rF  z?Don't reorder loops since both nodes are reductions: %s v.s. %s)r   r{  r  r¬   Úbuffer_namesr|  r]   r/  r¡  rD   r|   rÁ  rÂ  rî  rk   r  ry   r'   r•  ru  Údep_size_hintrd  rô   r˜  r?  rU   r  )rV   r8  r9  Únode1_buffer_namesÚnode2_buffer_namesÚcommon_buffer_namesrþ   r2  r3  Ú
candidatesÚbuffer_namer4  r5  Ú_numels                 rX   Ú!shared_data_after_reordering_loopz+Scheduler.shared_data_after_reordering_loop8  sA  € ô ×0Ò0´Cñ 8
Ø!&¨ ô8
ô 5
ð à"×.Ñ.×;Ñ;Ó=ÐØ"×.Ñ.×;Ñ;Ó=Ðà0Ð3EÑEÐÙ"Øà38×3DÑ3D×3UÑ3UÓ3WÖX¨C˜#Ÿ(™( C™-ÐXˆÐXØ38×3DÑ3D×3UÑ3UÓ3WÖX¨C˜#Ÿ(™( C™-ÐXˆÐ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±~Ô#FÑ ˆ�˜ä˜'¤9Ô-´ZÀÌÔ5SØà×Ñ˜w×/Ñ/Ò/ð
 × Ñ Ó" g×&7Ñ&7Ó&9Ò9Ø×)Ñ)¨'Ó2Ð2Øð ×!Ñ!Ô#Ø×+Ñ+¨G°WÕ=Ø×#Ñ#Ô%Ø×+Ñ+¨G°WÕ=ä×#Ñ#ØQØ—‘Ó Ø—‘Ó ôð ×'Ñ'¨¨uÓ5Ð5ùòe YùÚXs   Á>IÂ0I$c                ó„   — t        |t        t        f«      xr) |j                  «        xr t	        |j
                  «       S )z>
        Is this node unfusable under any conditions.
        )ry   rß  r‹  ri  rA   rL   r  s     rX   rþ  zScheduler.unfusable_nodeƒ  sD   € ô
 �tÔ7Ô9OÐPÓQò CØ×$Ñ$Ó&Ð&òCä7¸¿	¹	ÓBÐBð	
rZ   c                óò  — |j                  «       t        j                  j                  k  ry|j	                  «       }|j                  «       }d}|||z  kD  r	 |d«       yt        d„ |j                  «       D «       «      }|t        j                  j                  j                  j                  fk(  r	 |d«       yd	d„} ||j                  «       j                  «      r|j                  «       s	 |d«       yy)
zT
        Heuristics to avoid benchmarking predictably slow prologue fusions
        Tgš™™™™™ñ?z@prologue fusion will not increase amount of bytes read in kernelFc              3  ó¨   K  — | ]J  }|j                   �<|j                   j                  «       D ]  }|j                  dk(  r|j                  –— Œ! ŒL y ­w)NÚcall_function)rL   r   rW   r¢  )r  rO  r  s      rX   r  zEScheduler.check_prologue_fusion_heuristics_fusable.<locals>.<genexpr>­  sT   è ø€ ò 
àØ�v‰vÐ!Ø—V‘V×'Ñ'Ó)ò	
ð Ø�t‰t�Ò&ð	 �H�Hð
Øñ
ùs   ‚AAz\prologue fusion will not increase attempt to fuse in padding bc it increases unaligned readsc                ó<   — | j                   dk  xr | j                  S )NrÏ  )ÚitemsizeÚis_floating_point)r  s    rX   Úlow_prec_fpzGScheduler.check_prologue_fusion_heuristics_fusable.<locals>.low_prec_fpº  s   € Ø—>‘> QÑ&ÒB¨5×+BÑ+BÐBrZ   zVprologue fusion that must be upcast to fp32 not profitable for low precision templates)r  ztorch.dtyper˜   rŸ   )rD  rD   r|   Úinvoke_quant_opsr¶  r¸  rí  rC  rã   ÚopsÚatenÚconstant_pad_ndÚdefaultr  r  rR  )	rV   Úprologue_noder!  r@  Ú
read_bytesÚwrite_bytesÚBYTES_THRESHOLD_MULTIPLIERr©  rM  s	            rX   Ú(check_prologue_fusion_heuristics_fusablez2Scheduler.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Ø!×>Ñ>Ô@áØhôð àrZ   c                ó  ‡— ||u ryt        ||«      }|j                  «       r0| j                  |j                  «       «      j	                  ||«      ryt        |t        «      st        |t        «      r	 |d«       yt        |t        t        f«      r|j                  «       s	 |d«       yt        |t        t        f«      r|j                  «       s	 |d«       y|j                  «       |j                  z  r	 |d«       y|j                  «       �r!t        j                  s	 |d«       y|j                  «       s|j                  «       r	 |d«       y|j                  «       }t        |t        j                   «      s	 |d	«       y|j#                  «       }t%        d
„ |j&                  D «       «      |z
  }|j)                  «       |z  r	 |d«       y|j+                  «       s|j+                  «       r	 |d«       y|j-                  «       Š‰dd D ]B  }|j/                  «       }|D ]+  }	t1        ˆfd„|	j2                  D «       «      rŒ" |d«         y ŒD t        |t4        «      s|gn*|j6                  D �
cg c]  }
|
j                  «       sŒ|
‘Œ c}
}t9        |«      dk(  sJ ‚|d   }t9        ‰d   j:                  «      dk(  rSt9        ‰d   j:                  d   j2                  «      dk(  r+‰d   j:                  d   j2                  d   j<                  |u s	 |d«       y| j?                  |||«      sy|j                  «       r9|j+                  «       s |j                  «       st        j@                  s	 |d«       y|j)                  «       tB        jD                  jF                  z  s+|j)                  «       tB        jD                  jF                  z  r	 |d«       y|j                  «       }|j                  «       }||k7  r |d||«       y~| jI                  ||«      }|t        jJ                  k  r"t        jL                  r| jO                  ||«      }tP        jS                  tT        jV                  «      r4tP        jY                  d|j[                  «       |j[                  «       |«       tB        j\                  j_                  | |||«      sy|j                  «       |j                  z  rY| ja                  ||«      xrE tB        j\                  ja                  | |||«      xr! | j                  |«      ja                  ||«      S tB        j\                  jc                  | |||«      xr! | j                  |«      jc                  ||«      S c c}
w )zj
        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  ó<   K  — | ]  }|j                  «       –— Œ y ­wrT   r>  )r  Úinps     rX   r  z%Scheduler.can_fuse.<locals>.<genexpr>ÿ  s   è ø€ ÒE¨c˜3Ÿ<™<Ÿ>ÑEùrB  z;prologue fusion not implemented for kernel for these inputsz:template prologue can only fuse functional pointwise nodesNr›  c              3  ó:   •K  — | ]  }|j                   ‰v –— Œ y ­wrT   rÊ  )r  ro   Úprologue_nodess     €rX   r  z%Scheduler.can_fuse.<locals>.<genexpr>  s   øè ø€ ÒQ¸t˜tŸy™y¨NÔ:ÑQùry  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)z%s and %s has %s shared data)2r7  ri  ry  r[  Úcan_fuse_multi_outputs_templatery   rä  rß  r‹  rD  r¸   r   Úprologue_fusionrd  r  r   rÓ  Úget_allowed_prologue_inpsr   rú  rH  r  rC  r»   rQ  rQ   râ  rË  rk   r¼   rL   rW  rº  rD   r|   Úno_fuse_buffer_namesr  Úscore_fusion_memory_thresholdr{  rE  r˜  rô  rõ  r›  r?  rU   Úchoicesr:  Úcan_fuse_verticalÚcan_fuse_horizontal)rV   r8  r9  r@  r  r®  Úunsupported_prologue_argsrL   Ú	node_outsrÙ   rO  Útemplate_snodesÚtemplate_snoder`  Údevice2Úshared_data_scorer\  s                   @rX   r:  zScheduler.can_fuseÈ  s
  ø€ ð �E‰>Øä˜˜uÓ%ˆà×ÑÔ 4×#3Ñ#3Ø×ÑÓó$
ç
)Ñ
)¨%°Ó
7ð$8ð ä�eÔ1Ô2´jØÔ'ô7
ñ ÐAÔBØä�uÔ8Ô:PÐQÔRØ×%Ñ%Ô'áÐ(Ô)Øä�uÔ8Ô:PÐQÔ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ÙÐPÔQØà"Ÿ_™_Ó.ˆNØ& s¨Ð+ò %�Ø ×,Ñ,Ó.�	Ø$ò %�CÜÓQÀsÇyÁyÔ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Øà×ÑÔØ×*Ñ*Ô,Ø×!Ñ!Ô#Ü×)Ò)áÐ1Ô2Øà×"Ñ"Ó$¤q§w¡w×'CÑ'CÒCØ×"Ñ"Ó$¤q§w¡w×'CÑ'CÒCáÐ5Ô6Øà×!Ñ!Ó#ˆØ×"Ñ"Ó$ˆØ�WÒÙÐ,¨f°gÔ>ØØà ×4Ñ4°U¸EÓBÐà¤× DÑ DÒDÜ×1Ò1à $× FÑ FÀuÈeÓ TÐä×)Ñ)¬'¯-©-Ô8Ü×#Ñ#Ø.Ø—‘Ó Ø—‘Ó Ø!ô	ô �y‰y×!Ñ! $¨¨uÐ6GÔHØà×$Ñ$Ó&¨¯©Ò8ð ×&Ñ& u¨eÓ4ò MÜ—I‘I×/Ñ/°°e¸UÐDUÓVòMà×$Ñ$ VÓ,×>Ñ>¸uÀeÓLðô —9‘9×0Ñ0Ø�e˜UÐ$5óò Mà×"Ñ" 6Ó*×>Ñ>¸uÀeÓLðMùòC Bs   É5VÊVc                óÈ  — |j                  «       }t        ||«      }t        t        «      }|j                  D ]j  }| j
                  j                  |j                  |j                  «      }t        |t        «      r| j                  |||«      rŒW||   j                  |«       Œl |j                  j                  D ]€  }t        |t        «      sŒ|j                  | j
                  j                  |j                  |j                  «      «      }	|	sŒV|	D ]&  }
| j                  |
|«      sŒ|	j!                  |
«       Œ( Œ‚ t#        d„ t$        j&                  j)                  |j+                  «       «      D «       «      }||z  r	 |d«       y|j-                  «       }|D ]E  }| j.                  |   j1                  «       }|| j2                  |   j4                  z  sŒ= |d«        y y)a  
        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  ó4   K  — | ]  }|j                   –— Œ y ­wrT   r  r  s     rX   r  z.Scheduler.can_fuse_vertical.<locals>.<genexpr>z  s   è ø€ ò $
àð �H�Hñ$
ùr  zmemory deps did not matchFz(intermediate nodes between node1 & node2T)rH  r7  r   r‘   r­   rË  r  r]   ry   r)   Úfusable_weak_depr¡  r¬   rÒ   r'   Úfusable_read_and_writero  r   r  r  r­  r’   rD  rƒ   rY   r9  r¸   )rV   r8  r9  Únode1_buf_namesr@  Úremaining_deps_by_namerþ   r]   ÚcdÚ	remainingr5  Úremaining_depsÚnode1_op_namesr.  s                 rX   rc  zScheduler.can_fuse_vertical[  sÃ  € ð  ×0Ñ0Ó2ˆÜ˜˜uÓ%ˆÜ7BÄ4Ó7HÐà×+Ñ+ò 	5ˆCØ×(Ñ(×,Ñ,¨S¯X©X°s·x±xÓ@ˆDÜ˜#œwÔ'¨D×,AÑ,AÀ#ÀuÈeÔ,TØØ" 4Ñ(×/Ñ/°Õ4ð		5ð ×#Ñ#×*Ñ*ò 		-ˆBÜ˜b¤)Ô,ØØ.×2Ñ2Ø×%Ñ%×)Ñ)¨"¯'©'°2·7±7Ó;óˆIò Ø#ò -�BØ×2Ñ2°2°rÕ:Ø!×(Ñ(¨Õ,ñ-ð		-ô $ñ $
ä —‘×4Ñ4Ð5K×5RÑ5RÓ5TÓUô$
ó 
ˆð
 ˜OÒ+ñ
 Ð+Ô,Øà×2Ñ2Ó4ˆØ"ò 	ˆDØ×&Ñ& tÑ,×=Ñ=Ó?ˆGØ × 7Ñ 7¸Ñ @× JÑ JÓJÙÐ>Ô?Ùð		ð rZ   c                ó   ‡— |j                   |j                  «       vry|j                  j                  D �cg c]  }|j                   |j                  k(  r|‘Œ }}t        |«      dk7  ry|d   Št        ‰t        «      sJ ‚t        ‰j                  t        j                  «      ry| j                  |j                     }|j                  j                  D �cg c]  }|j                   |k(  sŒ|‘Œ }}t        ˆfd„|D «       «      S c c}w c c}w )NFr   r   c              3  óø   •K  — | ]q  }t        |t        «      xr[ t        |j                  t        j
                  «       xr4 |j                  ‰j                  k(  xr |j                  ‰j                  k(  –— Œs y ­wrT   )ry   r'   r   rÆ  r   ÚTMPrÇ  )r  r‘  rê  s     €rX   r  z-Scheduler.fusable_weak_dep.<locals>.<genexpr>©  sm   øè ø€ ò 
ð
 ô	 �tœYÓ'ò (Ü'¨¯
©
´D·H±HÓ=Ð=ò(à—
‘
˜eŸk™kÑ)ò(ð —	‘	˜UŸZ™ZÑ'ó(ñ
ùs   ƒA7A:)r]   rH  r¬   rÒ   r  rk   ry   r'   r   rÆ  r   rw  r  rÓ   rQ  )	rV   Úweak_depr8  r9  rê  Úmutating_writesÚ	real_namer‘  Úrelevant_readss	       `    rX   rm  zScheduler.fusable_weak_dep�  s
  ø€ ð �=‰= × 6Ñ 6Ó 8Ñ8Øð ×*Ñ*×1Ñ1ö
àØ�z‰z˜X×2Ñ2Ò2ò ð
ˆð 
ô
 ˆÓ 1Ò$ØØ Ñ"ˆÜ˜%¤Ô+Ð+Ð+ä˜uŸ{™{¬D¯H©HÔ5Øà×+Ñ+¨H×,AÑ,AÑBˆ	à"×.Ñ.×4Ñ4ö
Ø¸¿	¹	ÀYÓ8NŠDð
ˆð 
ô ó 
ð
 'ô
ó 
ð 	
ùò#
ùò
s   ·"DÃDÃ,Dc                óì  — t        |t        «      �rH| j                  j                  |j                  |j                  «      }||j                  k7  sHt        |j                  t        j                  «      s$t        |j                  t        j                  «      ryt        j                  r9|j                  |j                  k7  r |j                  «       }|j                  «       }|j                  |j                  k(  xr\ t        |j                  «      t        |j                  «      k\  xr/ |j                  d t        |j                  «       |j                  k(  S t        |t        «      r‹| j                  j                  |j                  |j                  «      }| j                  j                  |j                  |j                  «      }|j                   |j                   k(  r|j                   �||k(  ryyr‰   )ry   r'   rË  r  r]   r   rÆ  r   rw  r   r{  r•  ru  rk   rÇ  r(   rÌ  )rV   r‘  rê  Ú	read_nameÚ
write_names        rX   rn  z Scheduler.fusable_read_and_writeµ  s`  € Ü�dœIÕ&Ø×-Ñ-×1Ñ1°$·)±)¸T¿Y¹YÓGˆIð ˜UŸZ™ZÒ'Ü& t§z¡z´4·8±8Ô<Ü& u§{¡{´D·H±HÔ=àä×0Ò0°T·]±]ÀeÇnÁnÒ5Tð —~‘~Ó'�ØŸ™Ó)�ð —
‘
˜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Ð*Ø Ò+àØrZ   c                óÆ   — d}|| j                   vr2	 |j                  «       s|j                  «       }|| j                   |<   |S | j                   |   }|S # t        $ r Y Œ-w xY wrû  )r°  Úhas_unbacked_symbolsÚnumbytes_hintÚKeyError)rV   rþ   Úress      rX   r>  zScheduler.dep_size_hint×  sz   € ØˆØ�d×0Ñ0Ñ0ðØ×/Ñ/Ô1Ø×+Ñ+Ó-�Cð /2ˆD×&Ñ& sÑ+ð ˆ
ð ×,Ñ,¨SÑ1ˆCØˆ
øô ò ñ ð	ús   ’ A Á	A ÁA c                ó2  ‡ — t        |j                  j                  «      t        |j                  j                  «      z   }t        |j                  j                  «      t        |j                  j                  «      z   }t	        ||«      dz  t        ||«      k  r‰||kD  r|}|}|}|j                  j                  |j                  j                  z  D �cg c]4  }||j                  j                  v s||j                  j                  v r|‘Œ6 }}t        ˆ fd„|D «       «      S |j                  j                  |j                  j                  z  |j                  j                  |j                  j                  z  z  }t        ˆ fd„|D «       «      S c c}w )zn
        The first term in our fusion score that estimates number of saved
        memory operations.
        rH  c              3  ó@   •K  — | ]  }‰j                  |«      –— Œ y ­wrT   ©r>  r(  s     €rX   r  z0Scheduler.score_fusion_memory.<locals>.<genexpr>þ  s   øè ø€ Ò?°3�t×)Ñ)¨#×.Ñ?ùrz  c              3  ó@   •K  — | ]  }‰j                  |«      –— Œ y ­wrT   r†  r(  s     €rX   r  z0Scheduler.score_fusion_memory.<locals>.<genexpr>  s   øè ø€ ÒI¨s�4×%Ñ% c×*ÑIùrz  )rk   r¬   rÓ   rÒ   rÙ  r  r»  )	rV   r8  r9  Únode1_dep_lenÚnode2_dep_lenÚtmprþ   r$  Úcommon_memory_depss	   `        rX   r  zScheduler.score_fusion_memoryç  sh  ø€ ô ˜E×-Ñ-×3Ñ3Ó4´s¸5×;LÑ;L×;SÑ;SÓ7TÑTˆÜ˜E×-Ñ-×3Ñ3Ó4´s¸5×;LÑ;L×;SÑ;SÓ7TÑTˆô ˆ}˜mÓ,¨qÑ0´3°}ÀmÓ3TÒTØ˜}Ò,Ø�Ø�Ø�ð !×,Ñ,×2Ñ2°U×5FÑ5F×5MÑ5MÑMöàØ˜%×+Ñ+×1Ñ1Ñ1°S¸E×<MÑ<M×<TÑ<TÑ5Tò ðˆDð ô Ó?¸$Ô?Ó?Ð?à#×/Ñ/×5Ñ5¸×8IÑ8I×8PÑ8PÑPØ×Ñ×#Ñ# e×&7Ñ&7×&>Ñ&>Ñ>ñ
Ðô ÓIÐ6HÔIÓIÐIùòs   Ã9Fc                óÀ  — t        |«      dk(  r|S i }|D ]…  \  }}|j                  «       |j                  «       k(  sJ ‚|j                  «       }t        | j                  |«      j	                  ||«      «      }||vr	||fg||<   Œp||   j                  ||f«       Œ‡ t        |j                  «       t        j                  d«      ¬«      d   }t        |«      dkD  sJ ‚|S )Nr   rF  r   )
rk   r[  r›   ry  Úget_fusion_pair_priorityr¡  rÙ  r	  ÚoperatorÚ
itemgetter)rV   rú  Ú"possible_fusions_group_by_priorityr8  r9  r`  Úfusion_pair_priorityÚ&possible_fusions_with_highest_prioritys           rX   r   z4Scheduler.get_possible_fusions_with_highest_priority  s  € ô
 ÐÓ  AÒ%Ø#Ð#ð ð 	+ð -ò 	‰LˆE�5Ø×#Ñ#Ó%¨×)9Ñ)9Ó);Ò;Ð;Ð;Ø×%Ñ%Ó'ˆFÜ#&Ø× Ñ  Ó(×AÑAÀ%ÈÓOó$Ð ð $Ð+MÑMà˜E�NðLÐ2Ð3GÒHð 3Ð3GÑH×OÑOØ˜E�Nõð	ô 25Ø.×4Ñ4Ó6¼H×<OÑ<OÐPQÓ<Rô2
à
ñ2Ð.ô Ð9Ó:¸QÒ>Ð>Ð>Ø5Ð5rZ   c                óB   — t        j                  j                  | g|¢­Ž S )z-
        Shim for list.sort(key=...)
        )rD   rb  Úscore_fusionr³  s     rX   r  zScheduler.score_fusion_key%  s   € ô �y‰y×%Ñ% dÐ3¨UÒ3Ð3rZ   c                óô   — t        t        j                  j                  «       «      }t	        | j
                  «      D ]9  }|j                  || j                  «       |j                  |j                  «       Œ; y)zg
        Populate node.last_usage recursively (also for the nodes within a FusedSchedulerNode)
        N)
r   rD   r|   rÚ  r¶  r  r  r  r
  r¹   )rV   r  rL   s      rX   rÞ  zScheduler.compute_last_usage-  s]   € ô
 )¬¯©×)AÑ)AÓ)CÓDÐä˜TŸZ™ZÓ(ò 	8ˆDØ×ÑÐ 3°T×5LÑ5LÔMØ×&Ñ& t§¡Õ7ñ	8rZ   c                ó†  — t        | j                  t        j                  j                  z
  t        j                  j
                  j                  z
  «      D �]N  }|| j                  v rT| j                  |   }|j                  «       sŒ2t        j                  j
                  j                  |j                  «       Œf|t        j                  j                  v sŒƒt        j                  j                  |   }t        |t        j                  «      r*t        j                  j
                  j                  |«       Œä|j                  }t        |t        j                   «      r|j#                  «       sJ ‚t        j                  j
                  j                  |j                  «       �ŒQ | j                  j%                  «        y)z*Free any buffers that are no longer neededN)rK  rá  rD   r|   r‰  r}   Úfreedrƒ   r�   Úcodegen_freerL   rã  ry   r   r×  rà   r„  Úis_input_bufferÚclear)rV   r]   r¿   rZ  Ústorages        rX   Úfree_bufferszScheduler.free_buffers8  s8  € äØ×%Ñ%Ü�g‰g×%Ñ%ñ&ä�g‰g×"Ñ"×(Ñ(ñ)ó
ó 	DˆDð
 �t×'Ñ'Ñ'Ø×&Ñ& tÑ,�Ø—<‘<•>Ü—G‘G×(Ñ(×5Ñ5°c·h±hÕ?ØœŸ™×-Ñ-Ò-Ü—g‘g×*Ñ*¨4Ñ0�Ü˜c¤2×#5Ñ#5Ô6Ü—G‘G×(Ñ(×5Ñ5°cÕ:à!Ÿh™h�Gä" 7¬B¯M©MÔ:¸w×?VÑ?VÔ?XðØXä—G‘G×(Ñ(×5Ñ5°g·l±lÖCð%	Dð( 	×!Ñ!×'Ñ'Õ)rZ   c                ó‚   — | j                   j                  «       D ]  }|j                  «        Œ | j                  «        y rT   )rÀ  r’   Úflushrœ  )rV   rc  s     rX   rž  zScheduler.flushP  s3   € Ø—}‘}×+Ñ+Ó-ò 	ˆGØ�M‰M�Oð	à×ÑÕrZ   c                óÜ  — t        |t        «      sJ ‚t        d   dxx   dz  cc<   t        j                  t        d¬«      «      5  |j                  «        |j                  «        d d d «       |j                  }t        |t        j                  «      sJ dt        |«      ›�«       ‚|j                  t        j                  j                  «       | j                  «        y # 1 sw Y   Œ|xY w)NÚinductorÚextern_callsr   F)Úincrease_kernel_countztype(node)=)ry   rß  r   rD   Úset_kernel_handlerr$   r•  r  rL   r   rö  re   r…  r|   r}   rœ  )rV   Úscheduler_noderL   s      rX   Úcodegen_extern_callzScheduler.codegen_extern_callU  s½   € Ü˜.Ô*CÔDÐDÐDô
 	�Ñ˜^Ó,°Ñ1Ó,Ü×!Ñ!¤&¸uÔ"EÓFñ 	&Ø×0Ñ0Ô2Ø×#Ñ#Ô%÷	&ð ×"Ñ"ˆÜ˜$¤§¡Ô0ÐB°[´T¸$³Z°MÐ2BÓBÐ0Ø�‰”Q—W‘W×)Ñ)Ô*Ø×ÑÕ÷	&ð 	&ús   Á!C"Ã"C+c                óP  — t        |j                  «      r|j                  €
J |› d�«       ‚t        j                  j                  |«       t        |j                  «      }|€t        d|j                  › �«      ‚t        «       sœ|j                  dk(  rLt        j                  j                  |«      x}j                  dk  rt        |t        j                  «       «      ‚t        |j                  «      r,|j                  dk(  st!        t        j                  «       «      ‚ || «      S )Nz( should have been normalized in loweringzUnsupported device type: Úcudaé   Úmps)r?   re   rÆ  rD   r|   Úadd_device_infor#   rF  r   rã   r§  Úget_device_propertiesÚmajorr*   ÚinspectÚcurrentframer+   )rV   r`  Údevice_schedulingÚdevice_propss       rX   Úcreate_backendzScheduler.create_backendd  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Ó$:Ó;Ð;á  Ó&Ð&rZ   c                ó€   — |€J ‚|| j                   vr| j                  |«      | j                   |<   | j                   |   S rT   )rÀ  r±  r_  s     rX   ry  zScheduler.get_backendy  sB   € ØÐ!Ð!Ð!Ø˜Ÿ™Ñ&Ø$(×$7Ñ$7¸Ó$?ˆD�M‰M˜&Ñ!Ø�}‰}˜VÑ$Ð$rZ   c                ó”  ‡ — dˆ fd„}|j                  «       D ��ci c]8  }|j                  �*|j                  j                  «       D ]  } ||«      |fd “Œ Œ: }}}t        |j	                  «       «      }|rMt        |t        j                  d«      ¬«      \  }}t        j                  j                  j                  |«       y y c c}}w )Nc                óâ   •— | ‰j                   vrL‰j                   j                  t        | j                  j                  «      D �� ci c]  \  }} | |“Œ
 c} }«       ‰j                       S c c} }w rT   )râ  r
  r  r|   r  )rO  r  rV   s     €rX   Ú	get_orderz*Scheduler.enter_context.<locals>.get_order€  s\   ø€ Ø˜×,Ñ,Ñ,Ø×$Ñ$×+Ñ+¼iÈÏÉÏÉÓ>V×,W±d°a¸¨Q°©TÓ,WÔXØ×'Ñ'¨Ñ*Ð*ùó -Xs   ÁA+
r   rF  )rO  ztorch.fx.Noder˜   r›   )rC  rL   r   r‘   rÄ  r  rŽ  r�  rD   r|   r}   Úenter_context)rV   rL   rµ  rO  r  r©  rõ  Úlasts   `       rX   r¶  zScheduler.enter_context  sº   ø€ õ	+ð —^‘^Ó%÷
àØ�v‰vÐ!Ø—V‘V×'Ñ'Ó)ò	
ð ñ �q‹\˜1Ð˜tÑ#ð
Øð
ˆñ 
ô �w—|‘|“~Ó&ˆÙÜ˜'¤x×':Ñ':¸1Ó'=Ô>‰GˆAˆtÜ�G‰G× Ñ ×.Ñ.¨tÕ4ð ùó
s   ›=Cc                ó¾   ‡— 	 | j                   |   j                  }t        ˆfd„|D «       «      xr || j                  vxr || j
                  vS # t        $ r Y yw xY w)NFc              3  ó^   •K  — | ]$  }|j                   xs |j                  «       ‰v –— Œ& y ­wrT   )r¦  rU   )r  ro   Úfused_node_namess     €rX   r  zAScheduler.can_buffer_be_removed_through_fusion.<locals>.<genexpr>™  s)   øè ø€ ÒVÈ�—‘ÒC §¡£Ð3CÐ CÓCÑVùs   ƒ*-)rƒ   rQ   r‚  rQ  rË  r  )rV   r]   rº  rQ   s     ` rX   Ú$can_buffer_be_removed_through_fusionz.Scheduler.can_buffer_be_removed_through_fusion‘  sn   ø€ ð	Ø×$Ñ$ TÑ*×0Ñ0ˆEô ÓVÐPUÔVÓVò 4Ø˜D×1Ñ1Ð1ò4à˜D×3Ñ3Ð3ð	
øô ò 	Ùð	ús   ƒA Á	AÁAc                ó’  — |j                  «       sy|j                  €yt        |j                  t        j                  «      ryt        |j                  t        j
                  «      ryt        |j                  dd«      ryt        |j                  d«      r1t        d„ |j                  j                  j                  D «       «      ryy)zBReturn True if we should partition the inductor graph on this nodeTNÚunbacked_bindingsrg   c              3  ól   K  — | ],  }t        |t        j                  «      xr |j                  –— Œ. y ­wrT   )ry   r·  rN  r  )r  Úexprs     rX   r  z-Scheduler.should_partition.<locals>.<genexpr>¯  s1   è ø€ ò 0
àô �tœUŸZ™ZÓ(Ò>¨T×->Ñ->Ó>ñ0
ùs   ‚24F)r?   rL   ry   r   Ú
DeviceCopyÚConditionalrÑ   r   r  rg   rÇ  r  s     rX   Úshould_partitionzScheduler.should_partitionž  s“   € à�{‰{Œ}Øà�9‰9ÐØä�d—i‘i¤§¡Ô/Øä�d—i‘i¤§¡Ô0Øä�4—9‘9Ð1°4Ô8Øä�4—9‘9˜hÔ'¬Cñ 0
àŸ	™	×(Ñ(×-Ñ-ô0
ô -
ð àrZ   c                óà   — i }|j                  t        j                  j                  «       | j                  D ]3  }|j
                  j                  «       D ]  \  }}|j                  ||<   Œ Œ5 |S )z~
        Return a mapping from name strings to the corresponding graph inputs or
        base scheduler node outputs.
        )r
  rD   r|   rã  r  r½   r	  rL   )rV   r2  rL   r]   Úscheduler_buffers        rX   Úget_name_to_nodeszScheduler.get_name_to_nodes·  sr   € ð UWˆØ×ÑœAŸG™G×0Ñ0Ô1à—J‘Jò 	;ˆDØ*.×*>Ñ*>×*DÑ*DÓ*Fò ;Ñ&�Ð&Ø%5×%:Ñ%:�˜TÒ"ñ;ð	;ð ÐrZ   c           	     óÄ  — g }t        t        j                  j                  «       «      }| j	                  «       }t        t        |«      t        |«      «      D �]e  \  }}t        «       }|D ]+  }	|j                  |	j                  j                  «       «       Œ- |j                  |«      }
t        j                  j                  |D �	cg c]  }	|	j                  ‘Œ c}	«      }t        |j                  |j                   z  D �cg c]  }|j"                  ‘Œ c}«      |z
  }t        «       }|D ]  }	|j                  |	j$                  «       Œ |D �ci c]  }||v r|||   “Œ }}|D �ci c]  }||v r	|||v rdnd“Œ }}|
D �cg c]  }||   ‘Œ	 }}|j'                  t)        ||||«      «       |j+                  ||
z
  «      }�Œh |ddd…   S c c}	w c c}w c c}w c c}w c c}w )z¡
        Gets signature for each graph partition, including input nodes, output nodes, and
        whether deallocating an input within graph partition.
        TFNr›  )r   rD   r|   rÚ  rÅ  r¬  r¶  r
  r½   rÄ  r  r   rÚ  rÛ  r¬   rÓ   rÒ   r]   r¹   r¡  r.   rÜ  )rV   Ú
partitionsÚskip_cudagraphsÚ
signaturesÚunmet_output_namesr2  Ú	partitionÚskip_cudagraphÚoutput_namesrL   Úreturned_output_namesr¬   r“  Úpartition_input_namesrá  r]   Úinput_nodesÚinput_deallocationÚoutput_nodess                      rX   Úget_graph_partition_signaturez'Scheduler.get_graph_partition_signatureÇ  s   € ð ˆ
ä'¬¯©×(@Ñ(@Ó(BÓCÐØ×-Ñ-Ó/ˆä),Ü�ZÓ ¤(¨?Ó";ó*
ó -	Ñ%ˆI�~ô -7«LˆLà!ò A�Ø×#Ñ# D×$8Ñ$8×$=Ñ$=Ó$?Õ@ðAð %1×$=Ñ$=Ð>PÓ$QÐ!ô '×1Ñ1×<Ñ<Ø.7Ö8 d�×!Ó!Ò8óˆKô ¨K×,=Ñ,=À×@RÑ@RÑ,RÖS q˜AŸF›FÒSÓTØñð "ô
 5?³LÐ Ø!ò =�Ø$×+Ñ+¨D¯O©OÕ<ð=ð
 2öàØ˜<Ñ'ð �l 4Ñ(Ñ(ðˆKð ð 2ö"àØ˜<Ñ'ð ˜dÐ&:Ñ:‘dÀÑEð"Ðð "ð
 <QÖQ°4˜L¨Ó.ÐQˆLÐQØ×ÑÜ'ØØ Ø&Ø"ó	ôð "7×!<Ñ!<Ø"Ð%:Ñ:ó"ÒðW-	ð^ ™$˜B˜$ÑÐùòE 9ùò Tùòùò
"ùò
 Rs   ÃG	
ÄG
ÅGÅ%GÅ?Gc                óD  — g }d}g }g }| j                   D ]Q  }| j                  |«      }|r)||k7  r$|j                  |«       |j                  |«       g }|}|j                  |«       ŒS |r"|j                  |«       |j                  |«       || j                  ||¬«      fS )z’
        Given a list of BaseSchedulerNodes, split into a list of
        graph partitions and compute partition input/output signatures.
        T)rÇ  rÈ  )r  rÂ  r¡  rÓ  )rV   rÇ  rÌ  Úcur_partitionrÈ  rL   rÂ  s          rX   Úgraph_partitionzScheduler.graph_partition  sÀ   € ð +-ˆ
àˆØ')ˆØˆØ—J‘Jò 	'ˆDØ#×4Ñ4°TÓ:ÐÙ Ð3CÒ!CØ×!Ñ! -Ô0Ø×&Ñ& ~Ô6Ø "�à-ˆNØ× Ñ  Õ&ð	'ñ Ø×Ñ˜mÔ,Ø×"Ñ" >Ô2à˜4×=Ñ=Ø!°?ð >ó 
ð 
ð 	
rZ   c                óä   — t        d«      5  t        j                  j                  j                  r| j                  «       n| j                  | j                  «      	 cd d d «       S # 1 sw Y   y xY w)NzScheduler.codegen)r   rã   rä   r   rÖ  Ú_codegen_partitionsÚ_codegenr  r^   s    rX   r…  zScheduler.codegen"  sX   € ÜÐ-Ó.ñ 	ô —?‘?×)Ñ)×9Ò9ð ×(Ñ(Ô*à—]‘] 4§:¡:Ó.ð÷	÷ 	ò 	ús   ŒAA&Á&A/c                ó4  — t         j                  j                  }t        | j                  «      }t         j                  j                  «       5  t         j                  j                  dd|› �||¬«       | j                  |«       t         j                  j                  j                  t         j                  j                  «      \  }}ddd«       t         j                  j                  j                  j                  «       t         j                  j                  j                  ||«       t         j                  j                  j                  j                  |j                  D �cg c]  }|j!                  «       ‘Œ c}«       y# 1 sw Y   ŒÀxY wc c}w )z,Codegen a partition given its inputs/outputsTÚ
partition_)Úis_subgraphÚsubgraph_nameÚparent_wrapper_codeÚpartition_signaturesN)rD   r|   r}   r  rÃ  Úset_current_wrapper_codeÚinit_wrapper_coderÙ  ÚgenerateÚis_inferenceÚdefine_subgraph_launcher_fnÚvalueÚcodegen_partition_callÚ	allocatedr
  rÒ  rU   )rV   rË  Ú	signaturerÞ  Úgraph_partition_idÚpartition_coderõ  rL   s           rX   Ú_codegen_partition_wrapperz$Scheduler._codegen_partition_wrapper*  s)  € ô  Ÿg™g×2Ñ2ÐÜ! $×"?Ñ"?Ó@Ðä�W‰W×-Ñ-Ó/ñ 	TÜ�G‰G×%Ñ%Ø Ø *Ð+=Ð*>Ð?Ø$7Ø%.ð	 &ô ð �M‰M˜)Ô$Ü !§¡× 4Ñ 4× =Ñ =¼a¿g¹g×>RÑ>RÓ SÑˆN˜A÷	Tô 	
�‰×Ñ×8Ñ8¸×9MÑ9MÔNä	�‰×Ñ×3Ñ3Ð4FÈ	ÔRÜ	�‰×Ñ×&Ñ&×-Ñ-Ø)2×)?Ñ)?Ö@ ˆT�]‰]�_Ò@õ	
÷	Tð 	Tüò As   ÁA<F	Å*FÆ	Fc                óp  — | j                  «       \  }}t        ||«      D ]V  \  }}t        |«      dk\  sJ dt        |«      › �«       ‚|j                  r| j	                  |«       ŒE| j                  ||«       ŒX t        | j                  «      }t        j                  j                  j                  |«       y)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   z5Each partition must have at least one node but found N)rÖ  r¬  rk   rÌ  rÙ  rë  r  rÃ  rD   r|   r}   Úset_all_partition_names)rV   rÇ  rÉ  rË  rè  Únum_partitionss         rX   rØ  zScheduler._codegen_partitionsD  s­   € ð "&×!5Ñ!5Ó!7Ñˆ
�Jä$'¨
°JÓ$?ò 	FÑ ˆI�yÜ�y“> QÒ&ð ØGÌÈIËÐGWÐXóÐ&ð ×'Ò'Ø—‘˜iÕ(à×/Ñ/°	¸9ÕEð	Fô ˜d×;Ñ;Ó<ˆÜ	�‰×Ñ×4Ñ4°^ÕDrZ   c                óæ
  — t         j                  r¿dd l}t        j                  «       }t        «       }t        |«      D ]�  }|j                  dk(  r/|j                  |j                  j                  j                  k(  r nQ|j                  |j                  f}||vs"J d|j                  › d|j                  › d�«       ‚|j                  |«       Œ‘ d | _        |D �]þ  }t        j!                  t"        j$                  «      r4	 t        j'                  d|j)                  «       |j+                  «       «       | j/                  |«       |j1                  «       x}�r|| j                  k7  s |j3                  «       s|j5                  «       r| j7                  «        || j                  k7  rµ| j                  rGt9        | j                  j:                  «      r(t<        j>                  j@                  jC                  «        || _        t9        |j:                  «      rF|jD                  €J d«       ‚t<        j>                  j@                  jG                  |jD                  «       | jH                  jK                  |jL                  «       |j5                  «       rP|jO                  tQ        |jS                  «       «      «      \  }	}
}| jU                  |«      jW                  |
||	«       �n|j3                  «       r,tY        jZ                  t\        |«      }| j_                  |«       nÚ|ja                  «       rqtY        jZ                  tb        |«      }| jU                  |«      }d	d
l2m3} d	dl4m5} tm        |||f«      r|}nto        dt;        | «      ›�«      ‚|jq                  |«       nYtm        |tr        tt        f«      r!| jU                  |«      jw                  |«       n"tm        |tx        «      sJ ‚|j{                  «        t         j|                  j~                  r| jU                  |«      j�                  «        | j‚                  jK                  |j…                  «       «       | j†                  jK                  |j‰                  «       «       tm        |tx        «      r�Œº|j1                  «       }|€�ŒÎ| jU                  |«      j‹                  «       s�Œï| j7                  «        �Œ | j                  rGt9        | j                  j:                  «      r(t<        j>                  j@                  jC                  «        | j7                  «        y # t,        $ r( t        j'                  d|j)                  «       «       Y �Œ;w xY w)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.0zdevice should have an indexr   )ÚCUDACombinedSchedulingr‚  ztype(self)=)Fr   Ú"check_stack_no_cycles_TESTING_ONLYÚtorch._dynamo.convert_frameÚ	tracebackÚextract_stackr   r¶  r]   ÚfilenameÚ_dynamoÚconvert_frameÚ__file__Úlinenor!  rê  rÖ   rô  rõ  r›  r?  rU   r  rÕ   r¶  r[  rk  ri  rž  r9   re   rD   r|   r}   Úcodegen_device_guard_exitrÆ  Úcodegen_device_guard_enterrá  r
  r¹   r#  r‘   rC  ry  Úcodegen_templater=  r>  rß  r¥  rm  r+  Ú codegen.cuda_combined_schedulingrò  r†  rƒ  ry   r?  Úcodegen_combo_kernelrâ  rM  Úcodegen_noder‹  r  r¦  Údebug_sync_kernelÚcodegen_syncr'  rH  rˆ  rD  Úready_to_flush)rV   r  rã   Ústackr?  ÚframerG  rL   r`  r   r!  r"  Úbackend_rò  rƒ  rc  s                   rX   rÙ  zScheduler._codegenY  s4  € Ü×4Ò4Û.ä×+Ñ+Ó-ˆEÜ7A³|ˆDÜ! %›ò �ð —J‘JÐ"2Ò2ØŸ™¨%¯-©-×*EÑ*E×*NÑ*NÒNáØ—~‘~ u§|¡|Ð4�Ø $‘ð Ø,¨U¯^©^Ð,<¸A¸e¿l¹l¸^ð LJð Jó�ð
 —‘˜•ðð #ˆÔØó G	!ˆDÜ×Ñ¤§¡Ô.ð
Ü—I‘IØOØŸ™›Ø×2Ñ2Ó4ôð ×Ñ˜tÔ$àŸ™Ó*Ð*ˆvÑ*à˜d×1Ñ1Ò1Ø—~‘~Ô'Ø×'Ñ'Ô)à—J‘J”LØ˜T×0Ñ0Ò0Ø×*Ò*Ô/@Ø×+Ñ+×0Ñ0ô0ô Ÿ™×,Ñ,×FÑFÔHØ*0�DÔ'Ü(¨¯©Ô5Ø%Ÿ|™|Ð7ÐVÐ9VÓVÐ7ÜŸ™×,Ñ,×GÑGÈÏÉÔUà×%Ñ%×,Ñ,¨T¯_©_Ô=à×ÑÔ!Ø48×4WÑ4WÜ˜Ÿ™Ó)Ó*ó5Ñ1�˜-¨ð × Ñ  Ó(×9Ñ9Ø! 8¨Xöð —‘Ô!Ü—{‘{Ô#<¸dÓC�Ø×(Ñ(¨Õ.Ø—‘Ô"Ü—{‘{Ô#=¸tÓD�Ø×+Ñ+¨FÓ3�ÝTÝ8ä˜h¨Ð9OÐ(PÔQØ&‘Gä(¨K¬D°«J¨=Ð)9Ó:Ð:Ø×,Ñ,¨TÕ2Ü˜DÔ#5´}Ð"EÔFØ× Ñ  Ó(×5Ñ5°dÕ;ä! $Ô(>Ô?Ð?Ð?Ø—‘”ä�}‰}×.Ò.Ø× Ñ  Ó(×5Ñ5Ô7à×'Ñ'×.Ñ.¨t×/DÑ/DÓ/FÔGØ×%Ñ%×,Ñ,¨T×-EÑ-EÓ-GÔHä˜dÔ$:Ö;ØŸ™Ó*�ØÒ%¨$×*:Ñ*:¸6Ó*B×*QÑ*QÖ*SØ—J‘J–LðOG	!ðR ×ÒÔ#4°T×5HÑ5H×5MÑ5MÔ#Nô �G‰G× Ñ ×:Ñ:Ô<à�
‰
�øôM !ò Ü—I‘IØPØŸ™›÷ðús   Ä3T?Ô?-U0Õ/U0c                ó¬   — |d   j                  «       }| t        j                  _        || _        |€J ‚| j                  |«      }|j                  |«      S )r^  r   )r[  rD   r|   rK   rê  ry  Úbenchmark_combo_kernel)rV   r’  r`  rc  s       rX   r	  z Scheduler.benchmark_combo_kernel¿  sW   € ð ˜1‘×(Ñ(Ó*ˆØ Œ�‰ÔØ$ˆÔØÐ!Ð!Ð!Ø×"Ñ" 6Ó*ˆØ×-Ñ-¨iÓ8Ð8rZ   c                óè  — t         j                  sy|}|d   j                  «       }|�|j                  dk(  ryddlm} dg }}t        |«      D ]”  \  }}|j                  «       }	| j                  |	«      rt        j                  d«       	 | j                  |	«      \  }
}t        j                  |
«      rt        j                  d|«        y		 ||
z  }|j                  |«       Œ– 	 | j                  |«      \  }}}||z
  dk  xs |dk  }t        j!                  t"        j$                  «      rP||kD  s|r%t        j                  dt'        ||z  d›«      «       n$t        j                  dt)        ||z  d›«      «       ||z
  |k  xs |S # |$ r.}d
t        |«      v rt        j                  d«       Y d}~ y‚ d}~ww xY w# |$ r-}d
t        |«      v rt        j                  d«       Y d}~y‚ d}~ww xY w)r•  Tr   Nr^  r—  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 variableg333333Ó?z/can fuse (benchmark): fusing causes %sx speeduprš  z3cannot fuse (benchmark): fusing causes %sx slowdown)r   r	  r[  re   rÔ  r˜  r  rC  r“  r>  r?  r_  rÍ  rÎ  r™   r¡  rô  rõ  r›  r4   r5   )rV   r  Úsubkernel_nodesr`  r˜  r�  Ú
path1_listr  rî  r’  Úmsr¹  r  rž  Ú	ms2_cloneÚ_path2_listÚsmall_kernels                    rX   ró  z!Scheduler.speedup_by_combo_kernelÍ  s  € ô
 ×,Ò,ØàˆØ  Ñ#×.Ñ.Ó0ˆð ˆ>˜VŸ[™[¨EÒ1Øå;à˜rˆZˆÜ! /Ó2ò 	$‰HˆAˆuØŸ™Ó)ˆIð ×#Ñ# IÔ.Ü× Ñ ØRôðØ×5Ñ5°iÓ@‘��DÜ—:‘:˜b”>Ü×$Ñ$ØUØôñ !ð "ð �2‰IˆCØ×Ñ˜dÕ#ð7	$ð:
	Ø*.×*EÑ*EÀoÓ*VÑ'ˆC�˜Kð ˜Y‘¨Ñ,Ò9°°c±	ˆÜ×"Ñ"¤7§=¡=Ô1Ø�SŠy™LÜ× Ñ ØEÜ #¨¡)¨C Ó2õô
 × Ñ ØIÜ  c¡	¨#˜Ó0ôð
 �Y‰ Ñ$Ò4¨Ð4øðM $ò à*¬c°!«fÑ4Ü×$Ñ$Ø]ôõ  àûðûð  ò 	à&¬#¨a«&Ñ0Ü× Ñ ØYôô àûð	ús<   Â?F	Ã&F? Æ	F<Æ"F7Æ6F7Æ7F<Æ?G1Ç"G,Ç+G,Ç,G1c                óp   — | j                   |   }|j                  €J ‚|j                  j                  «       S rT   )rƒ   rL   Ú
get_layout)rV   rX  r¿   s      rX   Úget_buffer_layoutzScheduler.get_buffer_layout  s5   € Ø×Ñ˜xÑ(ˆØ�x‰xÐ#Ð#Ð#Ø�x‰x×"Ñ"Ó$Ð$rZ   c                óÌ  — | j                   D ]Õ  }|j                  «       sŒ|j                  j                  D ]©  }t        j
                  j                  j                  |j                  «      }|sŒ9t        |«      dk(  sŒHt        |j                  t        «      rŒc|j                  «       g k(  sŒwt        j
                  j                  j                  |j                  «       Œ« Œ× y r]  )r  r?   r¬   rÓ   rD   r|   r"  r  r]   r-   ry   rg   r0   rç   Úzero_dim_cpu_tensor_listr!  )rV   rL   r‘  r§  s       rX   rÈ  z$Scheduler.update_zero_dim_cpu_tensor  s¥   € Ø—J‘Jò 
	HˆDØ�{‰{�}Ø ×,Ñ,×2Ñ2ò H�DÜŸW™W×3Ñ3×7Ñ7¸¿	¹	ÓB�FâÜ+¨FÓ3°uÓ<Ü *¨6¯=©=Ô:KÕ LØ"ŸO™OÓ-°Ó3äŸ™×8Ñ8×<Ñ<¸T¿Y¹YÕGñHñ
	HrZ   )r  zlist[ir.Operation]r˜   r�   )r˜   z!dict[str, SchedulerDonatedBuffer]r.  )r`  r/  r˜   r�   rœ   )r÷  r™   r˜   r�   )rL   r$  r˜   rG   rs  )rî  rG   r˜   r4  )r˜   rt  ©r  rÞ  r˜   útuple[float, str]©r  rÞ  rf  rŸ   r˜   r™   )ri  r   r`  r'  r˜   r  )r’  rÞ  r˜   rŸ   )r8  rG   r9  rG   r˜   zUnion[bool, Callable[[], bool]])rL   rG   r˜   rG   rT   )r·  zOptional[int]r˜   r�   rý  )r  r4  r˜   ú1list[tuple[BaseSchedulerNode, BaseSchedulerNode]]©r8  rG   r9  rG   r˜   rŸ   )r8  rG   r9  rG   r0  z"Union[tuple[str], OrderedSet[str]]r˜   r™   ©r8  rG   r9  rG   r˜   r›   r  )rS  rG   r!  rG   r@  r7  r˜   rŸ   )rx  r)   r8  rG   r9  rG   r˜   rŸ   )r‘  r&   rê  r'   r˜   rŸ   )rþ   r&   r˜   r›   )rú  r  r˜   r  )r  z+tuple[BaseSchedulerNode, BaseSchedulerNode]r˜   r   )r¤  rß  r˜   r�   )r`  r'  r˜   ÚBaseScheduling)r`  r/  r˜   r  )rL   rG   r˜   r�   )r]   r™   rº  r)  r˜   rŸ   )r˜   z;dict[str, Union[ir.IRNode, ir.TorchBindObject, sympy.Expr]])rÇ  zlist[PartitionType]rÈ  z
list[bool]r˜   zlist[GraphPartitionSignature])r˜   z9tuple[list[PartitionType], list[GraphPartitionSignature]])rË  ÚPartitionTyperè  r.   r˜   r�   ©r’  rÞ  r˜   z(tuple[float, float, list[Optional[str]]])r  r4  r˜   rŸ   )rX  r™   r˜   z	ir.Layout)Frf   r¡   r¢   r£   r¶   r²  rÉ  Úpropertyrê  Úsetterrà  rø  rÇ  rÓ  rÍ  rÏ  rÎ  rI  rZ  rÐ  r“  r~  rÝ  r_  re  rh  rÖ  r“  rÝ  r{  rX  rØ  r:  rì  rä  r'  r+  r9  rE  rþ  rW  r:  rc  rm  rn  r>  r  r   r  rÞ  rœ  rž  r¥  r±  ry  r¶  r»  rÂ  rÅ  rÓ  rÖ  r…  rë  rØ  rÙ  r	  ró  r  rÈ  rh  ri  s   @rX   rJ   rJ   ¼  s²  ø… Ø)Ó)óõs
ój	#ð ò&ó ð&ð ×Ñò(ó ð(ó7ó#ó,ó"óHOSób(#ðTØ,ðà	 óó6Só(ó4#ó&$ó6ó6	ð8Ø0ð8à	ó8ð$TØ0ðTØDHðTà	óTð
>Ø ð
>Ø*6ð
>à	ó
>óL@ó\
ð~(Ø&ð~(Ø/@ð~(à	(ó~(ó@>ðhØ,ðhà	 óhôT..ó`?ð0 Ø,ð0 à	:ó0 ðd,Ø&ð,Ø/@ð,à	ó,ð\7Ø&ð7Ø/@ð7à	ó7ðr$Ø&ð$Ø/@ð$à	ó$ð6<à ð<ð !ð<ð =ð	<ð
 
ó<ð|I6Ø&ðI6Ø/@ðI6à	óI6óV
ð9à(ð9ð )ð9ð ð	9ð
 
ó9óvQMðf3Ø&ð3Ø/@ð3à	ó3ðj
Øð
Ø(9ð
ØBSð
à	ó
óJ óDð JØ&ðJØ/@ðJà	óJð<6Ø Qð6à	:ó6ð@4Ø@ð4à	ó4ó	8ó*ó0ó
ó'ó*%ó5ð$
Øð
Ø+:ð
à	ó
óð2à	Dóð ; Ø-ð; Ø@Jð; à	&ó; ðz
à	Bó
ó<ð
à ð
ð +ð
ð 
ó	
ó4Eó*dðL9Ø4ð9à	1ó9óI5óV%÷
HrZ   c                  ó  ‡ — e Zd Zdˆ fd„Zdd„Zdd„Z	 	 	 	 	 	 dd„Z	 	 	 	 	 	 dd„Z	 	 	 	 	 	 dd„Z	 	 	 	 	 	 dd„Z		 	 	 	 dd„Z
	 	 	 	 	 	 	 	 dd	„Z	 	 	 	 	 	 dd
„Zdd„Zdd„Zdd„Zdd„Z	 	 	 	 dd„Zdd„Z	 	 	 	 	 	 dd„Z	 	 	 	 d d„Zˆ xZS )!r  c                ó0   •— t         ‰| �  «        || _        y rT   )r_  r¶   rK   )rV   rK   rþ  s     €rX   r¶   zBaseScheduling.__init__,  s   ø€ Ü‰ÑÔØ"ˆ�rZ   c                óR   — | j                   r| j                   j                  «        y y rT   )rK   rœ  r^   s    rX   Úfree_buffers_in_schedulerz(BaseScheduling.free_buffers_in_scheduler0  s   € Ø�>Š>Ø�N‰N×'Ñ'Õ)ð rZ   c                ó   — t        «       S )z0Return a set of .codegen.common.BackendFeature()r   r_  s     rX   Úget_backend_featuresz#BaseScheduling.get_backend_features4  s
   € ä‹|ÐrZ   c                ó   — t         ‚)zO
        Check whether node1 and node2 can be vertically fused or not.
        r  r<  s      rX   rc  z BaseScheduling.can_fuse_vertical8  ó
   € ô "Ð!rZ   c                ó   — t         ‚)zQ
        Check whether node1 and node2 can be horizontally fused or not.
        r  r<  s      rX   rd  z"BaseScheduling.can_fuse_horizontal@  r(  rZ   c                 ó   — y)au  
        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.
        Fr¦   r<  s      rX   r]  z.BaseScheduling.can_fuse_multi_outputs_templateH  s   € ð rZ   c                óš   — |j                  «       s|j                  «       rt        j                  ||«      S t        j                  ||«      S )z 
        Fuse two nodes
        )rm  r+  rë  râ  r<  s      rX   rë  zBaseScheduling.fuseT  sA   € ð ×ÑÔ ×!1Ñ!1Ô!3Ü-×2Ñ2°5¸%Ó@Ð@ä%×*Ñ*¨5°%Ó8Ð8rZ   c                ó   — t         ‚)z[
        Process the iteration sizes in case a transformation needs to be applied.
        r  )rV   r�  s     rX   rz  zBaseScheduling.group_fn_  r(  rZ   c                ó   — t         ‚)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  )rV   r!  Úepilogue_nodesr\  s       rX   rþ  zBaseScheduling.codegen_templateg  s
   € ô "Ð!rZ   c                ó   — t         ‚©zD
        Generate a kernel given a list of pre-fused nodes.
        r  )rV   r  rf  s      rX   re  z.BaseScheduling.generate_kernel_code_from_nodesu  r(  rZ   c                ó   — t         ‚r0  r  r  s     rX   r  zBaseScheduling.codegen_node}  ó
   € ô "Ð!rZ   c                ó   — t         ‚)zt
        Generate synchronization code for the kernel. This method depends on the hardware characteristics.
        r  r^   s    rX   r  zBaseScheduling.codegen_syncƒ  r2  rZ   c                 ó   — y)z•
        Check whether the backend is requesting the scheduler to flush the generated kernel.
        If not supported, please return False.
        Fr¦   r^   s    rX   r  zBaseScheduling.ready_to_flush‰  s   € ð
 rZ   c                ó   — t         ‚)z]
        Flush the generated kernel and python wrapper code to the source code file.
        r  r^   s    rX   rž  zBaseScheduling.flush�  r2  rZ   c                ó   — t         ‚)r^  r  r³  s     rX   r_  z$BaseScheduling.benchmark_fused_nodes–  ó
   € ô "Ð!rZ   c                ó   — t         ‚)z�
        Benchmark a compiled module and return the execution time
        in milliseconds on randomly generated inputs.
        r  )rV   ri  s     rX   rh  z)BaseScheduling.benchmark_codegened_moduleŸ  s
   € ô
 "Ð!rZ   c                 ó   — y)zŒ
        Return an unsigned integer which represents the priority of this fusion pair.
        The smaller is with higher priority.
        r   r¦   r<  s      rX   r�  z'BaseScheduling.get_fusion_pair_priority¦  s   € ð rZ   c                ó   — t         ‚)z¡
        Benchmark the list of nodes to combine and return the execution time
        and memory copy time in milliseconds on randomly generated inputs.
        r  r‘  s     rX   r	  z%BaseScheduling.benchmark_combo_kernel¯  r7  rZ   )rK   zOptional[Scheduler]rœ   )r`  r'  r˜   zOrderedSet[BackendFeature]r  r$  )r�  rÓ  r˜   z"tuple[tuple[sympy.Expr, ...], ...])r!  rG   r.  rÞ  r\  rÞ  r˜   zOptional[str]r  )rL   z(Union[FusedSchedulerNode, SchedulerNode]r˜   r�   rž   r  )ri  r   r˜   r  r  r  )rf   r¡   r¢   r¶   r$  r&  rc  rd  r]  rë  rz  rþ  re  r  r  r  rž  r_  rh  r�  r	  rh  ri  s   @rX   r  r  +  sC  ø„ õ#ó*óð"Ø&ð"Ø/@ð"à	ó"ð"Ø&ð"Ø/@ð"à	ó"ð
Ø&ð
Ø/@ð
à	ó
ð	9Ø&ð	9Ø/@ð	9à	ó	9ð"Ø3ð"à	+ó"ð"à(ð"ð 4ð"ð 4ð	"ð
 
ó"ð"Ø0ð"ØDHð"à	ó"ó"ó"óó"ð"Ø0ð"à	ó"ó"ðØ&ðØ/@ðà	óð"Ø4ð"à	1÷"rZ   r  )rN  r   r˜   r™   )rL   rG   r9  r,  rƒ   zdict[str, SchedulerBuffer]r˜   r�   )rØ  ú/Union[FusedSchedulerNode, GroupedSchedulerNode]r˜   r�   )rØ  r;  rK   rJ   rË  r4  r˜   r�   )r¦   )r™  zlist[list[int]]r�  rÔ  rŸ  ztuple[int, ...]r˜   z	list[int])ŒÚ
__future__r   rá  r¤   r›  r­  r  rõ  rÍ  rŽ  rñ  rL  rM  rõ  r=  r   r   r   r   r   r	   r
   r   r   Úcollections.abcr   Útypesr   r·  rã   Útorch._inductor.async_compileÚtorch._dynamo.utilsr   r   Útorch._inductor.codecacher   r   Útorch._inductor.metricsr   r   Ú%torch.fx.experimental.symbolic_shapesr   Útorch.utils._ordered_setr   Útorch.utils._sympy.symbolr   r   Útorch.utils._tritonr   rÛ   r   r   r   r   r    Úanalyze_preserves_zero_maskr!   Úcodegen.commonr"   r#   r$   Úcomm_analysisr%   r&   r'   r(   r)   Úexcr*   r+   r,   r-   r.   r/   r0   Ú	loop_bodyr1   rÙ  r2   r3   Úruntime.runtime_utilsr4   r5   rÁ  r6   Úutilsr7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   ÚvirtualizedrD   Ú	getLoggerrf   rÖ   Ú_loggingÚgetArtifactLoggerr>  r˜  r‘   r  Ú	dataclassrI   r¨   rG   r7  ri   r‹   r8  rO  rP  ÚconvolutionÚmmÚbmmÚaddmmÚ
_scaled_mmr÷  rß  r‹  rM  rÝ  rå  râ  r+  rä  r¢  r¤  rÂ  rÁ  rJ   r  r¦   rZ   rX   ú<module>rX     s  ðÝ "ã Û Û Û Û Û Û Û Û 	Û Û Û Û ß ,ß R× RÑ Rñ Ý(Ý ã ã Û $ß 6ß ?ß MÝ GÝ /ß ?Ý *ç 6Õ 6Ý Dß MÑ MÝ ;ß :Ó :ß 2÷õ õ  ß Jß 7Ý &÷÷ ÷ õ õ ð €g×Ñ˜Ó!€Ø�^‰^×-Ñ-¨h¸ÓA€
Ø—N‘N×4Ñ4°X¸ÓOÐ àÐ(Ñ)€ð ×Ñ÷e.ð e.ó ðe.ðP ×Ñô4˜_ó 4ó ð4÷w
1ñ w
1÷t
ñ 
ó,÷ñ ð &KØ
ð&Kà4ð&Kð ,ð&Kð 
ó	&KðV #(§)¡)§.¡.×"<Ñ"<ØŸ™Ÿ™×*Ñ*ØŸ)™)Ÿ.™.×,Ñ,Ø!ŸI™IŸN™N×0Ñ0Ø!&§¡§¡×!:Ñ!:ñÐ ôWÐ 1ô Wô"5Ð.ô 5ô~+Ð%ô ~+ðBØ@ðà	óð$Ø@ðàðð $ðð 
ó	ô,P*Ð*ô P*ôfy:Ð!3ô y:ôx	?Ð,ô ?ðJ %'ð+Ø#ð+àð+ð "ð+ð ó	+ð\ ×Ñ÷
ð 
ó ð
ð> +˜9Ÿ?š?Ó,Ð ÷l%Hñ l%H÷^KK"ò K"rZ   