ó
    EñiRŸ  ã                  ó²  • S SK Jr  S SKrS SKrS SKrS SKrS SKJrJrJ	r	J
r
  S SKrS SKJr  S SKJr  S SKJr  SSKJr  SS	KJrJr  SS
KJrJr  SSKJr  \(       a  S SKJr  SSKJr  SSK J!r!J"r"  SSKJ#r#  \RH                  " \%5      r&\RN                   " S S5      5       r(\RN                   " S S5      5       r)\RN                   " S S5      5       r*\RN                   " S S5      5       r+      S+S jr,    S,S jr-      S-S jr.          S.S jr/\RN                   " S S5      5       r0        S/S jr1        S0S jr2\RN                   " S  S!5      5       r3        S1S" jr4          S2S# jr5S3S$ jr6S3S% jr7S4S& jr8        S5S' jr9            S6S( jr:\5\6\7/4             S7S) jjr;            S8S* jr<g)9é    )ÚannotationsN)ÚOptionalÚTYPE_CHECKINGÚ	TypedDictÚUnion)Ú	is_fbcode)Úsignpost_event)Ú
OrderedSeté   )Úconfig)ÚMultiOutputLayoutÚ
NoneLayout)Úget_dtype_sizeÚis_nonfreeable_buffers)ÚV)ÚCallable)ÚDep)ÚBaseSchedulerNodeÚSchedulerBuffer)ÚWeakDepc                  ó4   • \ rS rSr% S\S'   S\S'   S\S'   Srg	)
ÚPeakMemoryResulté    úlist[BaseSchedulerNode]ÚorderÚintÚpeak_memoryÚstrÚmethod© N©Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__annotations__Ú__static_attributes__r    ó    ÚS/home/mande/repo/quber/.venv/lib/python3.13/site-packages/torch/_inductor/memory.pyr   r       s   ‡ à"Ó"ØÓØ†Kr(   r   c                  ó�   • \ rS rSr% SrS\S'   SrS\S'   \R                  " \	S9r
S\S'   \R                  " \	S9rS\S	'   SS
 jrSrg)ÚMemoryPlanningInfoForBufferé'   r   r   Ú
size_allocÚ	size_free©Údefault_factoryúOrderedSet[BaseSchedulerNode]Ú
succ_nodesÚsucc_nodes_for_orderingc                óŽ   ^ • [         R                  " [        T R                  5      [        T R                  5      :*  U 4S j5        g )Nc                 ó`   >• S[        T R                  5       S[        T R                  5       3$ )NzHsucc_nodes must be a subset of succ_nodes_for_ordering. len(succ_nodes)=z, len(succ_nodes_for_ordering)=)Úlenr2   r3   ©Úselfs   €r)   Ú<lambda>Ú;MemoryPlanningInfoForBuffer.__post_init__.<locals>.<lambda>7   s2   ø€ ð Ü" 4§?¡?Ó3Ð4Ð4SÔTWÐX\×XtÑXtÓTuÐSvñxr(   )ÚtorchÚ_checkr6   r2   r3   r7   s   `r)   Ú__post_init__Ú)MemoryPlanningInfoForBuffer.__post_init__4   s1   ø€ Ü�ŠÜ�—‘Ó ¤C¨×(DÑ(DÓ$EÑEôxõ	
r(   r    N)ÚreturnÚNone)r"   r#   r$   r%   r-   r&   r.   ÚdataclassesÚfieldr
   r2   r3   r=   r'   r    r(   r)   r+   r+   '   sU   ‡ à€J�ÓØ€IˆsÓà0;×0AÒ0AØ"ñ1€JÐ-ó ð >I×=NÒ=NØ"ñ>ÐÐ:ó ÷
r(   r+   c                  ó°   • \ rS rSr% SrS\S'   SrS\S'   \R                  " \	S9r
S\S'   \R                  " \	S9rS	\S
'   \R                  " \	S9rS	\S'   Srg)ÚMemoryPlanningInfoForNodeé<   r   r   ÚindexÚsizer/   z7OrderedSet[Union[SchedulerBuffer, FreeableInputBuffer]]Úpred_buffersr1   Ú
pred_nodesr2   r    N)r"   r#   r$   r%   rF   r&   rG   rA   rB   r
   rH   rI   r2   r'   r    r(   r)   rD   rD   <   si   ‡ à€Eˆ3ƒNØ€Dˆ#ƒMà×Ò¨*Ñ5ð ÐIó ð 1<×0AÒ0AØ"ñ1€JÐ-ó ð 1<×0AÒ0AØ"ñ1€JÐ-ö r(   rD   c                  ó^   • \ rS rSr% S\S'   \R                  " \S9rS\S'   SS jr	SS jr
S	rg
)ÚFreeableInputBufferéK   r   Únamer/   r+   Ú
mpi_bufferc                ó   • U R                   $ ©N©rM   r7   s    r)   Úget_nameÚFreeableInputBuffer.get_nameR   s   € Ø�y‰yÐr(   c                ó,   • [        U R                  5      $ rP   )ÚhashrM   r7   s    r)   Ú__hash__ÚFreeableInputBuffer.__hash__U   s   € Ü�D—I‘I‹Ðr(   r    N)r?   r   )r?   r   )r"   r#   r$   r%   r&   rA   rB   r+   rN   rR   rV   r'   r    r(   r)   rK   rK   K   s,   ‡ à
ƒIØ.9×.?Ò.?Ø3ñ/€JÐ+ó ô÷r(   rK   c           
     ól  • SS jn[         R                  " [        5      n[         R                  " [        5      n[        5       nU  Hº  nUR                  R
                   H�  nUR                  U;   d  M  [        U5      (       a  M'  XGR                     R                  U5        U" U5      XWR                  '   [        U[        5      (       a  UR                  (       a  M€  X7R                     R                  U5        MŸ     M¼     [        5       nU H   n	[        U	[        XY   X9   XI   S95      X‰'   M"     U$ )z©
Create and keep track of all input buffers that can be freed during the program

Returns:
    A dictionary containing all freeable input buffers, keyed by their names.
c                ó@   • [         R                  R                  U 5      $ rP   )r   ÚgraphÚget_dep_size_hint)Údeps    r)   Ú_dep_size_hintÚ.get_freeable_input_buf.<locals>._dep_size_hintd   s   € Ü�w‰w×(Ñ(¨Ó-Ð-r(   )r.   r2   r3   )r\   r   r?   r   )ÚcollectionsÚdefaultdictr
   ÚdictÚread_writesÚreadsrM   r   ÚaddÚ
isinstancer   Úis_fakerK   r+   )
ÚnodesÚgraph_inputsr]   Údep_name_to_succ_nodesÚ#dep_name_to_succ_nodes_for_orderingÚdep_name_to_sizeÚnoder\   Úname_to_freeable_input_bufÚdep_names
             r)   Úget_freeable_input_bufro   Y   s  € ô.ô 	×Ò¤
Ó+ð ô 	×Ò¤
Ó+ð (ô (,£vÐãˆØ×#Ñ#×)Ô)ˆCØ�x‰x˜<Õ'Ü-¨c×2Ó2ð 8¿¹ÑA×EÑEÀdÔKÙ1?ÀÓ1DÐ$§X¡XÑ.Ü& s¬G×4Ñ4¸¿¿¹Ø.¯x©xÑ8×<Ñ<¸TÖBó *ñ ô BFÃÐÛ7ˆÜ/BØÜ'Ø*Ñ4Ø1Ñ;Ø(KÑ(Uñó0
Ð"Ó,ñ 8ð &Ð%r(   c                óÊ   ^^^^• SSK Jm  SSKJm  [	        5       m S     SUUUU4S jjjmU R                  5        H!  nUR                  5       T;  d  M  T" U5        M#     T$ )aÁ  
Compute the size of each scheduler buffer, including (1) memory allocated when
it is created and (2) memory deallocated when it is freed.

We specially handle the case of MultiOutputLayout.
Consider the following case:
    buf0 = some_ops_with_multi_outputs(...)
    buf1 = buf0[0] # assume 10 bytes
    buf2 = buf0[1] # assume 20 bytes
In such cases,
    buf0: at creation, 30 bytes allocated, when deleted, 0 bytes freed
    buf1: at creation, 0 bytes allocated, when deleted, 10 bytes freed
    buf2: at creation, 0 bytes allocated, when deleted, 20 bytes freed

When an operation mutates a buffer in-place, the scheduler creates a new buffer name
to track the "before" and "after" states, even though they share the same memory.

The mutated buffer represents a rename with zero allocation and deallocation cost.
During dependency tracking, we transfer dependencies from the mutated name back to
the original buffer, ensuring the original memory is only freed when all aliases
are done.

This handles cases where a buffer has multiple non-overlapping aliases - rather than
trying to assign free costs to individual aliases, we forward all alias dependencies
to the original buffer.

Consider:
    buf0 = op0()
    buf1 = mutation_op_(buf0)
    del buf0
    ...
    op(buf1)
    del buf1

The only memory events are the creation prior to op0, and the deletion following buf1.

Returns:
    A dictionary mapping a scheduler buffer to a tuple of (size_alloc, size_free).
r   )ÚMultiOutput)Ú
OutputNodec                ó¤  >• U R                  5       [        R                  R                  R                  ;   a  ST	U R                  5       '   g[        U R                  R                  [        5      (       a  ST	U R                  5       '   g[        U R                  R                  [        5      (       aœ  SnU R                   Hj  n[        UR                  T5      (       a  M   UR                  R                  5        H,  n[        UR                  T5      (       d  M   UT" US5      -  nM.     Ml     U(       a  SOUS4T	U R                  5       '   U$ [        R                  R                  R                  U R                  R                  5       SS9[        U R                  R!                  5       5      -  nU(       a  SOUU4T	U R                  5       '   U$ )N)r   r   r   T)Úfallback)rR   r   rZ   Ú	schedulerÚmutation_real_namere   rl   Úlayoutr   r   ÚusersÚget_outputsÚsizevarsÚ	size_hintÚ	get_numelr   Ú	get_dtype)
Ú	sched_bufÚuser_of_MultiOutputLayoutr-   ÚuserÚbufÚbuf_sizerq   rr   Ú_compute_and_update_buf_sizeÚsched_buf_to_sizes
         €€€€r)   rƒ   ÚGcompute_size_for_scheduler_buffer.<locals>._compute_and_update_buf_size¹   s‚  ø€ ð ×ÑÓ¤1§7¡7×#4Ñ#4×#GÑ#GÓGØ6<Ð˜i×0Ñ0Ó2Ñ3ØÜ˜	Ÿ™×-Ñ-¬z×:Ñ:Ø6<Ð˜i×0Ñ0Ó2Ñ3ØÜ˜	Ÿ™×-Ñ-Ô/@×AÑAØˆJØ!Ÿœ�Ü˜dŸi™i¨×4Ñ4ÙØŸ9™9×0Ñ0Ö2�CÜ! #§(¡(¨K×8Ó8Ø"Ñ&BÀ3ÈÓ&MÑMš
ó 3ñ (ö /‘°JØð7Ð˜i×0Ñ0Ó2Ñ3ð Ðä—w‘w×'Ñ'×1Ñ1Ø—‘×(Ñ(Ó*°Qð 2ð ä˜yŸ~™~×7Ñ7Ó9Ó:ñ;ˆHö /‘°HØð7Ð˜i×0Ñ0Ó2Ñ3ð ˆOr(   )F)r~   r   r   Úboolr?   r   )Úirrq   ru   rr   ra   ÚvaluesrR   )Úname_to_bufr~   rq   rr   rƒ   r„   s     @@@@r)   Ú!compute_size_for_scheduler_bufferrŠ   Š   sw   û€ õT  Ý%ä48³FÐð GLðØ"ðØ?Cðà	÷ó ð@ !×'Ñ'Ö)ˆ	ð ×ÑÓÐ'8Õ8Ù(¨Ö3ñ	 *ð Ðr(   c                ó”  • [        U5      n[        R                  " [        5      n[        R                  " [        5      nU  Hx  nUR                   He  nXFR
                     R                  U5        [        U[        5      (       a  UR                  (       a  MH  X6R
                     R                  U5        Mg     Mz     [        [        R                  R                  R                  R                  5       5       H"  u  pxX8==   UU   -  ss'   XH==   XG   -  ss'   M$     U H$  n	[!        X)   S   X)   S   X9   XI   S9X   l        M&     g)z‡
For each SchedulerBuffer, assign its size info and successor nodes.
A buffer's successor nodes determines when a buffer can be freed.
r   r   )r-   r.   r2   r3   N)rŠ   r_   r`   r
   Úunmet_dependenciesrM   rd   re   r   rf   Úreversedr   rZ   ru   rv   Úitemsr+   rN   )
rg   r‰   r„   ri   rj   rl   r\   Úmutating_buf_nameÚreal_buf_nameÚbuf_names
             r)   Ú1assign_memory_planning_info_for_scheduler_buffersr’   â   s6  € ô :¸+ÓFÐô
 	×Ò¤
Ó+ð ô 	×Ò¤
Ó+ð (ó ˆØ×*Ô*ˆCð 0·±Ñ9×=Ñ=¸dÔCÜ˜s¤G×,Ñ,°··±Ø&§x¡xÑ0×4Ñ4°TÖ:ó +ñ ô -5Ü	�‰×Ñ×,Ñ,×2Ñ2Ó4ö-Ñ(Ðð 	Ó-Ð1GØñ2
ñ 	
Ó-ð 	,Ó:Ø/ÑBñ	
Õ:ñ-ó  ˆÜ+FØ(Ñ2°1Ñ5Ø'Ñ1°!Ñ4Ø-Ñ7Ø$GÑ$Qñ	,
ˆÑÖ(ò  r(   c           	     ó  • [         R                  " [        5      n0 n[         R                  " [        5      nU  HŠ  n[        S UR                  5        5       5      nX…U'   U H  n	XI   R	                  U5        M     UR                  5        H3  n
U
R
                  R                   H  n	Xi   R	                  U
5        M     M5     MŒ     UR                  5        H3  nUR
                  R                   H  n	Xi   R	                  U5        M     M5     [        U 5       He  u  pÇ[        S UR                  5        5       5      nXW   nXG   nUR                  U5        UR                  U5        [        UUXg   XG   US9Ul        Mg     g)zD
Assign to each scheduler node its predecessor and successor nodes.
c              3  ób   #   • U  H%  nUR                   R                    H  nUv •  M	     M'     g 7frP   )rN   r3   )Ú.0ÚbufferÚ	succ_nodes      r)   Ú	<genexpr>ÚBassign_memory_planning_info_for_scheduler_nodes.<locals>.<genexpr>'  s0   é € ð  
â,�Ø#×.Ñ.×FÕF�	õ áFñ Ú,ùs   ‚-/c              3  óL   #   • U  H  oR                   R                  v •  M     g 7frP   )rN   r-   )r•   r–   s     r)   r˜   r™   ?  s   é € ÐWÒDV¸&×*Ñ*×5Ö5ÒDVùó   ‚"$)rF   rG   rH   rI   r2   N)r_   r`   r
   ry   rd   rN   r2   rˆ   Ú	enumerateÚsumÚdiscardrD   Úmpi_node)rg   Úname_to_fused_noder‰   rm   Únode_to_pred_nodesÚnode_to_succ_nodesÚnode_to_pred_buffersrl   r2   r—   r–   Úfreeable_bufferrF   r-   rI   s                  r)   Ú/assign_memory_planning_info_for_scheduler_nodesr¥     s|  € ô 	×Ò¤
Ó+ð ð RTÐô 	×Ò¤
Ó+ð ó
 ˆÜñ  
à×*Ñ*Ô,ó 
ó 
ˆ
ð
 $.˜4Ñ ó $ˆIØÑ)×-Ñ-¨dÖ3ñ $ð ×&Ñ&Ö(ˆFØ#×.Ñ.×9Ô9�	Ø$Ñ/×3Ñ3°FÖ;ó :ó )ñ ð& 6×<Ñ<Ö>ˆØ(×3Ñ3×>Ô>ˆIØ Ñ+×/Ñ/°Ö@ó ?ñ ?ô
 ! Ö'‰ˆÜÑWÀD×DTÑDTÔDVÓWÓWˆ
Ø'Ñ-ˆ
Ø'Ñ-ˆ
ð 	×Ñ˜4Ô Ø×Ñ˜4Ô ä1ØØØ-Ñ3Ø)Ñ/Ø!ñ
ˆŽò (r(   c                  óH   • \ rS rSr% S\S'   S\S'   S\S'   S\S'   S\S'   S	rg
)Ú
BufferInfoiQ  z+Union[SchedulerBuffer, FreeableInputBuffer]r–   r   r-   r.   Ú
start_stepÚend_stepr    Nr!   r    r(   r)   r§   r§   Q  s   ‡ à7Ó7ØƒOØƒNØƒOØ†Mr(   r§   c                ó¼  ^• [        U 5       VVs0 s H  u  p4XC_M	     snnm/ n0 n    SU4S jjnUR                  5        He  u  p‰Sn
X‚;  a  U" U	5      u  p«Uc   eX¶U	'   UR                  [        U	U	R                  R
                  U	R                  R
                  SU
5      5        Mg     [        U 5       H™  u  p4UR                  5        H€  nUR                  5       nSn
X‚;  a   U" U5      u  p«U
S:X  a  Un
XFU'   O	Uc   eX¶U'   UR                  [        UUR                  R                  UR                  R
                  UU
5      5        M‚     M›     UTU4$ s  snnf )z^
Compute buffer allocation and deallocation sizes and map their
lifetime to the node schedule
c                óˆ   >• SnS nU R                   R                  nU(       a  U H  nTU   nXQ:”  d  M  UnUnM     Uc   eX4$ )Néÿÿÿÿ)rN   r2   )r�   Úmax_stepÚmax_step_snoder2   r—   ÚstepÚnode_to_steps         €r)   Ú_get_end_step_and_snodeÚ8compute_memory_timeline.<locals>._get_end_step_and_snodet  s[   ø€ ð ˆØ6:ˆØ—^‘^×.Ñ.ˆ
ÞÛ'�	Ø# IÑ.�Ø•?Ø#�HØ%.’Nñ	 (ð
 "Ñ-Ð-Ð-ØÐ'Ð'r(   r¬   r   )r�   z+Union[FreeableInputBuffer, SchedulerBuffer]r?   z'tuple[int, Optional[BaseSchedulerNode]])	rœ   rŽ   Úappendr§   rN   r.   ry   rR   r-   )rg   rm   Úgraph_outputsr¯   rl   Úbuf_info_listÚbuf_to_snode_last_user±   r‘   Ú	input_bufr©   Úend_step_snoder~   r°   s                @r)   Úcompute_memory_timeliner¹   Z  s™  ø€ ô" &/¨uÔ%5ô2Ú%5‘z�tˆŠ
Ñ%5ò2€Lð
 ')€Mð 	ð ð(Ø8ð(à	0÷(ð   :×?Ñ?ÖAÑˆØˆØÓ(Ù'>¸yÓ'IÑ$ˆHØ!Ñ-Ð-Ð-Ø/= )Ñ,à×ÑÜØØ×$Ñ$×.Ñ.Ø×$Ñ$×.Ñ.ØØóö	
ñ  Bô$   Ö&‰
ˆØ×)Ñ)Ö+ˆIð !×)Ñ)Ó+ˆHØˆHØÓ,Ù+BÀ9Ó+MÑ(�Ø˜r“>Ø#�HØ7;¨)Ò4à)Ñ5Ð5Ð5Ø7E¨)Ñ4à× Ñ ÜØØ×(Ñ(×3Ñ3Ø×(Ñ(×2Ñ2ØØóöó ,ñ 'ð4 ˜,Ð(=Ð=Ð=ùóM2s   �Ec                ó¦  • [        XU5      u  n  n[        [        U 5      S-   5       Vs/ s H  nSPM     nnU HF  nXVR                  ==   UR                  -  ss'   XVR
                  S-   ==   UR                  -  ss'   MH     SnSn/ n	[        [        U 5      S-   5       H&  n
X…U
   -  nU	R                  U5        [        Xx5      nM(     Xy4$ s  snf )zô
Given a list of nodes in their execution order, estimate the peak memory, by
keeping track of the liveliness of SchedulerBuffers and FreeableInputBuffers.

Returns:
    int: peak memory
    List[int]: memory usage at each node (or each step).
r   r   )	r¹   Úranger6   r¨   r-   r©   r.   r³   Úmax)rg   rm   r´   rµ   Ú_ÚmemoryÚbuf_infoÚ
max_memoryÚ
cur_memoryÚmemories_at_nodesÚts              r)   Úestimate_peak_memoryrÄ   ³  sá   € ô 2Ø¨=óÑ€M�1�aô
 œs 5›z¨A™~Ô.Ó/Ò.�A‹aÑ.€FÐ/ó "ˆØ×"Ñ"Ó# x×':Ñ':Ñ:Ó#Ø× Ñ  1Ñ$Ó%¨×);Ñ);Ñ;Õ%ñ "ð
 €JØ€JØÐÜ”3�u“: ‘>Ö"ˆØ˜Q‘iÑˆ
Ø× Ñ  Ô,Ü˜Ó0Š
ñ #ð
 Ð*Ð*ùò! 0s   ªCc                  ó*   • \ rS rSr% S\S'   S\S'   Srg)ÚSNodeMemoryiÙ  r   r-   r.   r    Nr!   r    r(   r)   rÆ   rÆ   Ù  s   ‡ àƒOØ†Nr(   rÆ   c                ó|  • [        XU5      u  p4n[        [        U 5      5       Vs/ s H  n[        SS5      PM     nnU Hk  nXgR                     =R
                  UR
                  -  sl        UR                  S:w  d  M@  XgR                     =R                  UR                  -  sl        Mm     0 n[        U 5       H  u  pšXi   XŠ'   M     SnSn/ n[        [        U 5      5       HJ  nXn   R
                  nXn   R                  nXÏ-  nUn[        X¼5      nUU-  nUnUR                  UU45        ML     UUUU4$ s  snf )aª  
Alternative version of estimate_peak_memory, that respects the fact,
that every SchedulerNode has multiple phases:
1. alloc ( outputs )
2. run_kernel
3. dealloc last_use buffers
estimate_peak_memory collapses memory into one value: size_alloc - size_free
While peak memory happens after alloc.

Duplicating the code to not migrate all callsites at once,
In future usages of estimate_peak_memory will migrate to this version.
r   r¬   )r¹   r»   r6   rÆ   r¨   r-   r©   r.   rœ   r¼   r³   )rg   rm   r´   rµ   r½   r¶   Ústep_idx_allocfreer¿   Úsnodes_allocfreeÚirl   rÀ   rÁ   Úsnodes_curr_memoryrÃ   ÚallocÚfreeÚ
post_allocÚ	post_frees                      r)   Úestimate_peak_memory_allocfreerÐ   ß  sZ  € ô. /FØ¨=ó/Ñ+€MÐ+ô
 6;¼3¸u»:Ô5FÓGÒ5F°œ+ a¨Ö+Ñ5FÐÐGó "ˆØ×.Ñ.Ñ/×:Ò:¸h×>QÑ>QÑQÕ:Ø×Ñ Õ"Ø×0Ñ0Ñ1×;Ò;¸x×?QÑ?QÑQ×;ñ "ð
 ÐÜ˜UÖ#‰ˆØ!3Ñ!6ÐÓñ $ð €JØ€JØÐÜ”3�u“:ÖˆØ"Ñ%×0Ñ0ˆØ!Ñ$×.Ñ.ˆØÑˆ
Øˆ
Ü˜Ó0ˆ
Ø�dÑˆ
Øˆ	Ø×!Ñ! :¨yÐ"9Ö:ñ ð 	ØØØð	ð ùò3 Hs   ¦D9c                óì  ^ ^^•  " S S[         5      n " S S[         5      n[        5       m[        5       n[        5       nT  HG  n[        UR                  R
                  5      SS.TU'   TU   S   S:X  d  M6  UR                  U5        MI     [        UR                  5       5      [        UR                  5       5      -    H?  n	S[        U	R                  R                  5      U	R                  5       U;   a  S	OS-   0Xi'   MA     [        S
 UR                  5        5       5      n
SnU HG  nXÂ;   a  X²U   R                  R                  -  nM%  XÁ;   d  M,  X±U   R                  R                  -  nMI     [        X«5      nXÚ-
  mT  H™  nUR                  R                   H4  n	Xi   S   S	:X  d  M  TU   S==   U	R                  R                  -  ss'   M6     UR!                  5        H4  n	Xi   S   S:X  d  M  TU   S==   U	R                  R                  -  ss'   M6     M›     / n["        R$                  nSnU[        T 5      :  Ga–  U(       GaŽ  US:”  a%  ['        S U 5       5      U:”  a  ['        UU 4S jS9nO['        UUU4S jS9nUR)                  U5        UR+                  U5        US	-  nU
UR                  R,                  -  n
[        XÚ5      nU
TU   S   -  n
XÚ-
  mUR                  R                   H@  nTU   S   S:”  d   eTU   S==   S	-  ss'   TU   S   S:X  d  M/  UR                  U5        MB     UR                  R                   Hm  n	Xi   S   S:”  d   eXi   S==   S	-  ss'   Xi   S   S	:X  d  M,  U	R                  R                   H'  nTU   S==   U	R                  R                  -  ss'   M)     Mo     U[        T 5      :  a
  U(       a  GMŽ  U[        T 5      :”  a  [/        S5      eU$ )a±  
A bfs-based greedy topological order. LPMF stands for "Least Peak Memory First".

The idea is from this paper:
Buffer memory optimization for video codec application modeled in Simulink
https://www.cs.york.ac.uk/rts/docs/DAC-1964-2006/PAPERS/2006/DAC06/PDFFILES/P0689.PDF

The algorithm maintains the max memory so far.
At every iteration, for each scheduleable node, it computes:
    - how much memory needs to be allocated for the output buffers of this node;
    - how much memory can be freed as a result of executing this node.
This gives us two values for each node:
    (1) mem1: memory during the execution of the node;
    (2) mem2: memory after executing the node, after some input buffers are freed.
The greedy approach select as follows:
    (i) if there are nodes whose mem1 values are below the max memory so far,
        then pick the node with the lowest mem2 value;
    (ii) otherwise, pick the one with the lowest mem1 value.
c                  ó*   • \ rS rSr% S\S'   S\S'   Srg)Ú'topological_sort_lpmf.<locals>.NodeInfoi6  r   ÚindegreeÚmemory_to_freer    Nr!   r    r(   r)   ÚNodeInforÓ   6  s   ‡ Ø‹ØÖr(   rÖ   c                  ó    • \ rS rSr% S\S'   Srg)Ú)topological_sort_lpmf.<locals>.BufferInfoi:  r   Ú	outdegreer    Nr!   r    r(   r)   r§   rØ   :  s   ‡ ØŽr(   r§   r   )rÔ   rÕ   rÔ   rÙ   r   c              3  óN   #   • U  H  nUR                   R                  v •  M     g 7frP   ©rN   r.   )r•   r·   s     r)   r˜   Ú(topological_sort_lpmf.<locals>.<genexpr>S  s#   é € ð â<ˆIð 	×Ñ×&Ö&Ú<ùó   ‚#%rÕ   c              3  óL   #   • U  H  oR                   R                  v •  M     g 7frP   )rŸ   rG   )r•   rl   s     r)   r˜   rÜ   w  s   é € ÐEÒ3D¨4—M‘M×&Ö&Ò3Dùr›   c                ó`   >• [        S U R                  R                   5       [        T5      S9$ )Nc              3  óN   #   • U  H  nUR                   R                  v •  M     g 7frP   ©rŸ   rF   )r•   r—   s     r)   r˜   Ú:topological_sort_lpmf.<locals>.<lambda>.<locals>.<genexpr>|  s#   é € ð â)A˜Ið "×*Ñ*×0Ö0Ú)AùrÝ   )Údefault)ÚminrŸ   r2   r6   )rl   rg   s    €r)   r9   Ú'topological_sort_lpmf.<locals>.<lambda>{  s*   ø€ ¤ñà)-¯©×)AÒ)Aóô   ›Jò"r(   ©Úkeyc                óÐ   >• U R                   R                  T:”  a  U R                   R                  OSU R                   R                  TU    S   -
  U R                   R                  4$ )Nr   rÕ   )rŸ   rG   rF   )rl   Ú
memory_gapÚ	node_infos    €€r)   r9   rå   †  sQ   ø€ Ø*.¯-©-×*<Ñ*<¸zÓ*I�D—M‘M×&Ò&ÈqØ—M‘M×&Ñ&¨°4©Ð9IÑ)JÑJØ—M‘M×'Ñ'ñ"r(   z4Failed to schedule, while loop ran too long for lpmf)r   ra   r
   r6   rŸ   rI   rd   Úlistrˆ   rN   r2   rR   r�   r.   r¼   rH   ry   r   Ú&size_threshold_for_succ_based_strategyrä   Úremover³   rG   ÚRuntimeError)rg   rm   r‰   r´   rÖ   r§   r¿   Únodes_to_schedulerl   r�   Úlive_memoryÚoutput_memoryr‘   rÀ   ÚscheduleÚsize_thresholdÚ	num_itersÚselected_noder—   ré   rê   s   `                  @@r)   Útopological_sort_lpmfrö     sä  ú€ ô4”9ô ô”Yô ô 48³6€IÜNRËf€Hô 8B³|ÐÛˆä˜DŸM™M×4Ñ4Ó5Øñ
ˆ	�$‰ð �T‰?˜:Ñ&¨!Õ+Ø×!Ñ! $Ö'ñ ô �K×&Ñ&Ó(Ó)¬DÐ1K×1RÑ1RÓ1TÓ,UÔUˆàœ˜SŸ^™^×6Ñ6Ó7Ø—L‘L“N mÓ3‰q¸ñ<ð
ˆ‹ñ Vô ñ à3×:Ñ:Ô<óó €Kð €MÛ!ˆØÓ"Ø¨Ñ2×=Ñ=×GÑGÑGŠMØÕ3Ø¸ÑA×LÑL×VÑVÑVŠMñ	 "ô
 �[Ó0€JØÑ)€Jó ˆà—=‘=×-Ô-ˆCØ‰}˜[Ñ)¨QÕ.Ø˜$‘Ð 0Ó1°S·^±^×5MÑ5MÑMÕ1ñ .ð ×#Ñ#Ö%ˆCØ‰}˜[Ñ)¨QÕ.Ø˜$‘Ð 0Ó1°S·^±^×5MÑ5MÑMÕ1ó &ñ ð )+€HÜ×BÑB€NØ€IØ
”c˜%“jÔ
 ×%6ð ˜QÓÜÑEÑ3DÓEÓEÈÓVäØ!ôñ	‰Mô  Ø!õñˆMð 	× Ñ  Ô/Ø�‰˜Ô&Ø�Q‰ˆ	ð 	�}×-Ñ-×2Ñ2Ñ2ˆÜ˜Ó1ˆ
Ø�y Ñ/Ð0@ÑAÑAˆØÑ-ˆ
ð '×/Ñ/×:Ô:ˆIØ˜YÑ'¨
Ñ3°aÓ7Ð7Ð7Ø�iÑ  Ó,°Ñ1Ó,Ø˜Ñ# JÑ/°1Õ4Ø!×%Ñ% iÖ0ñ	 ;ð !×)Ñ)×6Ô6ˆCØ‘= Ñ-°Ó1Ð1Ð1Ø‰M˜+Ó&¨!Ñ+Ó&Ø‰}˜[Ñ)¨QÕ.Ø!$§¡×!:Ô!:�IØ˜iÑ(Ð)9Ó:¸c¿n¹n×>VÑ>VÑVÕ:ó ";ñ	 7ðW ”c˜%“jÓ
 ×%6Ñ%6ðd ”3�u“:ÓÜÐQÓRÐRà€Or(   c           	     óF  ^
•  " S S[         5      n[        5       m
[        R                   " S S5      5       nSU
4S jjn/ nU  HY  n[	        UR
                  R                  5      SS.T
U'   T
U   S   S	:X  d  M6  [        R                  " XB" U" U5      U5      5        M[     / nS	nU[	        U 5      :  aÓ  U(       aÌ  [        R                  " U5      R                  n[	        U5      T
U   S
'   UR                  U5        US-  nUR
                  R                   HS  n	T
U	   S   S	:”  d   eT
U	   S==   S-  ss'   T
U	   S   S	:X  d  M/  [        R                  " UU" U" U	5      U	5      5        MU     U[	        U 5      :  a	  U(       a  MÌ  U[	        U 5      :”  a  [        S5      eU$ )aÛ  
A BFS topological sort that selects nodes whose dependencies are executed the
earliest. This follows a FIFO idea. Specifically, at every iteration, for each node
that is schedulable, we gather the order in which its predecessor nodes are executed,
and this sorted list of execution orders of predecessor nodes defines the priority.
We select the node whose predecessors nodes are executed the earliest. The FIFO
idea aims to reduce the liveness duration of buffers created.
c                  ó*   • \ rS rSr% S\S'   S\S'   Srg)Ú&topological_sort_bfs.<locals>.NodeInfoiµ  r   rÔ   r   r    Nr!   r    r(   r)   rÖ   rù   µ  s   ‡ Ø‹ØŽ
r(   rÖ   c                  ó4   • \ rS rSr% S\S'   S\S'   S	S jrSrg)
Ú.topological_sort_bfs.<locals>.NodeWithPriorityi»  ú	list[int]Úpriorityr   rl   c                óê   • U R                   UR                   :X  aA  U R                  R                  R                  UR                  R                  R                  :  $ U R                   UR                   :  $ rP   )rý   rl   rŸ   rF   )r8   Úothers     r)   Ú__lt__Ú5topological_sort_bfs.<locals>.NodeWithPriority.__lt__À  sP   € Ø�}‰} §¡Ó.Ø—y‘y×)Ñ)×/Ñ/°%·*±*×2EÑ2E×2KÑ2KÑKÐKØ—=‘= 5§>¡>Ñ1Ð1r(   r    N)rÿ   ÚNodeWithPriorityr?   r†   )r"   r#   r$   r%   r&   r   r'   r    r(   r)   r  rû   »  s   ‡ àÓØÓ÷	2r(   r  c                óˆ   >• TU    S   S:X  d   e[        [        U4S jU R                  R                   5       5      5      nU$ )NrÔ   r   c              3  ó4   >#   • U  H  nTU   S    v •  M     g7f)r   Nr    )r•   Ú	pred_noderê   s     €r)   r˜   Ú?topological_sort_bfs.<locals>._node_priority.<locals>.<genexpr>É  s   øé € ð Ú?W°)�	˜)Ñ$ WÖ-Ò?Wùs   ƒ)Úsortedr
   rŸ   rI   )rl   Úexec_ordersrê   s     €r)   Ú_node_priorityÚ,topological_sort_bfs.<locals>._node_priorityÅ  sK   ø€ à˜‰˜zÑ*¨aÓ/Ð/Ð/ÜÜô Ø?C¿}¹}×?WÒ?Wóó ó
ˆð
 Ðr(   r¬   )rÔ   r   rÔ   r   r   r   z3Failed to schedule, while loop ran too long for bfs)rl   r   r?   rü   )r   ra   rA   Ú	dataclassr6   rŸ   rI   ÚheapqÚheappushÚheappoprl   r³   r2   rî   )rg   rÖ   r  r	  rï   rl   rò   rô   rõ   r—   rê   s             @r)   Útopological_sort_bfsr  «  s˜  ø€ ô”9ô ô 48³6€Iä×Ñ÷2ð 2ó ð2÷ð 13ÐÛˆÜ'*¨4¯=©=×+CÑ+CÓ'DÈrÑRˆ	�$‰Ø�T‰?˜:Ñ&¨!Õ+Ü�NŠNØ!Ð#3±NÀ4Ó4HÈ$Ó#Oöñ ð )+€HØ€IØ
”c˜%“jÓ
 Ö%6äŸšÐ&7Ó8×=Ñ=ˆÜ,/°«Mˆ	�-Ñ  Ñ)Ø�‰˜Ô&Ø�Q‰ˆ	ð '×/Ñ/×:Ô:ˆIØ˜YÑ'¨
Ñ3°aÓ7Ð7Ð7Ø�iÑ  Ó,°Ñ1Ó,Ø˜Ñ# JÑ/°1Õ4Ü—’Ø%Ù$¡^°IÓ%>À	ÓJöñ	 ;ð ”c˜%“jÓ
 ×%6Ð%6ð" ”3�u“:ÓÜÐPÓQÐQà€Or(   c                ó~  ^^^^^• [        5       m[        5       m/ m[        5       mSUUUUU4S jjmU  H  nUR                  5        H  nUTU'   M
     M!     U  HC  nUR                  R                  [        S UR                  R                   5       5      -   TU'   ME     [        U U4S jS9 H  nT" U5        M     T$ )aÃ  
This is a DFS topological sort. The setup is similar to `topological_sort_schedule`
in scheduler.py. The difference is the order nodes are visited in the outer loop.
In `topological_sort_schedule`, nodes are visited in their original order.
In this function, nodes are visited based on their priority -- for each node, we
compute the total memory of all buffers it reads from or writes to, and we visit
the nodes in ascending order of this priority.
c                ó  >• U T;  a{  TR                  U 5        U R                   Vs/ s H$  nUR                  T;   d  M  TUR                     PM&     nn[        UU4S jS9 H  nT" U5        M     TR	                  U 5        g g s  snf )Nc                ó:   >• TU    U R                   R                  4$ rP   rá   ©ÚnÚsize_with_readss    €r)   r9   Ú5topological_sort_dfs.<locals>.visit.<locals>.<lambda>
  s   ø€ ¨/¸!Ñ*<¸a¿j¹j×>NÑ>NÑ)Or(   ræ   )rd   rŒ   rM   r  r³   )	r  r\   Ú	dep_nodesrl   Úname_to_nodeÚresultÚseenr  Úvisits	       €€€€€r)   r  Ú#topological_sort_dfs.<locals>.visit  sŒ   ø€ Ø�D‹=Ø�H‰H�QŒKð ×/Ò/óâ/�CØ—8‘8˜|Ñ+ó '�˜SŸX™XÔ&Ù/ð ð ô
 ØÔOô�ñ �d–ñð �M‰M˜!Õð ùòs
   §B¿Bc              3  óL   #   • U  H  oR                   R                  v •  M     g 7frP   rÛ   )r•   Úpred_bufs     r)   r˜   Ú'topological_sort_dfs.<locals>.<genexpr>  s   é € ð 9
Ú:T¨h×Ñ×)Ö)Ò:Tùr›   c                ó:   >• TU    U R                   R                  4$ rP   rá   r  s    €r)   r9   Ú&topological_sort_dfs.<locals>.<lambda>  s   ø€ ¨_¸QÑ-?ÀÇÁ×AQÑAQÑ,Rr(   ræ   )r  r   r?   r@   )r
   ra   Úget_buffer_namesrŸ   rG   r�   rH   r  )rg   rl   rM   r  r  r  r  r  s      @@@@@r)   Útopological_sort_dfsr#  ó  s¸   ü€ ô +5«,€DÜ15³€LØ&(€FÜ48³F€O÷ó ó ˆØ×)Ñ)Ö+ˆDØ!%ˆL˜Óó ,ñ ó ˆØ $§¡× 2Ñ 2´Sñ 9
Ø:>¿-¹-×:TÒ:Tó9
ó 6
ñ !
ˆ˜Óñ ô �uÔ"RÔSˆÙˆdŽñ Tð €Mr(   c                ó˜   ^^^^^• Su  nmm[         R                  X5      m/ mSUUUUU4S jjmU  H  nTU   U:X  d  M  T" U5        M     g)zŠ
Validate that the graph is acyclic by checking predecessor relationships.

Raises:
    RuntimeError: If a cycle is detected in the graph
)r   r   é   c                ó‚  >• TU    T:X  a  g TU    T:X  aO  TR                  U 5        SR                  T V s/ s H  o R                  5       PM     sn 5      n[        SU S35      eTTU '   TR                  U 5        U R                  R
                   H  nX :w  d   eT" U5        M     TR                  5         TTU '   g s  sn f )Nz -> z_Cycle detected in memory planning graphPath containing cycle (i -> j: j is a dependency of i): zG This indicates invalid dependency relationships in the scheduler graph)r³   ÚjoinrR   rî   rŸ   rI   Úpop)rl   Ú	path_infor  ÚBLACKÚGRAYÚcolorÚ	dfs_visitÚpaths      €€€€€r)   r-  Ú)validate_graph_acyclic.<locals>.dfs_visit-  sÉ   ø€ Ø�‰;˜%ÓØà�‰;˜$ÓØ�K‰K˜ÔØŸ™ÁÓ$FÂ¸§]¡]¦_ÁÑ$FÓGˆIäðKØKTÈ+ð VYðZóð ð ˆˆd‰Ø�‰�DÔàŸ™×1Ô1ˆIØÓ$Ð$Ð$Ù�iÖ ñ 2ð 	�‰Œ
ØˆˆdŠùò! %Gs   µB<N)rl   r   r?   r@   )ra   Úfromkeys)rg   ÚWHITErl   r*  r+  r,  r-  r.  s      @@@@@r)   Úvalidate_graph_acyclicr2    sM   ü€ ð !Ñ€Eˆ4�Ü�M‰M˜%Ó'€EØ$&€D÷ó ó2 ˆØ�‰;˜%ÕÙ�dŽOò r(   c                ór  • U  H±  nUR                  5        Hš  nUR                  5       nXQ;  a  [        U SUR                  5        S35      eX   U:w  a6  [        SU SU SUR                  5        SX   R                  5        S3	5      eXR;   d  M|  [        SU S	UR                  5        S
35      e   M³     g)a>  
Validate that for each node's output buffer, the name_to_buf mapping is correct.
For each output buffer buf, we should have name_to_buf[buf.get_name()] == buf.
Also validate that no buffer names overlap with freeable input buffer names.

Raises:
    RuntimeError: If buffer name mapping is incorrect or names overlap
z from zN is not found in name_to_buf mapping. This indicates a missing buffer mapping.z&Buffer name mapping is incorrect for 'z'.Expected name_to_buf['z	'] to be zbut got z/This indicates some buffers share the same namez Buffer name conflict detected: 'z' from node z/ is also used as a freeable input buffer name. N)ry   rR   rî   Ú	debug_str)rg   r‰   rm   rl   r�   r‘   s         r)   Úvalidate_unique_buffer_namesr5  K  së   € ó ˆØ×#Ñ#Ö%ˆCØ—|‘|“~ˆHð Ó*Ü"Ø�j  t§}¡}£Ð&7ð 8@ð Aóð ð Ñ$¨Ó+Ü"Ø<¸X¸Jð G-Ø-5¨J°iÀÇÁÃÐ?PØ˜{Ñ4×>Ñ>Ó@ÐAØEðGóð ð Õ5Ü"Ø6°x°jÀÈTÏ]É]Ë_ÐL]ð ^Eð Fóð ó+ &ò r(   c                óh   • [        X5      n[        X5        [        XX5        [        XU5      u  pgXe4$ )a   
Prepare planning info. As nodes are scheduled one at a time, these help
keep track of when a buffer can be freed, and when a node can be scheduled

Returns:
    int: peak memory estimation
    dict[str, FreeableInputBuffer]: name to freeable input buffer
)ro   r’   r¥   rÄ   )rg   r‰   r    rh   r´   rm   Úestimated_peak_memoryr½   s           r)   Úprepare_planning_infor8  t  sD   € ô "8¸Ó!LÐÜ5°eÔIÜ3Ø ;ôô
  4Ø¨=ó ÑÐð !Ð<Ð<r(   c           
     óò  • [         R                  S[        U 5      5        [        U UUUU5      u  pg[        R
                  (       a  [        U UUUU5         [        U 5        [        XU5        / nUR                  [        XS5      5        [         R                  SU5        U H�  n	 U	[        L a
  U	" XX5      n
OU	" U 5      n
[        U
5      [        U 5      :X  d   e[        X§U5      u  p¼UR                  [        X«U	R                   5      5        [         R                  SU	R                   U5        M�     [%        SSS	U Vs0 s H  oÝR&                  UR(                  _M     sn0S
9  [+        US S9nUR,                  $ ! [         a)    [         R                  S5        [        5       (       d  e  GNAf = f! ["         a5    [         R                  SU	R                   5        [        5       (       d  e  GMN  f = fs  snf )z“
Try a few heuristics based topological sort algorithms, and pick the one whose
resulting topological order has the lowest peak memory estimation.
z&Reordering for peak memory -- %d nodesz!Memory planning validation failedÚbaselinezBaseline peak memory: %dz%s peak memory: %dzFailed to reorder for %sÚinductorr¾   Úorm)ÚcategoryrM   Ú
parametersc                ó   • U R                   $ rP   )r   )Úxs    r)   r9   Ú)reorder_for_peak_memory.<locals>.<lambda>å  s   € ¸a¿mºmr(   ræ   )Ú	torch_logÚinfor6   r8  r   Úreorder_for_peak_memory_debugÚexport_graph_for_simulatorr2  r5  rî   Ú	exceptionr   r³   r   rö   rÄ   r"   Ú	Exceptionr	   r   r   rä   r   )rg   r‰   r    rh   r´   Úmethodsr7  rm   Úpeak_memory_diff_methodsr   r   r   r½   ÚelemÚbest_results                  r)   Úreorder_for_peak_memoryrL  ‘  sî  € ô" ‡N�NÐ;¼SÀ»ZÔHä8MØØØØØó9Ñ5Ðô ×+×+Ü"ØØ&ØØØô	
ðÜ˜uÔ%Ü$ UÐ9SÔTð 8:ÐØ×#Ñ#Ü˜°zÓBôô ‡N�NÐ-Ð/DÔEó ˆð	ØÔ.Ò.ÙØ°{ó‘ñ ˜u›�Ü�u“:¤ U£Ó+Ð+Ð+Ü1Ø°=ó‰NˆKð %×+Ñ+Ü  °V·_±_ÓEôô �N‰NÐ/°·±À+ÖNñ ô* ØØàÑ>VÓWÒ>V°d—K‘K ×!1Ñ!1Ò1Ñ>VÑWð
òô Ð.Ñ4KÑL€Kà×ÑÐøô[ ó Ü×ÑÐ?Ô@Ü�{‰{Øò ðûô: ó 	Ü×ÑÐ :¸F¿O¹OÔLÜ—;‘;Øó ð	üò Xs+   ÁE< Â&B	F2Ä? G4Å</F/Æ.F/Æ2:G1Ç0G1c                ó  ^^•  " S S[         5      n " S S[         5      n " S S[         5      n/ n/ n	UR                  5        H_  u  p«U
UR                  R                  UR                  R                  UR                  R                  SX¤;   / / S.nUR	                  U5        Ma     U  VVs0 s H*  oÝR                  5         H  oîR                  5       U_M     M,     nnnUR                  5        HÖ  u  n
nUR                  c  M  UUR                  R                  5          R                  R                   Vs/ s H  nUR                  5       PM     nnU
UR                  R                  UR                  R                  UR                  R                  S
X¤;   UU V
s/ s H  oªU;  d  M
  U
PM     sn
S.nUR	                  U5        MØ     U  H>  nUR                  5       [        UR                  5       5      S.nU	R	                  U5        M@     U	US.nSS	KnSS	KnSS	KnSSKJn  UR$                  R'                  U" 5       5      S   S-   mUR)                  USS9mUR*                  R-                  SU4S jU4S jS9  g	s  snnf s  snf s  sn
f )z¥
This is for debugging purposes. It will dump a json file that records graph information.
The graph can then be used in a simulator: https://fburl.com/code/3l3d3qi4
c                  óf   • \ rS rSr% S\S'   S\S'   S\S'   S\S'   S\S	'   S\S
'   S\S'   S\S'   Srg)Ú-export_graph_for_simulator.<locals>.ORMBufferiö  r   rM   r   r-   r.   rG   r†   Úis_inputÚ	is_outputú	list[str]ÚdepsÚ
unmet_depsr    Nr!   r    r(   r)   Ú	ORMBufferrO  ö  s+   ‡ Ø‹	Ø‹Ø‹Ø‹	Ø‹Ø‹Ø‹ØÖr(   rU  c                  ó*   • \ rS rSr% S\S'   S\S'   Srg)Ú+export_graph_for_simulator.<locals>.ORMNodei   r   rM   rR  Úbuffer_namesr    Nr!   r    r(   r)   ÚORMNoderW     s   ‡ Ø‹	ØÖr(   rY  c                  ó*   • \ rS rSr% S\S'   S\S'   Srg)Ú,export_graph_for_simulator.<locals>.ORMGraphi  zlist[ORMNode]rg   zlist[ORMBuffer]Úbuffersr    Nr!   r    r(   r)   ÚORMGraphr[    s   ‡ ØÓØ Ö r(   r]  T)rM   r-   r.   rG   rP  rQ  rS  rT  NF)rM   rX  )rg   r\  r   )Úget_graph_being_compiledÚ_fusedr%  )ÚindentÚartifactc                 ó   >• T SS.$ )NÚstring)rM   Úencodingr    rQ   s   €r)   r9   Ú,export_graph_for_simulator.<locals>.<lambda>O  s   ø€ ØØ ò
r(   c                 ó   >• T $ rP   r    )Úg_strs   €r)   r9   re  S  s   ø€ ™5r(   )Úmetadata_fnÚ
payload_fn)r   rŽ   rN   r.   r³   ry   rR   Údefining_oprŸ   rH   r-   rë   r"  ÚjsonÚosr;   Úfunctorch.compiler^  r.  ÚsplitextÚdumpsÚ_loggingÚtrace_structured)rg   rm   r    rh   r´   rU  rY  r]  Úorm_buffersÚ	orm_nodesr‘   r·   Úorm_buf_input_bufferrl   r�   r‰   r~   r  rS  Úorm_buf_scheduler_bufferÚorm_nodeÚgrk  rl  r;   r^  rg  rM   s                             @@r)   rE  rE  ê  s�  ù€ ô”Iô ô ”)ô  ô!”9ô !ð $&€KØ!€Ið  :×?Ñ?ÖAÑˆàØ#×.Ñ.×8Ñ8Ø"×-Ñ-×7Ñ7Ø×(Ñ(×2Ñ2ØØ!Ñ2ØØñ	+
Ðð 	×ÑÐ/Ö0ñ  Bñ ).ô/Ú(- ×9IÑ9I×9K°#�‰‹˜ÒÑ9K‰©ð ñ /ð  +×0Ñ0Ö2Ñˆ�)Ø× Ñ Ñ(Ùð /Ø×%Ñ%×.Ñ.Ó0ñç‰h—|‘|ð$ó
ò$�ð ×ÑÖñ$ð 	ð 
ð Ø#×.Ñ.×9Ñ9Ø"×-Ñ-×7Ñ7Ø×(Ñ(×2Ñ2ØØ!Ñ2Øá)-óÚ)-˜XÀÑ1M—©ññ/
Ð ð 	×ÑÐ3Ö4ñ+  3ó0 ˆà—M‘M“OÜ  ×!6Ñ!6Ó!8Ó9ñ
ˆð 	×Ñ˜Ö"ñ ð Øñ€Aó ÛãÝ:à�7‰7×ÑÑ4Ó6Ó7¸Ñ:¸XÑE€Dà�J‰J�q ˆJÐ#€Eà	‡N�N×#Ñ#Øô
ô !ð $ò ùóg/ùò
ùòs   Â,1I?Ä8JÆ	J
Æ*J
)rg   r   rh   úOrderedSet[str]r?   údict[str, FreeableInputBuffer])r‰   údict[str, SchedulerBuffer]r?   zdict[str, tuple[int, int]])rg   r   r‰   rz  r?   r@   )
rg   r   r    údict[str, BaseSchedulerNode]r‰   rz  rm   ry  r?   r@   )rg   r   rm   ry  r´   rx  r?   z{tuple[list[BufferInfo], dict[BaseSchedulerNode, int], dict[Union[FreeableInputBuffer, SchedulerBuffer], BaseSchedulerNode]])rg   r   rm   ry  r´   rx  r?   ztuple[int, list[int]])rg   r   rm   ry  r´   rx  r?   z�tuple[int, list[tuple[int, int]], dict[BaseSchedulerNode, SNodeMemory], dict[Union[FreeableInputBuffer, SchedulerBuffer], BaseSchedulerNode]])
rg   r   rm   ry  r‰   rz  r´   rx  r?   r   )rg   r   r?   r   )rg   r   r?   r@   )rg   r   r‰   rz  rm   ry  r?   r@   )rg   r   r‰   rz  r    r{  rh   rx  r´   rx  r?   z*tuple[int, dict[str, FreeableInputBuffer]])rg   r   r‰   rz  r    r{  rh   rx  r´   rx  rH  z,list[Callable[..., list[BaseSchedulerNode]]]r?   r   )rg   r   rm   ry  r    r{  rh   rx  r´   rx  r?   r@   )=Ú
__future__r   r_   rA   r  ÚloggingÚtypingr   r   r   r   r;   Útorch._environmentr   Útorch._utils_internalr	   Útorch.utils._ordered_setr
   Ú r   r‡   r   r   Úutilsr   r   Úvirtualizedr   Úcollections.abcr   Údependenciesr   ru   r   r   r   Ú	getLoggerr"   rB  r  r   r+   rD   rK   ro   rŠ   r’   r¥   r§   r¹   rÄ   rÆ   rÐ   rö   r  r#  r2  r5  r8  rL  rE  r    r(   r)   Ú<module>rˆ     sx  ðÝ "ã Û Û Û ß <Ó <ã Ý (Ý 0Ý /å ß -ß 9Ý ö Ý(å!ß=å !ð ×Ò˜hÓ'€	ð ×Ñ÷ð ó ðð ×Ñ÷
ð 
ó ð
ð( ×Ñ÷ð ó ðð ×Ñ÷
ð 
ó ð
ð.&Ø"ð.&à!ð.&ð $ô.&ðbUØ+ðUàôUðp.
Ø"ð.
à+ð.
ð 
ô.
ðb:
Ø"ð:
à4ð:
ð ,ð:
ð !?ð	:
ð
 
ô:
ð| ×Ñ÷ð ó ððV>Ø"ðV>à >ðV>ð #ðV>ðô	V>ðr#+Ø"ð#+à >ð#+ð #ð#+ð ô	#+ðL ×Ñ÷ð ó ðð
:Ø"ð:à >ð:ð #ð:ðô	:ðzLØ"ðLà >ðLð ,ðLð #ð	Lð
 ôLô^EôP'ôT+ð\&Ø"ð&à+ð&ð !?ð&ð 
ô	&ðR=Ø"ð=à+ð=ð 5ð=ð "ð	=ð
 #ð=ð 0ô=ðH 	ØØð=ðVØ"ðVà+ðVð 5ðVð "ð	Vð
 #ðVð :ðVð õVðrjØ"ðjà >ðjð 5ðjð "ð	jð
 #ðjð 
õjr(   