§
    Ÿ²Åjv¢ ã                   ó`  — 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
 d dlmZ d dlmZmZmZmZmZmZmZmZmZmZ d dlZd dlmZ d dlmZmZ d dlm Z  dd	l!m"Z"m#Z#m$Z$ dd
l%m&Z& erd dlm'Z' g d¢Z( ej)        e*¦  «        Z+ G d„ de¦  «        Z,e,j-        Z-e,j.        Z.e,j/        Z/e,j0        Z0e,j1        Z1e,j2        Z2e,j3        Z3e,j4        Z4e,j5        Z5e,j6        Z6e-Z7e.Z8e/Z9e6Z: ej;        d¦  «        Z< G d„ de¦  «        Z=	 dBdee>eee=                  f         dee>         de?fd„Z@ G d„ de¦  «        ZAdBdeejB                 dee?         fd„ZC	 dBdeejB                 dee?         dee>ej'        f         fd„ZD G d„ deA¦  «        ZE G d„ deE¦  «        ZF G d „ d!eE¦  «        ZG G d"„ d#eE¦  «        ZH	 dCd%eee=                  d&e>dee=         fd'„ZId%eee=                  dee=         fd(„ZJd%ee>ee=         f         d)ee>ge>f         d*e>dee>ee=         f         fd+„ZKd,ee>eee=                  f         d-e>d*e>d.e>fd/„ZL G d0„ d1eA¦  «        ZM G d2„ d3eM¦  «        ZN G d4„ d5eM¦  «        ZO	 	 dDd7„ZP G d8„ d9eM¦  «        ZQ G d:„ d;eM¦  «        ZR G d<„ d=eM¦  «        ZSd>e?fd?„ZTd)ee>ge>f         d*e>fd@„ZUdA„ ZVdS )Eé    N)ÚABCÚabstractmethod)ÚCounterÚdefaultdict)ÚEnum)
ÚAnyÚCallableÚDictÚListÚ
NamedTupleÚOptionalÚSetÚTupleÚTYPE_CHECKINGÚUnion)Ú
FSDPModuleÚUnshardHandle)Úrecord_functioné   )Úmerge_chunksÚsplit_args_kwargs_into_chunksÚTensorChunkSpec)Ú_PipelineStageBase)ÚWork)	Úget_schedule_classÚPipelineScheduleSingleÚPipelineScheduleMultiÚSchedule1F1BÚScheduleGPipeÚScheduleInterleaved1F1BÚScheduleLoopedBFSÚScheduleInterleavedZeroBubbleÚScheduleZBVZeroBubblec                   óR   — e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
Zd„ Zed„ ¦   «         ZdS )Ú_ComputationTyper   é   é   é   é   é   é   é   é	   é
   c                 ó  — t           j        dt           j        dt           j        dt           j        dt           j        dt           j        dt           j        dt           j        dt           j	        d	t           j
        d
i
}||          S )NÚFÚIÚWÚUNSHARDÚRESHARDÚSEND_FÚRECV_FÚSEND_BÚRECV_BÚB)r%   ÚFORWARDÚBACKWARD_INPUTÚBACKWARD_WEIGHTr3   r4   r5   r6   r7   r8   ÚFULL_BACKWARD)ÚselfÚstr_maps     úWC:\Projects\Historical\venv\Lib\site-packages\torch/distributed/pipelining/schedules.pyÚ__str__z_ComputationType.__str__A   se   € åÔ$ cÝÔ+¨SÝÔ,¨cÝÔ$ iÝÔ$ iÝÔ# XÝÔ# XÝÔ# XÝÔ# XÝÔ*¨Cð
ˆð �tŒ}Ðó    c                 óŽ  — | dk    rt           j        S | dk    rt           j        S | dk    rt           j        S | dk    rt           j        S | dk    rt           j        S | dk    rt           j        S | dk    rt           j        S | dk    rt           j        S | d	k    rt           j	        S | d
k    rt           j
        S t          d| › �¦  «        ‚)Nr0   r1   r2   r3   r4   r5   r6   r7   r8   r9   zInvalid computation type )r%   r:   r;   r<   r3   r4   r5   r6   r7   r8   r=   ÚRuntimeError)Úactions    r@   Úfrom_strz_ComputationType.from_strP   sÙ   € à�SŠ=ˆ=Ý#Ô+Ð+Ø�sŠ]ˆ]Ý#Ô2Ð2Ø�sŠ]ˆ]Ý#Ô3Ð3Ø�yÒ Ð Ý#Ô+Ð+Ø�yÒ Ð Ý#Ô+Ð+Ø�xÒÐÝ#Ô*Ð*Ø�xÒÐÝ#Ô*Ð*Ø�xÒÐÝ#Ô*Ð*Ø�xÒÐÝ#Ô*Ð*Ø�sŠ]ˆ]Ý#Ô1Ð1åÐC¸6ÐCÐCÑDÔDÐDrB   N)Ú__name__Ú
__module__Ú__qualname__r:   r;   r<   r3   r4   r5   r6   r7   r8   r=   rA   ÚstaticmethodrF   © rB   r@   r%   r%   4   su   € € € € € à€GØ€NØ€OØ€GØ€GØ€FØ€FØ€FØ€FØ€Mðð ð ð ðEð Eñ „\ðEð Eð ErB   r%   z?(\d+)(F|I|B|W|UNSHARD|RESHARD|SEND_F|RECV_F|SEND_B|RECV_B)(\d*)c                   ó`   — e Zd ZU eed<   eed<   dZee         ed<   d„ Ze	de
fd„¦   «         ZdS )Ú_ActionÚstage_indexÚcomputation_typeNÚmicrobatch_indexc                 ó˜   — t          | j        ¦  «        }|t          | j        ¦  «        z  }| j        �|t          | j        ¦  «        z  }|S ©N)ÚstrrN   rO   rP   )r>   Úreprs     r@   Ú__repr__z_Action.__repr__†   sJ   € Ý�4Ô#Ñ$Ô$ˆØ•�DÔ)Ñ*Ô*Ñ*ˆØÔ Ð,Ø•C˜Ô-Ñ.Ô.Ñ.ˆDØˆrB   Úaction_stringc                 óp  — |                       ¦   «         } t                               | ¦  «        x}rl|                     ¦   «         \  }}}t	          t          |¦  «        t                               |¦  «        t          |¦  «        rt          |¦  «        nd¦  «        S | dk    rdS t          d| › d�¦  «        ‚)zž
        Reverse of __repr__

        String should be formatted as [stage][action type][(microbatch)]
            e.g. `2F0`, `1UNSHARD`, `3SEND_F1`
        NÚ zInvalid action string: zD, should be formatted as [stage][action type][(microbatch)] e.g. 2F0)
ÚstripÚ_action_regexÚmatchÚgroupsrM   Úintr%   rF   ÚlenrD   )rV   r[   rN   rO   rP   s        r@   rF   z_Action.from_str�   sÆ   € ð &×+Ò+Ñ-Ô-ˆÝ!×'Ò'¨Ñ6Ô6Ð6ˆ5ð 	Ø>C¿lºl¹n¼nÑ;ˆKÐ)Ð+;ÝÝ�KÑ Ô Ý ×)Ò)Ð*:Ñ;Ô;Ý),Ð-=Ñ)>Ô)>ÐH•Ð$Ñ%Ô%Ð%ÀDñô ð ð
 ˜bÒ Ð Ø�4ÝØy mÐyÐyÐyñ
ô 
ð 	
rB   )rG   rH   rI   r]   Ú__annotations__r%   rP   r   rU   rJ   rS   rF   rK   rB   r@   rM   rM   �   sy   € € € € € € ØÐÐÑØ&Ð&Ð&Ñ&Ø&*Ð�h˜s”mÐ*Ð*Ñ*ðð ð ð ð
 ð 
ð 
ð 
ñ „\ð
ð 
ð 
rB   rM   Úpipeline_orderÚerror_step_numberÚreturnc                 óD  ‡ ‡‡‡— t          j        ‰ ¦  «        Š ‰ D ]@}t          t          ‰ |         ¦  «        ¦  «        D ]}‰ |         |         €d‰ |         |<   ŒŒAt	          d„ ‰                      ¦   «         D ¦   «         ¦  «        Šˆfd„t          ‰¦  «        D ¦   «         }ˆˆ fd„t          ‰ ¦  «        D ¦   «         }t          t          j	        |ddiŽ¦  «        }t          ‰ ¦  «        }d„ t          |¦  «        D ¦   «         }d„ t          |g|¢R Ž D ¦   «         Šd	t          |d
         ¦  «        dz   z  d	                     ˆfd„t          |¦  «        D ¦   «         ¦  «        z   }	ˆˆfd„t          ||¦  «        D ¦   «         }
|	dz   d                     |
¦  «        z   dz   }|S )zü
    Formats the pipeline order in a timestep (row) x rank (column) grid of actions
    and returns the formatted string.

    If `error_step_number` is passed in, an additional label will be added to signify which step
    that it is erroring on.
    NrX   c              3   ó4   K  — | ]}t          |¦  «        V — Œd S rR   )r^   )Ú.0Úactionss     r@   ú	<genexpr>z)_format_pipeline_order.<locals>.<genexpr>»   s(   è è € ÐHÐH W•C˜‘L”LÐHÐHÐHÐHÐHÐHrB   c                 ó”   •— g | ]D}d t          |¦  «                             t          t          ‰dz
  ¦  «        ¦  «        ¦  «        z   ‘ŒES )zStep r   )rS   Úzfillr^   )re   ÚiÚ	num_stepss     €r@   ú
<listcomp>z*_format_pipeline_order.<locals>.<listcomp>¼   sQ   ø€ ð ð ð Ø<=ˆ•#�a‘&”&—,’,�s¥3 y°1¡}Ñ#5Ô#5Ñ6Ô6Ñ7Ô7Ñ7ðð ð rB   c                 óD   •— g | ]}‰                      |d g‰z  ¦  «        ‘ŒS )rX   )Úget)re   Úkeyrk   r`   s     €€r@   rl   z*_format_pipeline_order.<locals>.<listcomp>À   s=   ø€ ð ð ð Ø69ˆ×Ò˜3   yÑ 0Ñ1Ô1ðð ð rB   Ú	fillvaluec                 ó2   — g | ]}d t          |¦  «        z   ‘ŒS )zRank ©rS   )re   rj   s     r@   rl   z*_format_pipeline_order.<locals>.<listcomp>Ç   s#   € Ð>Ð>Ð>¨�7�S ™VœVÑ#Ð>Ð>Ð>rB   c                 ó@   — g | ]}t          d „ |D ¦   «         ¦  «        ‘ŒS )c              3   óV   K  — | ]$}|�t          t          |¦  «        ¦  «        ndV — Œ%d S )Nr   )r^   rS   )re   Úitems     r@   rg   z4_format_pipeline_order.<locals>.<listcomp>.<genexpr>Ê   s7   è è € ÐFÐF¸$˜dÐ.�C•�D‘	”	‰NŒNˆN°AÐFÐFÐFÐFÐFÐFrB   )Úmax)re   Úcols     r@   rl   z*_format_pipeline_order.<locals>.<listcomp>É   s?   € ð ð ð àõ 	ÐFÐFÀ#ÐFÑFÔFÑFÔFðð ð rB   ú r   r&   c              3   ó8   •K  — | ]\  }}|d ‰|         › �›V — ŒdS ©ú<NrK   )re   rj   ÚlabelÚmax_lengthss      €r@   rg   z)_format_pipeline_order.<locals>.<genexpr>Î   sJ   øè è € ð <ð <Ù)1¨¨Eˆ5Ð$�;˜q”>Ð$Ð$Ð$ð<ð <ð <ð <ð <ð <rB   c           	      óâ   •— g | ]k\  }}|› d �d                      ˆfd„t          |¦  «        D ¦   «         ¦  «        z   ‰�-t          |                     ¦   «         d         ¦  «        ‰k    rdndz   ‘ŒlS )z: rx   c              3   óR   •K  — | ]!\  }}t          |¦  «        d ‰|         › �›V — Œ"dS rz   rr   )re   rj   ru   r}   s      €r@   rg   z4_format_pipeline_order.<locals>.<listcomp>.<genexpr>Ô   s?   øè è € ÐRÐR¹¸¸4•c˜$‘i”iÐ3 +¨a¤.Ð3Ð3Ð3ÐRÐRÐRÐRÐRÐRrB   Nr   z <-- ERROR HERErX   )ÚjoinÚ	enumerater]   Úsplit)re   r|   Úrowra   r}   s      €€r@   rl   z*_format_pipeline_order.<locals>.<listcomp>Ò   s    ø€ ð 
ð 
ð 
ñ ˆE�3ð ˆˆˆØ
�(Š(ÐRÐRÐRÐRÅ9ÈSÁ>Ä>ÐRÑRÔRÑ
RÔ
Rñ	Sð !Ð,Ý�E—K’K‘M”M !Ô$Ñ%Ô%Ð):Ò:Ð:ð Ðð ñ	
ð
ð 
ð 
rB   ú
)ÚcopyÚdeepcopyÚranger^   rv   ÚvaluesÚsortedÚlistÚ	itertoolsÚzip_longestÚzipr€   r�   )r`   ra   Úrankrj   Ústep_labelsÚrank_actionsÚtransposed_actionsÚ	num_ranksÚrank_labelsÚ
header_rowÚformatted_rowsÚformatted_tabler}   rk   s   ``          @@r@   Ú_format_pipeline_orderr—   ¤   s9  øøøø€ õ ”] >Ñ2Ô2€Nð ð -ð -ˆÝ•s˜>¨$Ô/Ñ0Ô0Ñ1Ô1ð 	-ð 	-ˆAØ˜dÔ# AÔ&Ð.à*,�˜tÔ$ QÑ'øð	-õ ÐHÐH°×0EÒ0EÑ0GÔ0GÐHÑHÔHÑHÔH€Iðð ð ð ÝAFÀyÑAQÔAQðñ ô €Kðð ð ð ð Ý=CÀNÑ=SÔ=Sðñ ô €Lõ �iÔ3°\ÐPÈRÐPÐPÑQÔQÐå�NÑ#Ô#€IØ>Ð>­U°9Ñ-=Ô-=Ð>Ñ>Ô>€Kðð å�{Ð8Ð%7Ð8Ð8Ð8ðñ ô €Kð
 �˜K¨œNÑ+Ô+¨aÑ/Ñ0°3·8²8ð <ð <ð <ð <Ý5>¸{Ñ5KÔ5Kð<ñ <ô <ñ 4ô 4ñ €Jð
ð 
ð 
ð 
ð 
õ ˜kÐ+=Ñ>Ô>ð
ñ 
ô 
€Nð ! 4Ñ'¨$¯)ª)°NÑ*CÔ*CÑCÀdÑJ€OØÐrB   c                   ó"  — e Zd Z	 	 	 	 ddedeedej        f                  deee	df                  dee
ee	f                  deee
eef         ee         f                  f
d„Zd	„ Zd
„ Zd„ Ze	 	 	 	 ddee         dee         dee         dee         fd„¦   «         Zedddœdee         fd„¦   «         Z	 	 	 	 ddee         dee         dee         dee         fd„Zd„ Z	 ddeedf         dee
eef                  fd„Zdee         defd„ZdS )Ú_PipelineScheduleNÚn_microbatchesÚloss_fn.Úargs_chunk_specÚkwargs_chunk_specÚoutput_merge_specc                 óÂ   — || _         || _        || _        || _        || _        	 | j        d u| _        g | _        t                               d| j	        j
        ¦  «         d S )NzUsing %s)Ú_n_microbatchesÚ_loss_fnÚ_args_chunk_specÚ_kwargs_chunk_specÚ_output_merge_specÚ_has_backwardÚ_internal_lossesÚloggerÚinfoÚ	__class__rG   )r>   rš   r›   rœ   r�   rž   s         r@   Ú__init__z_PipelineSchedule.__init__ã   sj   € ð  .ˆÔØˆŒà /ˆÔà"3ˆÔØ"3ˆÔð	ð "œ]°$Ð6ˆÔð 57ˆÔÝ�Š�J ¤Ô 7Ñ8Ô8Ð8Ð8Ð8rB   c                 ó–   — |j         r?| j        r:|                      |||         ¦  «        }| j                             |¦  «         d S d S d S rR   )Úis_lastr¥   Ú_compute_lossr¦   Úappend)r>   ÚstageÚoutputÚ
target_mbsÚmb_indexÚlosss         r@   Ú_maybe_compute_lossz%_PipelineSchedule._maybe_compute_loss   sa   € ØŒ=ð 	/˜TÔ/ð 	/Ø×%Ò% f¨j¸Ô.BÑCÔCˆDØÔ!×(Ò(¨Ñ.Ô.Ð.Ð.Ð.ð	/ð 	/ð 	/ð 	/rB   c                 óì   — d|cxk    ot          | j        ¦  «        k     nc }|j        r| j        r|r| j        |         S t          | j        ¦  «        dk    r|st	          d|› d| j        › �¦  «        ‚d S )Nr   zLoss for microbatch z6 is not available. Available losses for microbatches: )r^   r¦   r¬   r¥   rD   )r>   r¯   r²   Úvalid_indexs       r@   Ú_maybe_get_lossz!_PipelineSchedule._maybe_get_loss  s±   € Ø˜8Ð@Ð@Ò@Ð@¥c¨$Ô*?Ñ&@Ô&@Ò@Ð@Ð@Ð@ˆØŒ=ð 	˜TÔ/ð 	°Kð 	ØÔ(¨Ô2Ð2Ý�Ô&Ñ'Ô'¨1Ò,Ð,°[Ð,ÝðN xð Nð NØ6:Ô6KðNð Nñô ð ð
 �4rB   c                 ó�  — t          |t          ¦  «        s|g}t          d„ |D ¦   «         ¦  «        }|ry|�wt          | j        ¦  «        | j        k    r,t          d| j        › dt          | j        ¦  «        › �¦  «        ‚|                     ¦   «          |                     | j        ¦  «         | j                             ¦   «          dS )zB
        Update the losses to those in the internal state
        c              3   ó$   K  — | ]}|j         V — Œd S rR   ©r¬   ©re   r¯   s     r@   rg   z3_PipelineSchedule._update_losses.<locals>.<genexpr>  s$   è è € Ð!DÐ!D°E %¤-Ð!DÐ!DÐ!DÐ!DÐ!DÐ!DrB   Nú
Expecting z losses but got )	Ú
isinstancerŠ   Úanyr^   r¦   r    rD   ÚclearÚextend)r>   ÚstagesÚlossesÚcontains_last_stages       r@   Ú_update_lossesz _PipelineSchedule._update_losses  sÔ   € õ
 ˜&¥$Ñ'Ô'ð 	Ø�XˆFÝ!Ð!DÐ!D¸VÐ!DÑ!DÔ!DÑDÔDÐð ð 		1 6Ð#5Ý�4Ô(Ñ)Ô)¨TÔ-AÒAÐAÝ"Øc Ô!5ÐcÐcÅsÈ4ÔK`ÑGaÔGaÐcÐcñô ð ð
 �LŠL‰NŒNˆNà�MŠM˜$Ô/Ñ0Ô0Ð0àÔ×#Ò#Ñ%Ô%Ð%Ð%Ð%rB   Úarg_mbsÚ	kwarg_mbsr±   rÂ   c                 ó   — t           ‚)zø
        Run one iteration of the pipeline schedule with list of microbatches.
        Will go through all the microbatches according to the schedule
        implementation.

        Args:
            microbatches: list of microbatch args.
        ©ÚNotImplementedError)r>   rÅ   rÆ   r±   rÂ   s        r@   Ú_step_microbatchesz$_PipelineSchedule._step_microbatches(  s
   € õ  "Ð!rB   ©ÚtargetrÂ   c                ó   — t           ‚)áê  
        Run one iteration of the pipeline schedule with *whole-batch* input.
        Will chunk the input into microbatches automatically, and go through the
        microbatches according to the schedule implementation.

        args: positional arguments to the model (as in non-pipeline case).
        kwargs: keyword arguments to the model (as in non-pipeline case).
        target: target for the loss function.
        losses: a list to store the losses for each microbatch.
        rÈ   )r>   rÌ   rÂ   ÚargsÚkwargss        r@   Ústepz_PipelineSchedule.step:  s
   € õ "Ð!rB   c                 ó  ‡ — dt           fˆ fd„}|� ||d¦  «         ndg‰ j        z  }|� ||d¦  «         ni g‰ j        z  }|� ||d¦  «         |�4t          |t          ¦  «        st	          dt          |¦  «        › �¦  «        ‚||fS )	z*
        Pre-process/check inputs
        Únamec           
      óø   •— t          | t          ¦  «        s!t          |› dt          | ¦  «        › �¦  «        ‚t	          | ¦  «        ‰j        k    r*t          d‰j        › d|› dt	          | ¦  «        › �¦  «        ‚d S )Nz must be a list but got a r¼   rx   z	 but got )r½   rŠ   Ú	TypeErrorÚtyper^   r    Ú
ValueError)ÚmbsrÓ   r>   s     €r@   Úcheck_type_and_lenz;_PipelineSchedule._check_inputs.<locals>.check_type_and_lenS  sŠ   ø€ Ý˜c¥4Ñ(Ô(ð PÝ 4Ð NÐ NÅ4ÈÁ9Ä9Ð NÐ NÑOÔOÐOÝ�3‰xŒx˜4Ô/Ò/Ð/Ý ØQ Ô!5ÐQÐQ¸ÐQÐQÅsÈ3ÁxÄxÐQÐQñô ð ð 0Ð/rB   NrÅ   rK   rÆ   r±   z losses must be a list but got a )rS   r    r½   rŠ   rÕ   rÖ   )r>   rÅ   rÆ   r±   rÂ   rÙ   s   `     r@   Ú_check_inputsz_PipelineSchedule._check_inputsH  sÚ   ø€ ð	­#ð 	ð 	ð 	ð 	ð 	ð 	ð ÐØÐ˜w¨	Ñ2Ô2Ð2Ð2à�d˜TÔ1Ñ1ˆGàÐ ØÐ˜y¨+Ñ6Ô6Ð6Ð6à˜˜tÔ3Ñ3ˆIàÐ!ØÐ˜z¨<Ñ8Ô8Ð8àÐÝ˜f¥dÑ+Ô+ð SÝÐ QÅ4ÈÁ<Ä<Ð QÐ QÑRÔRÐRà˜	Ð!Ð!rB   c                 ó.   — |                       ||¦  «        S rR   )r¡   )r>   r°   rÌ   s      r@   r­   z_PipelineSchedule._compute_lossn  s   € Ø�}Š}˜V VÑ,Ô,Ð,rB   rÏ   rÐ   c                 óˆ   — |s|r)t          ||| j        | j        | j        ¦  «        \  }}||fS dg| j        z  i g| j        z  fS )zj
        Splits a full-batch input into chunks (i.e. microbatches) and returns
        the chunks
        rK   )r   r    r¢   r£   )r>   rÏ   rÐ   Ú
args_splitÚkwargs_splits        r@   Ú_split_inputsz_PipelineSchedule._split_inputsq  so   € ð ð 	L�6ð 	LÝ'DØØØÔ$ØÔ%ØÔ'ñ(ô (Ñ$ˆJ˜ð ˜|Ð+Ð+ð �4˜$Ô.Ñ.°°°tÔ7KÑ0KÐKÐKrB   Úoutput_chunksrb   c                 ó,   — t          || j        ¦  «        S )z£
        Merge output chunks back to a batch state.
        If output_merge_spec is None, the utility will merge output chunks by dimension 0 (batch dim).
        )r   r¤   )r>   rà   s     r@   Ú_merge_outputsz _PipelineSchedule._merge_outputsˆ  s   € õ
 ØØÔ#ñ
ô 
ð 	
rB   ©NNNNrR   )rG   rH   rI   r]   r   r	   ÚtorchÚTensorr   r   r
   rS   r   r   rª   r´   r·   rÄ   r   r   rÊ   rÑ   rÚ   r­   rß   râ   rK   rB   r@   r™   r™   â   sd  € € € € € ð :>ØAEØBFØIMð9ð 9àð9ð ˜( 3¨¬Ð#4Ô5Ô6ð9ð " %¨¸Ð(<Ô"=Ô>ð	9ð
 $ D¨¨oÐ)=Ô$>Ô?ð9ð $ E¨$¨s°C¨x¬.¸%À¼*Ð*DÔ$EÔFð9ð 9ð 9ð 9ð:/ð /ð /ð

ð 
ð 
ð&ð &ð &ð. ð #'Ø$(Ø%)Ø!%ð"ð "à˜$”ð"ð ˜D”>ð"ð ˜T”Nð	"ð
 ˜”ð"ð "ð "ñ „^ð"ð" Ø!%Àð "ð "ð "¨x¸¬~ð "ð "ð "ñ „^ð"ð #'Ø$(Ø%)Ø!%ð$"ð $"à˜$”ð$"ð ˜D”>ð$"ð ˜T”Nð	$"ð
 ˜”ð$"ð $"ð $"ð $"ðL-ð -ð -ð ,0ðLð Là�C˜�HŒoðLð ˜˜c 3˜hœÔ(ðLð Lð Lð Lð.
¨D°¬Ið 
¸#ð 
ð 
ð 
ð 
ð 
ð 
rB   r™   Úp2p_opsÚdescc                 óÂ   — t          | ¦  «        dk    rdS |r|› d�nd}t                               d|| ¦  «         t          j        | ¦  «                             ¦   «         S )zt
    Simple wrapper over batch_isend_irecv from torch.distributed, which just adds a descriptive logger on top.
    r   Nz, rX   zbatch_p2p %s%s)r^   r§   ÚdebugÚdistÚbatch_isend_irecvÚpop)ræ   rç   Údesc_strs      r@   Ú
_batch_p2prî   “  sb   € õ ˆ7�|„|�qÒÐØˆtØ"Ð*�$ˆ{ˆ{ˆ{ˆ{¨€HÝ
‡L‚LÐ! 8¨WÑ5Ô5Ð5ÝÔ! 'Ñ*Ô*×.Ò.Ñ0Ô0Ð0rB   c                 ó  — t          t          ¦  «        }i }t          | ¦  «        dk    r|S | D ]"}||j                                      |¦  «         Œ#t          |                     ¦   «         ¦  «        D ]\  }}t          ||¬¦  «        ||<   Œ|S )zÊ
    Sorts the list of P2P ops by the peer rank, and then calls
    batch_isend_irecv. Return a dictionary of works by peer rank. This function
    helps us avoid hangs in case of skip connections.
    r   ©rç   )r   rŠ   r^   Úpeerr®   r‰   Úitemsrî   )ræ   rç   Úops_by_peerÚwork_by_peerÚoprñ   Úopss          r@   Ú_sorted_batch_p2pr÷   ž  s¥   € õ 0;½4Ñ/@Ô/@€KØ)+€LÝ
ˆ7�|„|�qÒÐØÐð ð (ð (ˆØ�B”GÔ×#Ò# BÑ'Ô'Ð'Ð'õ ˜K×-Ò-Ñ/Ô/Ñ0Ô0ð 8ð 8‰	ˆˆcÝ'¨°$Ð7Ñ7Ô7ˆ�TÑÐàÐrB   c                   óè   ‡ — e Zd ZdZ	 	 	 	 ddededee         deee	df                  dee
ee	f                  d	eee
eef         ee         f                  fˆ fd
„Zd„ Zdddœdee         fd„Zˆ xZS )r   z�
    Base class for single-stage schedules.
    Implements the `step` method.
    Derived classes should implement `_step_microbatches`.
    Nr¯   rš   r›   rœ   .r�   rž   c                 óª   •— t          ¦   «                              |||||¬¦  «         || _        |j        | _        | j        | j        _        d| _        d S )N©rš   r›   rœ   r�   rž   F)Úsuperrª   Ú_stageÚ
num_stagesÚ_num_stagesr¥   Úhas_backwardÚ_stage_initialized)r>   r¯   rš   r›   rœ   r�   rž   r©   s          €r@   rª   zPipelineScheduleSingle.__init__À  sd   ø€ õ 	‰Œ×ÒØ)ØØ+Ø/Ø/ð 	ñ 	
ô 	
ð 	
ð ˆŒØ Ô+ˆÔà#'Ô#5ˆŒÔ Ø"'ˆÔÐÐrB   c                 ó¢   — | j                              | j        ||¦  «         | j        r| j                              | j        ¦  «         d| _        d S ©NT)rü   Ú_prepare_forward_infrar    r¥   Ú_prepare_backward_infrar   )r>   rÏ   rÐ   s      r@   Ú_initialize_stagez(PipelineScheduleSingle._initialize_stageØ  sR   € ØŒ×*Ò*¨4Ô+?ÀÀvÑNÔNÐNØÔð 	FØŒK×/Ò/°Ô0DÑEÔEÐEØ"&ˆÔÐÐrB   rË   rÂ   c                óH  — | j                              ¦   «          |                      ||¦  «        \  }}|�(t          t	          j        || j        ¦  «        ¦  «        }nd}|                      ||||¦  «         | j         j        r|  	                    | j         j
        ¦  «        S dS ©rÎ   N)rü   Úclear_runtime_statesrß   rŠ   rä   Útensor_splitr    rÊ   r¬   râ   rà   )r>   rÌ   rÂ   rÏ   rÐ   rÝ   rÞ   Útargets_splits           r@   rÑ   zPipelineScheduleSingle.stepÞ  s©   € ð 	Œ×(Ò(Ñ*Ô*Ð*ð $(×#5Ò#5°d¸FÑ#CÔ#CÑ ˆ
�Lð ÐÝ ¥Ô!3°F¸DÔ<PÑ!QÔ!QÑRÔRˆMˆMà ˆMð 	×Ò 
¨L¸-ÈÑPÔPÐPð Œ;Ôð 	Ø×&Ò& t¤{Ô'@ÑAÔAÐAà�4rB   rã   )rG   rH   rI   Ú__doc__r   r]   r   r	   r   r   r
   rS   r   r   rª   r  r   rÑ   Ú__classcell__©r©   s   @r@   r   r   ¹  s  ø€ € € € € ðð ð '+ØAEØBFØIMð(ð (à!ð(ð ð(ð ˜(Ô#ð	(ð
 " %¨¸Ð(<Ô"=Ô>ð(ð $ D¨¨oÐ)=Ô$>Ô?ð(ð $ E¨$¨s°C¨x¬.¸%À¼*Ð*DÔ$EÔFð(ð (ð (ð (ð (ð (ð0'ð 'ð 'ð "&Àð ð ð ¨x¸¬~ð ð ð ð ð ð ð ð rB   r   c            
       ód   — e Zd ZdZ	 	 	 	 ddee         dee         dee         dee         fd„ZdS )	Ú_ScheduleForwardOnlyzo
    The forward-only schedule.
    Will go through all the microbatches and perform only the forward pass
    NrÅ   rÆ   r±   rÂ   c                 ó\  — |€|�t          d¦  «        ‚|                      ||||¦  «        \  }}| j        s"|                      |d         |d         ¦  «         g }t	          | j        ¦  «        D �]#}t          d|› �¦  «        5  | j                             |¦  «        }t          |d¬¦  «        }| 
                    ¦   «         D ]}	|	                     ¦   «          Œ| j                             |||         ||         ¦  «         | j                             |¦  «        }t          |d¬¦  «        }|                     | 
                    ¦   «         ¦  «         ddd¦  «         n# 1 swxY w Y   t                               d| j        j        |¦  «         �Œ%|D ]}	|	                     ¦   «          ŒdS )	z<
        Run one iteration of the pipeline schedule
        Nz7Forward-only schedule does not support loss computationr   úForward Úfwd_recvrð   Úfwd_sendú[%s] Forwarded microbatch %s)rD   rÚ   r   r  r‡   r    r   rü   Úget_fwd_recv_opsr÷   rˆ   ÚwaitÚforward_one_chunkÚget_fwd_send_opsrÀ   r§   ré   rN   )
r>   rÅ   rÆ   r±   rÂ   Úfwd_sends_to_waitrj   rö   ÚworksÚworks
             r@   rÊ   z'_ScheduleForwardOnly._step_microbatches  sû  € ð Ð! VÐ%7ÝØIñô ð ð "×/Ò/°¸ÀJÐPVÑWÔWÑˆ�ØÔ&ð 	=Ø×"Ò" 7¨1¤:¨y¸¬|Ñ<Ô<Ð<ð .0Ðõ �tÔ+Ñ,Ô,ð 	Uñ 	UˆAÝ  ¨A  Ñ0Ô0ð 
9ð 
9Ø”k×2Ò2°1Ñ5Ô5�Ý)¨#°JÐ?Ñ?Ô?�Ø!ŸLšL™NœNð  ð  �DØ—I’I‘K”K�K�Kà”×-Ò-¨a°¸´¸YÀq¼\ÑJÔJÐJà”k×2Ò2°1Ñ5Ô5�Ý)¨#°JÐ?Ñ?Ô?�Ø!×(Ò(¨¯ª©¬Ñ8Ô8Ð8ð
9ð 
9ð 
9ñ 
9ô 
9ð 
9ð 
9ð 
9ð 
9ð 
9ð 
9øøøð 
9ð 
9ð 
9ð 
9õ �LŠLÐ7¸¼Ô9PÐRSÑTÔTÐTÑTð
 &ð 	ð 	ˆDØ�IŠI‰KŒKˆKˆKð	ð 	s   ÂCE Å E$	Å'E$	rã   ©rG   rH   rI   r  r   r   rÊ   rK   rB   r@   r  r     s{   € € € € € ðð ð #'Ø$(Ø%)Ø!%ð*ð *à˜$”ð*ð ˜D”>ð*ð ˜T”Nð	*ð
 ˜”ð*ð *ð *ð *ð *ð *rB   r  c            
       ód   — e Zd ZdZ	 	 	 	 ddee         dee         dee         dee         fd„ZdS )	r   z^
    The GPipe schedule.
    Will go through all the microbatches in a fill-drain manner.
    NrÅ   rÆ   r±   rÂ   c           	      ó˜  — |                       ||||¦  «        \  }}| j        s"|                      |d         |d         ¦  «         g }t          | j        ¦  «        D �]@}t          d|› �¦  «        5  | j                             |¦  «        }t          |d¬¦  «        }| 	                    ¦   «         D ]}	|	 
                    ¦   «          Œ| j                             |||         ||         ¦  «        }
| j                             |¦  «        }t          |d¬¦  «        }|                     | 	                    ¦   «         ¦  «         ddd¦  «         n# 1 swxY w Y   t                               d| j        j        |¦  «         |                      | j        |
||¦  «         �ŒB|D ]}	|	 
                    ¦   «          Œ| j        sdS g }t          | j        ¦  «        D �]?}t          d|› �¦  «        5  | j                             |¦  «        }t          |d	¬¦  «        }| 	                    ¦   «         D ]}	|	 
                    ¦   «          Œ|                      | j        |¦  «        }| j                             |||| j        d
z
  k    ¬¦  «         | j                             |¦  «        }t          |d¬¦  «        }|                     | 	                    ¦   «         ¦  «         ddd¦  «         n# 1 swxY w Y   t                               d| j        j        |¦  «         �ŒA|                      | j        |¦  «         |D ]}	|	 
                    ¦   «          ŒdS )zç
        Run one iteration of the pipeline schedule with list of microbatches.
        Will go through all the microbatches according to the GPipe schedule.

        Args:
            microbatches: list of microbatch args.
        r   r  r  rð   r  Nr  z	Backward Úbwd_recvr   ©r³   Úlast_backwardÚbwd_sendz[%s] Backwarded microbatch %s)rÚ   r   r  r‡   r    r   rü   r  r÷   rˆ   r  r  r  rÀ   r§   ré   rN   r´   r¥   Úget_bwd_recv_opsr·   Úbackward_one_chunkÚget_bwd_send_opsrÄ   )r>   rÅ   rÆ   r±   rÂ   r  rj   rö   r  r  r°   Úbwd_sends_to_waitr³   s                r@   rÊ   z ScheduleGPipe._step_microbatches9  sÌ  € ð "×/Ò/°¸ÀJÐPVÑWÔWÑˆ�àÔ&ð 	=Ø×"Ò" 7¨1¤:¨y¸¬|Ñ<Ô<Ð<ð .0Ðõ �tÔ+Ñ,Ô,ð 	Iñ 	IˆAÝ  ¨A  Ñ0Ô0ð 
9ð 
9Ø”k×2Ò2°1Ñ5Ô5�Ý)¨#°JÐ?Ñ?Ô?�Ø!ŸLšL™NœNð  ð  �DØ—I’I‘K”K�K�Kàœ×6Ò6°q¸'À!¼*ÀiÐPQÄlÑSÔS�à”k×2Ò2°1Ñ5Ô5�Ý)¨#°JÐ?Ñ?Ô?�Ø!×(Ò(¨¯ª©¬Ñ8Ô8Ð8ð
9ð 
9ð 
9ñ 
9ô 
9ð 
9ð 
9ð 
9ð 
9ð 
9ð 
9øøøð 
9ð 
9ð 
9ð 
9õ �LŠLÐ7¸¼Ô9PÐRSÑTÔTÐTà×$Ò$ T¤[°&¸*ÀaÑHÔHÐHÑHð
 &ð 	ð 	ˆDØ�IŠI‰KŒKˆKˆKð Ô!ð 	ØˆFð .0ÐÝ�tÔ+Ñ,Ô,ð 	Vñ 	VˆAÝ  ¨Q  Ñ1Ô1ð 9ð 9Ø”k×2Ò2°1Ñ5Ô5�Ý)¨#°JÐ?Ñ?Ô?�Ø!ŸLšL™NœNð  ð  �DØ—I’I‘K”K�K�Kà×+Ò+¨D¬K¸Ñ;Ô;�Ø”×.Ò.Ø˜D°°TÔ5IÈAÑ5MÒ0Mð /ñ ô ð ð ”k×2Ò2°1Ñ5Ô5�Ý)¨#°JÐ?Ñ?Ô?�Ø!×(Ò(¨¯ª©¬Ñ8Ô8Ð8ð9ð 9ð 9ñ 9ô 9ð 9ð 9ð 9ð 9ð 9ð 9øøøð 9ð 9ð 9ð 9õ �LŠLÐ8¸$¼+Ô:QÐSTÑUÔUÐUÑUð 	×Ò˜DœK¨Ñ0Ô0Ð0ð &ð 	ð 	ˆDØ�IŠI‰KŒKˆKˆKð	ð 	s&   Á0CEÅE	ÅE	Ç*C-K#Ë#K'	Ë*K'	rã   r  rK   rB   r@   r   r   3  s†   € € € € € ðð ð #'Ø$(Ø%)Ø!%ðLð Là˜$”ðLð ˜D”>ðLð ˜T”Nð	Lð
 ˜”ðLð Lð Lð Lð Lð LrB   r   c            
       ód   — e Zd ZdZ	 	 	 	 ddee         dee         dee         dee         fd„ZdS )	r   zo
    The 1F1B schedule.
    Will perform one forward and one backward on the microbatches in steady state.
    NrÅ   rÆ   r±   rÂ   c                 ó¼  — |                       ||||¦  «        \  }}| j        s"|                      |d         |d         ¦  «         t          | j        | j        | j        j        z
  ¦  «        }d}d}d}g }	t          |¦  «        D ]×}
| j         	                    |¦  «        }t          |d¬¦  «        x}r|                     ¦   «          | j                             |||         ||         ¦  «        }|r|                     ¦   «          | j                             |¦  «        }	||dz
  k    rt          |	d¬¦  «        }|                      | j        |||¦  «         |dz  }ŒØ	 | j                             |¦  «        }t          |	|z   d¬¦  «        x}r|                     ¦   «          |                      | j        |¦  «        }| j                             |||| j        dz
  k    ¬	¦  «         | j                             |¦  «        }|dz  }|| j        k    rnª| j         	                    |¦  «        }t          ||z   d
¬¦  «        x}r|                     ¦   «          | j                             |||         ||         ¦  «        }|                      | j        |||¦  «         | j                             |¦  «        }	|dz  }�Œ]t          |d¬¦  «        }|| j        k     rÖ| j                             |¦  «        }t          |d¬¦  «        x}r|                     ¦   «          |                      | j        |¦  «        }| j                             |||| j        dz
  k    ¬	¦  «         |r|                     ¦   «          | j                             |¦  «        }t          |d¬¦  «        }|dz  }|| j        k     °Ö|r|                     ¦   «          |                      | j        |¦  «         dS )zæ
        Run one iteration of the pipeline schedule with list of microbatches.
        Will go through all the microbatches according to the 1F1B schedule.

        Args:
            microbatches: list of microbatch args.
        r   Nr  rð   r   r  TÚfwd_send_bwd_recvr   Úbwd_send_fwd_recvr"  r  )rÚ   r   r  Úminr    rþ   rü   rN   r‡   r  rî   r  r  r  r´   r#  r·   r$  r%  rÄ   )r>   rÅ   rÆ   r±   rÂ   Úwarmup_chunksÚfwd_mb_indexÚbwd_mb_indexÚ	send_workÚ	fwd_sendsÚ_Ú	fwd_recvsÚ	recv_workr°   Ú	bwd_recvsÚ	fuse_workr³   Ú	bwd_sendss                     r@   rÊ   zSchedule1F1B._step_microbatchesŽ  sO  € ð "×/Ò/°¸ÀJÐPVÑWÔWÑˆ�àÔ&ð 	=Ø×"Ò" 7¨1¤:¨y¸¬|Ñ<Ô<Ð<õ ØÔ ØÔ˜tœ{Ô6Ñ6ñ
ô 
ˆð ˆØˆð ˆ	Øˆ	Ý�}Ñ%Ô%ð 	ð 	ˆAàœ×4Ò4°\ÑBÔBˆIÝ& y°zÐBÑBÔBÐBˆyð !Ø—’Ñ Ô Ð ð ”[×2Ò2°<ÀÈÔAVÐXaÐbnÔXoÑpÔpˆFð ð !Ø—’Ñ Ô Ð ð œ×4Ò4°\ÑBÔBˆIØ˜}¨qÑ0Ò0Ð0å& y°zÐBÑBÔB�	ð
 ×$Ò$ T¤[°&¸*ÀlÑSÔSÐSØ˜AÑˆLˆLð
'	àœ×4Ò4°\ÑBÔBˆIõ ' y°9Ñ'<ÐCVÐWÑWÔWÐWˆyð !Ø—’Ñ Ô Ð ð ×'Ò'¨¬°\ÑBÔBˆDØŒK×*Ò*ØØØ*¨dÔ.BÀQÑ.FÒFð +ñ ô ð ð œ×4Ò4°\ÑBÔBˆIØ˜AÑˆLà˜tÔ3Ò3Ð3àð œ×4Ò4°\ÑBÔBˆIõ ' y°9Ñ'<ÐCVÐWÑWÔWÐWˆyð !Ø—’Ñ Ô Ð ð ”[×2Ò2°<ÀÈÔAVÐXaÐbnÔXoÑpÔpˆFð ×$Ò$ T¤[°&¸*ÀlÑSÔSÐSð œ×4Ò4°\ÑBÔBˆIØ˜AÑˆLñO'	õT ˜y¨zÐ:Ñ:Ô:ˆ	ð ˜TÔ1Ò1Ð1àœ×4Ò4°\ÑBÔBˆIÝ& y°zÐBÑBÔBÐBˆyð !Ø—’Ñ Ô Ð ð ×'Ò'¨¬°\ÑBÔBˆDØŒK×*Ò*ØØØ*¨dÔ.BÀQÑ.FÒFð +ñ ô ð ð ð !Ø—’Ñ Ô Ð ð œ×4Ò4°\ÑBÔBˆIÝ" 9°:Ð>Ñ>Ô>ˆIØ˜AÑˆLð+ ˜TÔ1Ò1Ð1ð0 ð 	Ø�NŠNÑÔÐð 	×Ò˜DœK¨Ñ0Ô0Ð0Ð0Ð0rB   rã   r  rK   rB   r@   r   r   ˆ  s†   € € € € € ðð ð #'Ø$(Ø%)Ø!%ðI1ð I1à˜$”ðI1ð ˜D”>ðI1ð ˜T”Nð	I1ð
 ˜”ðI1ð I1ð I1ð I1ð I1ð I1rB   r   r'   Úcompute_actionsÚmax_active_stagesc                 ó  ‡
‡‡— dt           dt          t          t                            dt          t                    fd„}t	          ¦   «         Š
g Šdt           fˆ
ˆfd„}dt           fˆ
ˆfd„}t          | ¦  «        D ]‘\  }}|€Œ ||| |d…         ¦  «        Št          t          ˆ
fd	„‰¦  «        ¦  «        }t          t          ˆfd
„‰
¦  «        ¦  «        }|D ]}	 ||	¦  «         Œ|D ]}	 ||	¦  «         Œ‰                     |¦  «         Œ’‰S )aR  Given a basic schedule involving only compute actions (F,B,W), add UNSHARD/RESHARD actions for FSDP.

    UNSHARD refers to fetching the full contents of an FSDP-sharded layer, requiring an all-gather operation.
    RESHARD does the opposite, releasing memory (but doing no commmunication)

    We abandon the "timestep lock"  during lowering

    max_active_stages controls how many prefetches we allow. It should be measured in mb and tuneable but in practice
    3 stages is probably the thing we want?
    (to account for having one f and one b active, and something else prefetching?)
    ÚcountÚnext_actionsrb   c                 óØ   — t          ¦   «         }g }|D ]V}|�R|j        |vrI|                     |j        ¦  «         |                     |j        ¦  «         t	          |¦  «        | k    r nŒW|S )zdRemove duplicates (same stage, different microbatch), find next 'count' stages that will do compute.)ÚsetrN   Úaddr®   r^   )r:  r;  ÚseenÚretÚas        r@   Únext_stage_indicesz0_add_unshard_reshard.<locals>.next_stage_indices*  sv   € õ ™œˆØˆàð 	ð 	ˆAØˆ} ¤°dÐ!:Ð!:Ø—’˜œÑ'Ô'Ð'Ø—
’
˜1œ=Ñ)Ô)Ð)Ý�s‘8”8˜uÒ$Ð$Ø�EøØˆ
rB   rN   c                 ó„   •— ‰                      | ¦  «         ‰                     t          | t          d ¦  «        ¦  «         d S rR   )r>  r®   rM   r3   ©rN   Úactive_stagesÚfsdp_aware_actionss    €€r@   Ú_unshardz&_add_unshard_reshard.<locals>._unshard<  s=   ø€ Ø×Ò˜+Ñ&Ô&Ð&Ø×!Ò!¥'¨+µwÀÑ"EÔ"EÑFÔFÐFÐFÐFrB   c                 ó„   •— ‰                      | ¦  «         ‰                     t          | t          d ¦  «        ¦  «         d S rR   )Úremover®   rM   r4   rD  s    €€r@   Ú_reshardz&_add_unshard_reshard.<locals>._reshard@  s=   ø€ Ø×Ò˜[Ñ)Ô)Ð)Ø×!Ò!¥'¨+µwÀÑ"EÔ"EÑFÔFÐFÐFÐFrB   Nc                 ó   •— | ‰vS rR   rK   )ÚsrE  s    €r@   ú<lambda>z&_add_unshard_reshard.<locals>.<lambda>K  s   ø€  a¨}Ð&<€ rB   c                 ó   •— | ‰vS rR   rK   )rL  Únext_ns    €r@   rM  z&_add_unshard_reshard.<locals>.<lambda>M  s   ø€  a¨v o€ rB   )	r]   r   r   rM   r=  r�   rŠ   Úfilterr®   )r7  r8  rB  rG  rJ  rj   rE   ÚfetchÚevictr¯   rE  rF  rO  s             @@@r@   Ú_add_unshard_reshardrS    s”  øøø€ ð ÝðÝ"&¥xµÔ'8Ô"9ðå	�cŒðð ð ð õ "™eœe€MØ(*ÐðG�cð Gð Gð Gð Gð Gð Gð GðG�cð Gð Gð Gð Gð Gð Gð Gõ ˜Ñ/Ô/ð *ð *‰	ˆˆ6Øˆ>Øð $Ð#Ð$5°ÀqÀrÀrÔ7JÑKÔKˆå•VÐ<Ð<Ð<Ð<¸fÑEÔEÑFÔFˆå•VÐ5Ð5Ð5Ð5°}ÑEÔEÑFÔFˆð ð 	ð 	ˆEØˆH�U‰OŒOˆOˆOØð 	ð 	ˆEØˆH�U‰OŒOˆOˆOØ×!Ò! &Ñ)Ô)Ð)Ð)àÐrB   c                 ó  — g }| �r|                       d¦  «        }|€Œt          | ¦  «        r8| d         x}€.|                       d¦  «         t          | ¦  «        r
| d         x}®.|j        t          k    r{|�y|j        t          k    ri|j        |j        k    rY|j        |j        k    rI|                     t          |j        t          |j        ¦  «        ¦  «         |                       d¦  «         n|                     |¦  «         | �°|S )a9  Given a basic schedule involving only compute actions (F,I,W), merge adjacent I and W ops into B ops.
    (note: I = BACKWARD_INPUT, W = BACKWARD_WEIGHT, B = FULL_BACKWARD)

    B refers to running the whole backward (not separating grad_input and grad_weight), which can be more efficient
    in some cases.
    r   )
rì   r^   rO   r;   r<   rN   rP   r®   rM   r=   )r7  Úmerged_actionsrE   Únext_actions       r@   Ú	_merge_bwrW  `  s2  € ð €NØ
ñ *Ø ×$Ò$ QÑ'Ô'ˆØˆ>Øå�/Ñ"Ô"ð 	#°ÀqÔ7IÐ(I¨Ð'Rà×Ò Ñ"Ô"Ð"õ �/Ñ"Ô"ð 	#°ÀqÔ7IÐ(I¨Ð'Rð
 Ô#¥~Ò5Ð5ØÐ'ØÔ,µÒ?Ð?ØÔ" kÔ&=Ò=Ð=ØÔ'¨;Ô+GÒGÐGà×!Ò!Ý˜Ô*­M¸6Ô;RÑSÔSñô ð ð ×Ò Ñ"Ô"Ð"Ð"à×!Ò! &Ñ)Ô)Ð)ð+ ñ *ð, ÐrB   Ústage_to_rankrý   c           	      óB  ‡‡‡— d„ | D ¦   «         }d„ | D ¦   «         }dt           dt          fˆˆfd„Šdt           dt          t           t           f         fˆfd„}dt          t                    dt          t                    dt          fˆfd„}| �r”d	}t          | ¦  «        D �]r}t          | |         ¦  «        d
k    s#J d|›dt          | |         ¦  «        ›�¦   «         ‚| |         d
         }	 ||	||         ¦  «        sŒ`|	�×||                              |	¦  «         ||                              |	¦  «          ‰|	¦  «        r– ||	¦  «        \  }
}||                              |
¦  «         ||                              |
¦  «         | ‰|j	        ¦  «                                      |¦  «         | ‰|j	        ¦  «                                      |¦  «         | |          
                    d
¦  «         t          | |         ¦  «        d
k    r| |= d}�Œt|s
J d¦   «         ‚| �°”|S )Nc                 ó   — i | ]}|g “ŒS rK   rK   ©re   rŽ   s     r@   ú
<dictcomp>z"_add_send_recv.<locals>.<dictcomp>ˆ  s   € Ð-SÐ-SÐ-S¸4¨d°BÐ-SÐ-SÐ-SrB   c                 ó,   — i | ]}|t          ¦   «         “ŒS rK   ©r=  r[  s     r@   r\  z"_add_send_recv.<locals>.<dictcomp>‰  s   € Ð,UÐ,UÐ,U¸T¨Tµ3±5´5Ð,UÐ,UÐ,UrB   rE   rb   c                 ó  •— | j         t          k    r3| j        ‰dz
  k    o$ ‰| j        dz   ¦  «         ‰| j        ¦  «        k    S | j         t          t          fv r0| j        dk    o$ ‰| j        dz
  ¦  «         ‰| j        ¦  «        k    S dS )Nr   r   F)rO   r0   rN   r;   r=   )rE   rý   rX  s    €€r@   Ú
_has_commsz"_add_send_recv.<locals>._has_comms‹  s·   ø€ ØÔ"¥aÒ'Ð'ØÔ%¨°a©Ò7ð 3¸M¸MØÔ" QÑ&ñ=ô =à�˜vÔ1Ñ2Ô2ò=3ð 3ð Ô$­½Ð(GÐGÐGØÔ%¨Ò*ð 3¨}¨}ØÔ" QÑ&ñ0ô 0à�˜vÔ1Ñ2Ô2ò03ð 3ð ˆurB   c                 ó0  •—  ‰| ¦  «        sJ | › d�¦   «         ‚| j         }| j        }| j        }t          ||t          k    rt
          nt          |¦  «        }|t          k    r|dz   n|dz
  }t          ||t          k    rt          nt          |¦  «        }||fS )Nz is not a valid comm actionr   )	rN   rO   rP   rM   r0   r5   r7   r6   r8   )rE   Ú	stage_idxÚctypeÚmb_idxÚsendÚrecv_stage_idxÚrecvr`  s          €r@   Ú
_get_commsz"_add_send_recv.<locals>._get_comms–  sŸ   ø€ Øˆz˜&Ñ!Ô!ÐIÐI fÐ#IÐ#IÐ#IÑIÔIÐ!ØÔ&ˆ	ØÔ'ˆØÔ(ˆÝ�y¨EµQªJ¨J¥& &½FÀFÑKÔKˆØ*/µ1ª*¨*˜ Q™˜¸)Àa¹-ˆÝ�~°½!²°¥v vÅÈÑPÔPˆØ�TˆzÐrB   Úprev_actionsc                 ó  •— | €dS | j         t          k    rX| j        dk    sMt          | j        t          | j        ¦  «        |v rdS t          | j        dz
  t          | j        ¦  «        |v rdS dS | j         t          t          fv r‚| j        ‰dz
  k    stt          | j        t          | j        ¦  «        |v rdS t          | j        dz   t          | j        ¦  «        |v rdS t          | j        dz   t          | j        ¦  «        |v rdS dS dS )a  We don't put our own recv ops in the schedule, we let a sender on another rank put our recv ops in place.
        This helps ensure a sane (non-hanging) ordering of sends and recvs.
        But it also means we might not be able to schedule our next compute action yet.
        NTr   r   F)	rO   r0   rN   rM   r6   rP   r;   r=   r8   )rE   ri  rý   s     €r@   Ú_ready_to_schedulez*_add_send_recv.<locals>._ready_to_schedule   s<  ø€ ð ˆ>Ø�4ØÔ$­Ò)Ð)°&Ô2DÈÒ2IÐ2Iå˜Ô*­F°FÔ4KÑLÔLØð ð  ð �tå˜Ô*¨QÑ.µ°6Ô3JÑKÔKØð ð  ð �tØ�5àÔ#­½Ð'FÐFÐFØÔ&¨*°q©.Ò8Ð8õ ˜Ô*­F°FÔ4KÑLÔLØð ð  ð �tå˜Ô*¨QÑ.µÀÔ@WÑXÔXØð ð  ð �tå˜Ô*¨QÑ.µ¸vÔ?VÑWÔWØð ð  ð �tØ�5à�4rB   Fr   úrank=z, len(compute_actions[rank])=Tz6Malformed compute schedule, can't schedule sends/recvs)rM   Úboolr   r   r   r‰   r^   r®   r>  rN   rì   )r7  rX  rý   Úcomm_actionsri  rh  rk  ÚprogressrŽ   rE   re  rg  r`  s    ``         @r@   Ú_add_send_recvrp  ƒ  s³  øøø€ ð
 .TÐ-SÀ?Ð-SÑ-SÔ-S€LØ,UÐ,UÀ_Ð,UÑ,UÔ,U€Lð	�7ð 	¥tð 	ð 	ð 	ð 	ð 	ð 	ð 	ð�7ð ¥u­WµgÐ-=Ô'>ð ð ð ð ð ð ð*Ý�Ô!ð*Ý14µW´ð*å	ð*ð *ð *ð *ð *ð *ðX ñ RØˆå˜?Ñ+Ô+ð 	ñ 	ˆDå�O DÔ)Ñ*Ô*¨QÒ.Ð.Ð.Ø8�$Ð8Ð8�3˜¨tÔ4Ñ5Ô5Ð8Ð8ñ /Ô.Ð.à$ TÔ*¨1Ô-ˆFà%Ð% f¨l¸4Ô.@ÑAÔAð ØàÐ!Ø˜TÔ"×)Ò)¨&Ñ1Ô1Ð1Ø˜TÔ"×&Ò& vÑ.Ô.Ð.Ø�:˜fÑ%Ô%ð LØ!+ ¨FÑ!3Ô!3‘J�D˜$ð ! Ô&×-Ò-¨dÑ3Ô3Ð3Ø  Ô&×*Ò*¨4Ñ0Ô0Ð0Ø   ¨tÔ/?Ñ!@Ô!@ÔA×HÒHÈÑNÔNÐNØ   ¨tÔ/?Ñ!@Ô!@ÔA×EÒEÀdÑKÔKÐKà˜DÔ!×%Ò% aÑ(Ô(Ð(Ý�? 4Ô(Ñ)Ô)¨QÒ.Ð.Ø# DÐ)ØˆH‰HØÐQÐQÐQÑQÔQˆxð9 ñ Rð: ÐrB   rf   Úpp_group_sizeÚnum_microbatchesc                 óŒ  — t          | ¦  «        |k    sJ d|› dt          | ¦  «        › �¦   «         ‚t          |¦  «        D ]}|| v sJ d|› �¦   «         ‚Œd„ t          |¦  «        D ¦   «         }| D �]…}| |         D �]x}|€Œt          |t          ¦  «        sJ d|› d�¦   «         ‚|j        }|j        }|j        }	|t          k    r'||         t                                        |	¦  «         Œp|t          k    rM|	||         t                   v sJ d|› d|	› d	�¦   «         ‚||         t                                        |	¦  «         ŒÈ|t          k    rN|	||         t                   v sJ d
|› d|	› d	�¦   «         ‚||         t                                        |	¦  «         �Œ!|t          k    rL|	||         t                   v sJ d|› d|	› d�¦   «         ‚||         t                                        |	¦  «         �Œz�Œ‡|D ]Ë}t          ||         t                   ¦  «        }
t          ||         t                   ¦  «        }t          ||         t                   ¦  «        }t          ||         t                   ¦  «        }|
|k    sJ d|
› dt          › d|› d|› �¦   «         ‚|||z   dz  z   |k    sJ d|› d|› d|› d|› d|› �
¦   «         ‚ŒÌd S )Nz2Schedule has incorrect number of ranks - expected z	, actual z%Schedule is missing actions for rank c                 ó¬   — i | ]Q}|t           t          ¦   «         t          t          ¦   «         t          t          ¦   «         t          t          ¦   «         i“ŒRS rK   )r0   r=  r9   r1   r2   )re   Ústage_ids     r@   r\  z&_validate_schedule.<locals>.<dictcomp>ú  sS   € ð =ð =ð =ð ð 	Ý�s‰uŒuÝ�s‰uŒuÝ�s‰uŒuÝ�s‰uŒuð	
ð=ð =ð =rB   zGot an invalid action: z, expected instance of _Actionz Running Full Backward for stage z, microbatch z without first running Forwardz!Running Backward Input for stage z"Running Backward Weight for stage z% without first running Backward InputzGot rx   z microbatches for stage z, expected r&   z(Invalid backward microbatches for stage z: expected z( total backwards,             but got B=z, I=z, W=)r^   r‡   r½   rM   rN   rO   rP   r0   r>  r9   r1   r2   )rf   rq  rý   rr  rŽ   Ústage_actionsrE   Ús_idrc  Úmb_idÚf_mbÚb_mbÚi_mbÚw_mbs                 r@   Ú_validate_scheduler}  ì  s¡  € õ 	ˆG‰Œ˜Ò%Ð%Ð%Øb¸MÐbÐbÕTWÐX_ÑT`ÔT`ÐbÐbñ 	&Ô%Ð%å�mÑ$Ô$ð Oð OˆØ�wˆˆˆÐ NÈÐ NÐ N‰Œˆˆð=ð =õ ˜jÑ)Ô)ð=ñ =ô =€Mð ð 2ñ 2ˆØ˜d”mð 	2ñ 	2ˆFØˆ~ØÝØ�ñô ð Pð PàO¨ÐOÐOÐOñPô Pð ð Ô%ˆDØÔ+ˆEØÔ+ˆEØ�ŠzˆzØ˜dÔ#¥AÔ&×*Ò*¨5Ñ1Ô1Ð1Ð1Ø�!’�à˜]¨4Ô0µÔ3Ð3Ð3Ð3Øn°dÐnÐnÈÐnÐnÐnñ 4Ô3Ð3à˜dÔ#¥AÔ&×*Ò*¨5Ñ1Ô1Ð1Ð1Ø�!’�à˜]¨4Ô0µÔ3Ð3Ð3Ð3Øo°tÐoÐoÈ%ÐoÐoÐoñ 4Ô3Ð3à˜dÔ#¥AÔ&×*Ò*¨5Ñ1Ô1Ð1Ñ1Ø�!’�à˜]¨4Ô0µÔ3Ð3Ð3Ð3Øw¸ÐwÐwÈ5ÐwÐwÐwñ 4Ô3Ð3à˜dÔ#¥AÔ&×*Ò*¨5Ñ1Ô1Ð1ùñ3	2ð6 ð 2ð 2ˆÝ�= Ô&¥qÔ)Ñ*Ô*ˆÝ�= Ô&¥qÔ)Ñ*Ô*ˆÝ�= Ô&¥qÔ)Ñ*Ô*ˆÝ�= Ô&¥qÔ)Ñ*Ô*ˆð Ð$Ò$Ð$Ð$ØW�$ÐWÐW�ÐWÐW°DÐWÐWÐEUÐWÐWñ %Ô$Ð$ð �D˜4‘K AÑ%Ñ%Ð)9Ò9Ð9Ð9ð2°dð 2ð 2ÐGWð 2ð 2Øð2ð 2Ø!%ð2ð 2Ø+/ð2ð 2ñ :Ô9Ð9Ð9ð2ð 2rB   c                   óž  ‡ — e Zd ZdZ	 	 	 	 	 	 ddee         dedee         dee	e
df                  deeee
f                  d	eeeeef         e	e         f                  d
eeeef                  dee         fˆ fd„Zde	edf         fd„Zd„ Zdd„Zdddœdee         fd„Z	 	 	 	 ddee         dee         dee         dee         fd„Zˆ xZS )r   zQ
    Base class for multi-stage schedules.
    Implements the `step` method.
    NrÁ   rš   r›   rœ   .r�   rž   Ústage_index_to_group_rankÚuse_full_backwardc	                 óÄ  •‡
— t          ¦   «                              |||||¬¦  «         || _        |d         j        | _        |d         j        | _        |d         j        | _        |�| j        D ]	}	||	_	        Œ
|d         j	        | _	        | j        D ]}	| j
        |	_        Œd| _        | j        d uŠ
ˆ
fd„| _        i | _        |�t                                d¦  «         d S d S )Nrú   r   Fc                 ó   •— | j         o‰S rR   rº   )r¯   Úhas_losss    €r@   rM  z0PipelineScheduleMulti.__init__.<locals>.<lambda>Z  s   ø€ °%´-Ð2LÀH€ rB   zDeprecation warning: 'use_full_backward' is no longer supported. Simply stop passing it, and everything should still work fine.)rû   rª   Ú_stagesrý   rþ   Ú
group_sizerq  Ú
group_rankrŽ   r  r¥   rÿ   Ú_stages_initializedr¡   Ú_should_compute_lossr`   r§   Úwarning)r>   rÁ   rš   r›   rœ   r�   rž   r  r€  r¯   rƒ  r©   s             @€r@   rª   zPipelineScheduleMulti.__init__5  s&  øø€ õ 	‰Œ×ÒØ)ØØ+Ø/Ø/ð 	ñ 	
ô 	
ð 	
ð ˆŒØ! !œ9Ô/ˆÔØ# AœYÔ1ˆÔØ˜1”IÔ(ˆŒ	à$Ð0Øœð Lð L�Ø2K�Ô/Ð/Ø)/°¬Ô)LˆÔ&ð ”\ð 	4ð 	4ˆEØ!%Ô!3ˆEÔÐØ#(ˆÔ ð œ¨dÐ2ˆØ$LÐ$LÐ$LÐ$LˆÔ!ð CEˆÔàÐ(Ý�NŠNðQñô ð ð ð ð )Ð(rB   rÏ   c                 ó  — t          ¦   «         }| j        D ]c}|j        r|                     | j        ||¦  «        }n|                     | j        ||¦  «        }| j        r|                     | j        ¦  «         Œdd| _        d S r  )Útupler„  Úis_firstr  r    r¥   r  r‡  )r>   rÏ   rÐ   Únext_stage_argsr¯   s        r@   Ú_initialize_stagesz(PipelineScheduleMulti._initialize_stagese  s    € õ ,1©7¬7ˆØ”\ð 	Dð 	DˆEØŒ~ð Ø"'×">Ò">ØÔ(¨$°ñ#ô #��ð #(×">Ò">ØÔ(¨/¸6ñ#ô #�ð Ô!ð DØ×-Ò-¨dÔ.BÑCÔCÐCøØ#'ˆÔ Ð Ð rB   c                 óÚ   — t          |dd¬¦  «        5 }t          j        |¦  «        }| j        D ]"}|                     | j        |         ¦  «         Œ#	 ddd¦  «         dS # 1 swxY w Y   dS )zQDump a CSV representation of the schedule into a file with the provided filename.ÚwrX   ©ÚnewlineN)ÚopenÚcsvÚwriterr`   Úwriterow©r>   ÚfilenameÚcsvfiler•  rŽ   s        r@   Ú	_dump_csvzPipelineScheduleMulti._dump_csvw  s»   € å�(˜C¨Ð,Ñ,Ô,ð 	;°Ý”Z Ñ(Ô(ˆFØÔ+ð ;ð ;�Ø—’ Ô 3°DÔ 9Ñ:Ô:Ð:Ð:ð;ð	;ð 	;ð 	;ñ 	;ô 	;ð 	;ð 	;ð 	;ð 	;ð 	;ð 	;ð 	;øøøð 	;ð 	;ð 	;ð 	;ð 	;ð 	;s   “?A Á A$Á'A$Úcompute_onlyc                 ó0  — |dk    sJ ‚t          |d¬¦  «        5 }t          j        |¦  «        }t          |¦  «        D ]\  }}d„ |D ¦   «         | j        |<   Œ	 ddd¦  «         n# 1 swxY w Y   t          | j        | j        | j        | j        ¦  «         dS )zöLoad a CSV representation of the schedule from a file with the provided filename.
        This API will most likely get renamed/refactored so is marked as internal for now.

        format must be "compute_only" for PipelineScheduleMulti
        r›  rX   r‘  c                 óB   — g | ]}t                                |¦  «        ‘ŒS rK   ©rM   rF   ©re   rL  s     r@   rl   z3PipelineScheduleMulti._load_csv.<locals>.<listcomp>ˆ  s&   € Ð,NÐ,NÐ,NÀQ­W×-=Ò-=¸aÑ-@Ô-@Ð,NÐ,NÐ,NrB   N)	r“  r”  Úreaderr�   r`   r}  rq  rþ   r    )r>   r˜  Úformatr™  r   rŽ   rƒ   s          r@   Ú	_load_csvzPipelineScheduleMulti._load_csv~  s  € ð ˜Ò'Ð'Ð'Ð'Ý�( BÐ'Ñ'Ô'ð 	O¨7Ý”Z Ñ(Ô(ˆFÝ& vÑ.Ô.ð Oð O‘	��cØ,NÐ,NÈ#Ð,NÑ,NÔ,N�Ô# DÑ)Ð)ðOð	Oð 	Oð 	Oñ 	Oô 	Oð 	Oð 	Oð 	Oð 	Oð 	Oð 	Oøøøð 	Oð 	Oð 	Oð 	Oõ 	ØÔØÔØÔØÔ ñ		
ô 	
ð 	
ð 	
ð 	
s   š>A%Á%A)Á,A)rË   rÂ   c                óV  — | j         D ]}|                     ¦   «          Œ|                      ||¦  «        \  }}|�(t          t	          j        || j        ¦  «        ¦  «        }nd}|                      ||||¦  «         | j         D ]%}|j        r|  	                    |j
        ¦  «        c S Œ&dS r  )r„  r  rß   rŠ   rä   r	  r    rÊ   r¬   râ   rà   )	r>   rÌ   rÂ   rÏ   rÐ   r¯   rÝ   rÞ   r
  s	            r@   rÑ   zPipelineScheduleMulti.step�  sØ   € ð ”\ð 	)ð 	)ˆEØ×&Ò&Ñ(Ô(Ð(Ð(ð $(×#5Ò#5°d¸FÑ#CÔ#CÑ ˆ
�Lð ÐÝ ¥Ô!3°F¸DÔ<PÑ!QÔ!QÑRÔRˆMˆMà ˆMð 	×Ò 
¨L¸-ÈÑPÔPÐPð ”\ð 	@ð 	@ˆEØŒ}ð @Ø×*Ò*¨5Ô+>Ñ?Ô?Ð?Ð?Ð?ð@ð ˆtrB   rÅ   rÆ   r±   c           	      ó¤
  — |                       ||||¦  «        \  }}| j        s"|                      |d         |d         ¦  «         d„ | j        D ¦   «         }t	          ¦   «         }t	          ¦   «         }|                     ¦   «         D ]\}|dk    r#|                     | j        |dz
           ¦  «         || j        dz
  k     r#|                     | j        |dz            ¦  «         Œ]t          ¦   «         }	t          | j        | j                 ¦  «        D �]#\  }
}	 g }|��þ|j        }|j        }|j        }|€
J d¦   «         ‚|t           j        k    rm||         }|                     |||         ||         ¦  «        }|                      ||||¦  «         |                     |                     |¦  «        ¦  «         �n`|t           j        k    r||         }|                      ||¦  «        }|	|xx         dz  cc<   |                     ||d|	|         | j        k    ¬¦  «         |                     |                     |¦  «        ¦  «         nÑ|t           j        k    r`||         }|                      ||¦  «        }|                     ||dd¬¦  «         |                     |                     |¦  «        ¦  «         na|t           j        k    r?||         }|	|xx         dz  cc<   |                     ||	|         | j        k    ¬	¦  «         nt=          d
|› �¦  «        ‚|D ]Ã}| j        |         }d}|
t?          |¦  «        k     r||
         }|�•|j        }|j        }|j        }|€
J d¦   «         ‚|t           j        k    r;|dz   |v r3||dz            }|                     |                      |¦  «        ¦  «         Œš|t,          t6          t8          fv rŒ±t=          d
|› �¦  «        ‚ŒÄ|D ]½}| j        |         }d}|
t?          |¦  «        k     r||
         }|��|j        }|j        }|j        }|€
J d¦   «         ‚|t"          t8          fv rŒ`|t6          t,          fv r;|dz
  |v r3||dz
           }|                     | !                    |¦  «        ¦  «         Œ«t=          d
|› �¦  «        ‚Œ¾|r!tE          |¦  «         #                    ¦   «          �Œµ# tH          $ rc}tJ           &                    d| j        | j'        j(        |
|¦  «         tJ           &                    dtS          | j        |
¬¦  «        ¦  «         |‚d}~ww xY w|  *                    | j        |¦  «         dS )úì
        Operate on the microbatches for looped schedules (multiple stages on each rank).

        TODO: Does not use sorted_batch_isend_irecv(). As a result, this schedule does
        not support models with skip connections.
        r   c                 ó   — i | ]
}|j         |“ŒS rK   ©rN   r»   s     r@   r\  z<PipelineScheduleMulti._step_microbatches.<locals>.<dictcomp>Æ  ó*   € ð ?
ð ?
ð ?
Ø).ˆEÔ˜uð?
ð ?
ð ?
rB   r   NzCAll currently supported action types require valid microbatch_indexT©r³   Úfull_backwardr!  F©r!  zUnknown computation type zy[Rank %s] pipeline schedule %s caught the following exception                      at time_step %s when running action %sz%s©ra   )+rÚ   r‡  rŽ  r„  r=  Úkeysr>  r  rþ   r   r�   r`   rŽ   rO   rP   rN   r%   r:   r  r´   rÀ   r  r=   r·   r$  r    r%  r;   r<   Úbackward_weight_one_chunkr×   r^   r  r#  rî   r  Ú	Exceptionr§   Úerrorr©   rG   r—   rÄ   )r>   rÅ   rÆ   r±   rÂ   Ústage_index_to_stageÚall_prev_ranksÚall_next_ranksrN   Úbackward_counterÚ	time_steprE   rö   rO   r²   r¯   r°   r³   Ú	prev_rankÚprev_rank_opsÚprev_rank_actionÚ	next_rankÚnext_rank_opsÚnext_rank_actionÚes                            r@   rÊ   z(PipelineScheduleMulti._step_microbatches²  ss  € ð "×/Ò/°¸ÀJÐPVÑWÔWÑˆ�àÔ'ð 	>Ø×#Ò# G¨A¤J°	¸!´Ñ=Ô=Ð=ð?
ð ?
Ø26´,ð?
ñ ?
ô ?
Ðõ $'¡5¤5ˆÝ#&¡5¤5ˆØ/×4Ò4Ñ6Ô6ð 	Tð 	TˆKà˜QŠˆØ×"Ò" 4Ô#AÀ+ÐPQÁ/Ô#RÑSÔSÐSØ˜TÔ-°Ñ1Ò1Ð1Ø×"Ò" 4Ô#AÀ+ÐPQÁ/Ô#RÑSÔSÐSøå)0©¬ÐÝ!*¨4Ô+>¸t¼yÔ+IÑ!JÔ!Jð E	ñ E	ÑˆI�vðDØ(*�ØÑ%Ø'-Ô'>Ð$Ø%Ô6�HØ"(Ô"4�Kà Ð,Ð,Ø\ñ -Ô,Ð,à'Õ+;Ô+CÒCÐCà 4°[Ô A˜Ø!&×!8Ò!8Ø$ g¨hÔ&7¸À8Ô9Lñ"ô "˜ð ×0Ò0°¸À
ÈHÑUÔUÐUØŸ
š
 5×#9Ò#9¸(Ñ#CÔ#CÑDÔDÐDÑDØ)Õ-=Ô-KÒKÐKà 4°[Ô A˜Ø#×3Ò3°E¸8ÑDÔD˜Ø(¨Ð5Ð5Ô5¸Ñ:Ð5Ð5Ñ5Ø×0Ò0Ø$Ø!%Ø*.Ø*:¸;Ô*GØ#Ô3ò+4ð	 1ñ ô ð ð Ÿ
š
 5×#9Ò#9¸(Ñ#CÔ#CÑDÔDÐDÐDØ)Õ-=Ô-LÒLÐLà 4°[Ô A˜Ø#×3Ò3°E¸8ÑDÔD˜Ø×0Ò0Ø$Ø!%Ø*/Ø*/ð	 1ñ ô ð ð Ÿ
š
 5×#9Ò#9¸(Ñ#CÔ#CÑDÔDÐDÐDØ)Õ-=Ô-MÒMÐMà 4°[Ô A˜Ø(¨Ð5Ð5Ô5¸Ñ:Ð5Ð5Ñ5Ø×7Ò7Ø$Ø*:¸;Ô*GØ#Ô3ò+4ð 8ñ ô ð ð õ )Ð)WÐEUÐ)WÐ)WÑXÔXÐXð "0ð ð �IØ$(Ô$7¸	Ô$B�MØ'+Ð$Ø ¥3 }Ñ#5Ô#5Ò5Ð5Ø+8¸Ô+CÐ(Ø'Ð3Ø+;Ô+LÐ(Ø#3Ô#D˜Ø&6Ô&B˜à$Ð0Ð0Ø`ñ 1Ô0Ð0ð ,Õ/?Ô/GÒGÐGà*¨Q™Ð2FÐFÐFð )=¸[È1¹_Ô(M Ø #§
¢
¨5×+AÒ+AÀ(Ñ+KÔ+KÑ LÔ LÐ LøØ-Ý)Ý*Ý+ð2ð ð ð !å",Ø NÐ<LÐ NÐ Nñ#ô #ð ð/ 4ð4 "0ð ð �IØ$(Ô$7¸	Ô$B�MØ'+Ð$Ø ¥3 }Ñ#5Ô#5Ò5Ð5Ø+8¸Ô+CÐ(Ø'Ð3Ø+;Ô+LÐ(Ø#3Ô#D˜Ø&6Ô&B˜à$Ð0Ð0Ø`ñ 1Ô0Ð0ð ,µ½Ð/IÐIÐIà Ø-µ.Å-Ð1PÐPÐPà*¨Q™Ð2FÐFÐFð )=¸[È1¹_Ô(M Ø #§
¢
¨5×+AÒ+AÀ(Ñ+KÔ+KÑ LÔ LÐ Løå",Ø NÐ<LÐ NÐ Nñ#ô #ð ð' 4ð0 ð +Ý˜s‘O”O×(Ò(Ñ*Ô*Ð*ùøÝð ð ð Ý—’ð=à”IØ”NÔ+ØØñô ð õ —’ØÝ*ØÔ+¸yðñ ô ñô ð ð �øøøøðøøøð" 	×Ò˜DœL¨&Ñ1Ô1Ð1Ð1Ð1s   ÄN,SÓ
T2ÓAT-Ô-T2)NNNNNN©r›  rã   )rG   rH   rI   r  r   r   r]   r   r	   r   r   r
   rS   r   r   rm  rª   rŽ  rš  r¢  rÑ   rÊ   r  r  s   @r@   r   r   /  så  ø€ € € € € ðð ð '+ØAEØBFØIMØ>BØ,0ð.ð .àÐ'Ô(ð.ð ð.ð ˜(Ô#ð	.ð
 " %¨¸Ð(<Ô"=Ô>ð.ð $ D¨¨oÐ)=Ô$>Ô?ð.ð $ E¨$¨s°C¨x¬.¸%À¼*Ð*DÔ$EÔFð.ð $,¨D°°c°¬NÔ#;ð.ð $ Dœ>ð.ð .ð .ð .ð .ð .ð`( u¨S°#¨X¤ð (ð (ð (ð (ð$;ð ;ð ;ð
ð 
ð 
ð 
ð$ "&Àð  ð  ð  ¨x¸¬~ð  ð  ð  ð  ðH #'Ø$(Ø%)Ø!%ðk2ð k2à˜$”ðk2ð ˜D”>ðk2ð ˜T”Nð	k2ð
 ˜”ðk2ð k2ð k2ð k2ð k2ð k2ð k2ð k2rB   r   c            
       óÎ   ‡ — e Zd ZdZ	 ddeeeee                  f         de	fd„Z
dde	de	fˆ fd„Zde	fd„Zd	„ Z	 	 	 	 ddee         dee         dee         dee         fd„Zˆ xZS )Ú_PipelineScheduleRuntimea%  
    Provides a simple runtime that requires a 'schedule IR' including specified communication operations.

    Can be instantiated directly by creating _PipelineScheduleRuntime and calling load_csv, or can be
    subclassed and the subclass can be responsible for creating a schedule IR.
    r›  rf   r¡  c                 ó‚  ‡ — ‰ j         €
J d¦   «         ‚i ‰ _        |dk    r@|D ];}g ‰ j        |<   ||         D ]&}|€J ‚‰ j        |                              |¦  «         Œ'Œ<dS |dk    rH|D ]}t          ||         ¦  «        ‰ j        |<   Œ t	          ‰ j        ˆ fd„‰ j        ¬¦  «        ‰ _        dS t          d|›d�¦  «        ‚)	zé
        Given an in-memory representation for a simple compute-only schedule, lower it to a complex schedule including
        communication actions.  Stores the schedule in self, and must be called before running step_mo()
        NzAstage_index_to_group_rank is required for PipelineScheduleRuntimeÚcompute_commsr›  c                 ó   •— ‰j         |          S rR   ©r  ©rL  r>   s    €r@   rM  z8_PipelineScheduleRuntime._load_actions.<locals>.<lambda>…  s   ø€ ¨Ô(FÀqÔ(I€ rB   )rX  rý   úformat=ú is not implemented)r  Úpipeline_order_with_commsr®   rS  rp  rþ   rÉ   )r>   rf   r¡  rŽ   rE   s   `    r@   Ú_load_actionsz&_PipelineScheduleRuntime._load_actionsh  s2  ø€ ð Ô*Ð6Ð6ØNñ 7Ô6Ð6àCEˆÔ&Ø�_Ò$Ð$Øð Hð H�Ø79�Ô.¨tÑ4Ø% dœmð Hð H�FØ!Ð-Ð-Ð-ØÔ2°4Ô8×?Ò?ÀÑGÔGÐGÐGðHðHð Hð �~Ò%Ð%àð ð �Ý7KØ˜D”Mñ8ô 8�Ô.¨tÑ4Ð4õ .<ØÔ.ØIÐIÐIÐIØÔ+ð.ñ .ô .ˆDÔ*Ð*Ð*õ &Ð&E¨Ð&EÐ&EÐ&EÑFÔFÐFrB   r˜  c                 ó¶  •— |dk    r=t          ¦   «                              |¦  «         |                      | j        ¦  «         dS |dk    r}i }t	          |d¬¦  «        5 }t          j        |¦  «        }t          |¦  «        D ]\  }}d„ |D ¦   «         ||<   Œ|                      ||¬¦  «         ddd¦  «         dS # 1 swxY w Y   dS t          d|›d	�¦  «        ‚)
a  Loads a csv in simple format and then lowers it to include comunication actions

        format must be either "compute_only" or "compute_comms".  If compute_only, the lowering passes
        will automatically be run to generate a compute_comms schedule.
        r›  rÁ  rX   r‘  c                 óB   — g | ]}t                                |¦  «        ‘ŒS rK   rž  rŸ  s     r@   rl   z6_PipelineScheduleRuntime._load_csv.<locals>.<listcomp>›  s&   € Ð$FÐ$FÐ$F¸Q¥W×%5Ò%5°aÑ%8Ô%8Ð$FÐ$FÐ$FrB   )r¡  NrÅ  rÆ  )	rû   r¢  rÈ  r`   r“  r”  r   r�   rÉ   )	r>   r˜  r¡  rf   r™  r   rŽ   rƒ   r©   s	           €r@   r¢  z"_PipelineScheduleRuntime._load_csv‹  sC  ø€ ð �^Ò#Ð#å‰GŒG×Ò˜hÑ'Ô'Ð'à×Ò˜tÔ2Ñ3Ô3Ð3Ð3Ð3Ø�Ò&Ð&ØˆGÝ�h¨Ð+Ñ+Ô+ð ;¨wÝœ GÑ,Ô,�Ý!*¨6Ñ!2Ô!2ð Gð G‘I�D˜#Ø$FÐ$FÀ#Ð$FÑ$FÔ$F�G˜D‘M�MØ×"Ò" 7°6Ð"Ñ:Ô:Ð:ð	;ð ;ð ;ñ ;ô ;ð ;ð ;ð ;ð ;ð ;ð ;ð ;øøøð ;ð ;ð ;ð ;ð ;ð ;õ &Ð&E¨Ð&EÐ&EÐ&EÑFÔFÐFs   ÁAB;Â;B?ÃB?c                 óü   — | j         €
J d¦   «         ‚t          |dd¬¦  «        5 }t          j        |¦  «        }| j         D ]"}|                     | j         |         ¦  «         Œ#	 ddd¦  «         dS # 1 swxY w Y   dS )zaDump a CSV representation of the compute + comms schedule into a file with the provided filename.Nz6Must initialize compute_comms schedule before dump_csvr�  rX   r‘  )rÇ  r“  r”  r•  r–  r—  s        r@   rš  z"_PipelineScheduleRuntime._dump_csv   sí   € ð
 Ô*Ð6Ð6ØCñ 7Ô6Ð6å�(˜C¨Ð,Ñ,Ô,ð 	F°Ý”Z Ñ(Ô(ˆFØÔ6ð Fð F�Ø—’ Ô >¸tÔ DÑEÔEÐEÐEðFð	Fð 	Fð 	Fñ 	Fô 	Fð 	Fð 	Fð 	Fð 	Fð 	Fð 	Fð 	Føøøð 	Fð 	Fð 	Fð 	Fð 	Fð 	Fs   ¤?A1Á1A5Á8A5c                 ó@   ‡ — t          ‰ j        ˆ fd„‰ j        ¦  «        S )Nc                 ó   •— ‰j         |          S rR   rÃ  rÄ  s    €r@   rM  z4_PipelineScheduleRuntime._simulate.<locals>.<lambda>¯  s   ø€ �dÔ4°QÔ7€ rB   )Ú_simulate_comms_computerÇ  rþ   )r>   s   `r@   Ú	_simulatez"_PipelineScheduleRuntime._simulate¬  s-   ø€ Ý&ØÔ*Ø7Ð7Ð7Ð7ØÔñ
ô 
ð 	
rB   NrÅ   rÆ   r±   rÂ   c                 óþ  ‡‡— |                       ||||¦  «        \  }}| j        s"|                      |d         |d         ¦  «         d„ | j        D ¦   «         }| j        €
J d¦   «         ‚i }i }g }i Št          ¦   «         Šdt          fˆˆfd„}	t          ¦   «         }
t          | j        | j	                 ¦  «        D �]E\  }}	 |j
        }|j        �|j        nd}|dk    s|t          t          fv sJ d|›d	�¦   «         ‚|j        }||         }t          |j        t"          ¦  «        }|d
z   |v }|d
z
  |v }t$                               d||¦  «         |t(          k    r7|                     t-          |                     |¦  «        ¦  «        ¦  «         �n|t0          k    r7|                     t-          |                     |¦  «        ¦  «        ¦  «         �nÙ|t4          k    r9||f|vs
J d¦   «         ‚t-          |                     |¦  «        ¦  «        |||f<   �n•|t8          k    r9||f|vs
J d¦   «         ‚t-          |                     |¦  «        ¦  «        |||f<   �nQ|t          k    r8|r4|‰vr|‰vsJ d|›d�¦   «         ‚|j                             d¬¦  «        ‰|<   �n|t          k    rA|r=|‰v sJ d|›d�¦   «         ‚|‰vsJ d|›d�¦   «         ‚|j                             ¦   «          �nÂ|t@          k    r±|r |	|¦  «         |j!        s?|s=||f|v sJ d|›d�¦   «         ‚| "                    ||f¦  «         #                    ¦   «          | $                    |||         ||         ¦  «        }|  %                    ||||¦  «         |r||d
z             &                    ||¦  «         �n|tN          k    r×|r |	|¦  «         |j(        s?|s=||f|v sJ d|›d�¦   «         ‚| "                    ||f¦  «         #                    ¦   «          |  )                    ||¦  «        }|
|xx         d
z  cc<   | *                    ||d|
|         | j+        k    ¬¦  «         |r2||d
z
            ,                    | -                    |¦  «        |¦  «         �n$|t\          k    r·|r |	|¦  «         |j(        s?|s=||f|v sJ d|›d�¦   «         ‚| "                    ||f¦  «         #                    ¦   «          |  )                    ||¦  «        }| *                    ||dd¬¦  «         |r2||d
z
            ,                    | -                    |¦  «        |¦  «         nb|t^          k    rD|r |	|¦  «         |
|xx         d
z  cc<   | 0                    ||
|         | j+        k    ¬¦  «         ntc          d|›d�¦  «        ‚�Œô# td          $ rF}t$           3                    d||¦  «         ti          tk          | j        |¬¦  «        ¦  «         |‚d}~ww xY wtm          |¦  «        r5| "                    ¦   «          #                    ¦   «          tm          |¦  «        °5tm          ‰¦  «        dk    s
J d¦   «         ‚|  7                    | j        |¦  «         dS )r¥  r   c                 ó   — i | ]
}|j         |“ŒS rK   r§  r»   s     r@   r\  z?_PipelineScheduleRuntime._step_microbatches.<locals>.<dictcomp>Æ  r¨  rB   Nz=Must call _load_actions() before calling _step_microbatches()rb  c                 ó–   •— | ‰v r2‰|                                ¦   «          ‰| = ‰                     | ¦  «         | ‰v sJ d| ›�¦   «         ‚dS )zQIf an unshard is active for `stage_idx`, wait() it and mark `stage_idx` unshared.z*Attempted to compute on sharded stage_idx=N)r  r>  )rb  Úunshard_opsÚunsharded_stagess    €€r@   Ú_assert_unshardedzF_PipelineScheduleRuntime._step_microbatches.<locals>._assert_unshardedÙ  sl   ø€ à˜KÐ'Ð'Ø˜IÔ&×+Ò+Ñ-Ô-Ð-Ø 	Ð*Ø ×$Ò$ YÑ/Ô/Ð/àÐ-Ð-Ð-Ð-Ø>°)Ð>Ð>ñ .Ô-Ð-Ð-Ð-rB   éÿÿÿÿzaction=z missing mb_indexr   z8_PipelineScheduleRuntime running time_step %d, action %szARecv twice for {stage_idx=} {mb_index=} without executing forwardzBRecv twice for {stage_idx=} {mb_index=} without executing backwardzUnsharding the same stage_idx=z twiceT)Úasync_opzResharding stage_idx=z without unshardingz before finishing unshardzComputing action=z before receiving inputz Attempted to run compute action=r©  Fr«  z is unknown or unsupportedz\_PipelineScheduleRuntime caught exception at step %s when running action %s.  Full Schedule:r¬  zUnused unshard operations)8rÚ   r‡  rŽ  r„  rÇ  r=  r]   r   r�   rŽ   rO   rP   r3   r4   rN   r½   Úsubmodr   r§   ré   r5   r®   rî   r  r7   r%  r6   r  r8   r#  ÚunshardÚreshardr:   rŒ  rì   r  r  r´   Úset_local_fwd_inputr=   r¬   r·   r$  r    Úset_local_bwd_inputÚget_local_bwd_outputr;   r<   r®  r×   r¯  r°  Úprintr—   r^   rÄ   )r>   rÅ   rÆ   r±   rÂ   r±  Úbwd_recv_opsÚfwd_recv_opsÚsend_opsrÕ  r´  rµ  rE   Ú	comp_typer²   rb  r¯   Ústage_uses_fsdpÚis_next_stage_on_this_rankÚis_prev_stage_on_this_rankr°   r³   r¼  rÓ  rÔ  s                          @@r@   rÊ   z+_PipelineScheduleRuntime._step_microbatches³  s	  øø€ ð "×/Ò/°¸ÀJÐPVÑWÔWÑˆ�ØÔ'ð 	>Ø×#Ò# G¨A¤J°	¸!´Ñ=Ô=Ð=ð?
ð ?
Ø26´,ð?
ñ ?
ô ?
Ðð
 Ô*Ð6Ð6ØJñ 7Ô6Ð6ð 57ˆØ46ˆð  "ˆð 13ˆÝ™5œ5Ðð	?­ð 	?ð 	?ð 	?ð 	?ð 	?ð 	?ð 	?õ *1©¬ÐÝ!*¨4Ô+IÈ$Ì)Ô+TÑ!UÔ!Uð i	ñ i	ÑˆI�vðhØ"Ô3�	ð Ô.Ð:ð Ô+Ð+àð ð
   1’}�}¨	ÝÝð6ð )ð )ð )ð 1�fÐ0Ð0Ð0ñ)ô )ð ð #Ô.�	Ø,¨YÔ7�Ý",¨U¬\½:Ñ"FÔ"F�à-6¸©]Ð>RÐ-RÐ*Ø-6¸©]Ð>RÐ-RÐ*å—’ØNØØñô ð ð ¥Ò&Ð&Ø—O’O¥J¨u×/EÒ/EÀhÑ/OÔ/OÑ$PÔ$PÑQÔQÐQÑQØ¥&Ò(Ð(Ø—O’O¥J¨u×/EÒ/EÀhÑ/OÔ/OÑ$PÔ$PÑQÔQÐQÑQØ¥&Ò(Ð(à!Ø ðð *ð*ð *ð *ð ,oñ*ô *ð *õ ;EØ×.Ò.¨xÑ8Ô8ñ;ô ;�L )¨XÐ!6Ñ7Ñ7ð ¥&Ò(Ð(à!Ø ðð *ð*ð *ð *ð ,pñ*ô *ð *õ ;EØ×.Ò.¨xÑ8Ô8ñ;ô ;�L )¨XÐ!6Ñ7Ñ7ð ¥'Ò)Ð)Ø&ð Uà%Ð-=Ð=Ð=Ø )°Ð <Ð <Ð <ØD°)ÐDÐDÐDñ !=Ô <ð=ð 27´×1EÒ1EÈtÐ1EÑ1TÔ1T˜ IÑ.ùØ¥'Ò)Ð)Ø&ð /à%Ð)9Ð9Ð9Ð9ØH¨ÐHÐHÐHñ :Ô9Ð9ð &¨[Ð8Ð8Ð8ØN¨ÐNÐNÐNñ 9Ô8Ð8àœ×,Ò,Ñ.Ô.Ð.ùØ¥'Ò)Ð)Ø&ð 5Ø)Ð)¨)Ñ4Ô4Ð4ð "œNð	Gð !;ð	Gð &Ø$ð ð *ð *ð  *ð  *ð ,Y¸Ð+XÐ+XÐ+Xñ *ô  *ð  *ð %×(Ò(¨)°XÐ)>Ñ?Ô?×DÒDÑFÔFÐFà"×4Ò4Ø  '¨(Ô"3°Y¸xÔ5Hñô �Fð ×,Ò,¨U°F¸JÈÑQÔQÐQð 2ð Ø,¨Y¸©]Ô;×OÒOØ" Hñô ð ùð ¥-Ò/Ð/Ø&ð 5Ø)Ð)¨)Ñ4Ô4Ð4ð "œMðGð !;ðGð &Ø$ð ð *ð *ð  *ð  *ð Y¸ÐXÐXÐXñ	 *ô  *ð  *ð %×(Ò(¨)°XÐ)>Ñ?Ô?×DÒDÑFÔFÐFØ×/Ò/°°xÑ@Ô@�DØ$ YÐ/Ð/Ô/°1Ñ4Ð/Ð/Ñ/Ø×,Ò,Ø Ø!Ø&*Ø&6°yÔ&AØÔ/ò'0ð	 -ñ ô ð ð 2ð Ø,¨Y¸©]Ô;×OÒOØ!×6Ò6°xÑ@Ô@À(ñô ð ùð ¥.Ò0Ð0Ø&ð 5Ø)Ð)¨)Ñ4Ô4Ð4à œ=ð GÐ1Kð Gà%Ø$ð ð *ð *ð  *ð  *ð Y¸ÐXÐXÐXñ	 *ô  *ð  *ð %×(Ò(¨)°XÐ)>Ñ?Ô?×DÒDÑFÔFÐFØ×/Ò/°°xÑ@Ô@�DØ×,Ò,Ø Ø!Ø&+Ø&+ð	 -ñ ô ð ð 2ð Ø,¨Y¸©]Ô;×OÒOØ!×6Ò6°xÑ@Ô@À(ñô ð øð ¥/Ò1Ð1Ø&ð 5Ø)Ð)¨)Ñ4Ô4Ð4Ø$ YÐ/Ð/Ô/°1Ñ4Ð/Ð/Ñ/Ø×3Ò3Ø Ø&6°yÔ&AØÔ/ò'0ð 4ñ ô ð ð õ %Ð%K¨Ð%KÐ%KÐ%KÑLÔLÐLùøÝð 	ð 	ð 	Ý—’ØrØØñô ð õ Õ,¨TÔ-KÐ_hÐiÑiÔiÑjÔjÐjØ�øøøøð	øøøõ �(‰mŒmð 	"Ø�LŠL‰NŒN×ÒÑ!Ô!Ð!õ �(‰mŒmð 	"õ �;ÑÔ 1Ò$Ð$Ð$Ð&AÑ$Ô$Ð$ð 	×Ò˜DœL¨&Ñ1Ô1Ð1Ð1Ð1s   ÃS+V.Ö.
W>Ö8AW9×9W>r½  rã   )rG   rH   rI   r  r
   r]   r   r   rM   rS   rÈ  r¢  rš  rÏ  rÊ   r  r  s   @r@   r¿  r¿  `  sH  ø€ € € € € ðð ð %ð!Gð !Gà�c˜4 ¨Ô 1Ô2Ð2Ô3ð!Gð ð!Gð !Gð !Gð !GðFGð G #ð G¨sð Gð Gð Gð Gð Gð Gð*
F #ð 
Fð 
Fð 
Fð 
Fð
ð 
ð 
ð #'Ø$(Ø%)Ø!%ðd2ð d2à˜$”ðd2ð ˜D”>ðd2ð ˜T”Nð	d2ð
 ˜”ðd2ð d2ð d2ð d2ð d2ð d2ð d2ð d2rB   r¿  c                   ó�   ‡ — e Zd ZdZ	 	 d	dee         dedee         dee	e
eef         ee         f                  fˆ fd„Zd„ Zˆ xZS )
r!   ai  
    Breadth-First Pipeline Parallelism.
    See https://arxiv.org/abs/2211.05953 for details.
    Simliar to Interleaved 1F1B, Looped BFS supports multiple stages per rank.
    What is different is that when microbatches are ready for multiple local
    stages, Loops BFS will prioritizes the earlier stage, running all available
    microbatches at once.
    NrÁ   rš   r›   rž   c                 óÌ   •— t          ¦   «                              ||||¬¦  «         i | _        t          | j        ¦  «        D ]!}|                      |¦  «        }|| j        |<   Œ"d S )N)rÁ   rš   r›   rž   )rû   rª   r`   r‡   rq  Ú!_calculate_single_rank_operations)r>   rÁ   rš   r›   rž   rŽ   Úrank_opsr©   s          €r@   rª   zScheduleLoopedBFS.__init__¤  s…   ø€ õ 	‰Œ×ÒØØ)ØØ/ð	 	ñ 	
ô 	
ð 	
ð CEˆÔå˜$Ô,Ñ-Ô-ð 	1ð 	1ˆDØ×=Ò=¸dÑCÔCˆHØ(0ˆDÔ Ñ%Ð%ð	1ð 	1rB   c           	      ó  ‡— t          | j        ¦  «        }t          || j        |z  | j        ¦  «        }d„ t          |¦  «        D ¦   «         }|D ]5Š|                     ˆfd„t          | j        ¦  «        D ¦   «         ¦  «         Œ6d| j        dz
  |z
  z  }|                     d g|z  ¦  «         t          |¦  «        D ]BŠ|                     ˆfd„t          t          | j        ¦  «        ¦  «        D ¦   «         ¦  «         ŒC|S )Nc                 ó   — g | ]}d ‘ŒS rR   rK   ©re   r1  s     r@   rl   zGScheduleLoopedBFS._calculate_single_rank_operations.<locals>.<listcomp>Ã  ó   € Ð,GÐ,GÐ,G°a¨TÐ,GÐ,GÐ,GrB   c              3   óN   •K  — | ]}t          ‰t          j        |¦  «        V — Œ d S rR   )rM   r%   r:   ©re   r²   rN   s     €r@   rg   zFScheduleLoopedBFS._calculate_single_rank_operations.<locals>.<genexpr>Æ  sG   øè è € ð ð àõ ˜Õ%5Ô%=¸xÑHÔHðð ð ð ð ð rB   r&   r   c              3   óN   •K  — | ]}t          ‰t          j        |¦  «        V — Œ d S rR   )rM   r%   r=   rï  s     €r@   rg   zFScheduleLoopedBFS._calculate_single_rank_operations.<locals>.<genexpr>Ñ  sG   øè è € ð ð àõ ˜Õ%5Ô%CÀXÑNÔNðð ð ð ð ð rB   )r^   r„  r‡   rq  rÀ   r    Úreversed)r>   rŽ   Ún_local_stagesÚstage_indicesré  Úpost_warmup_opsrN   s         @r@   rè  z3ScheduleLoopedBFS._calculate_single_rank_operations»  sN  ø€ Ý˜Tœ\Ñ*Ô*ˆÝØ�$Ô$ ~Ñ5°tÔ7Iñ
ô 
ˆð -HÐ,G½5À¹;¼;Ð,GÑ,GÔ,Gˆà(ð 	ð 	ˆKØ�OŠOð ð ð ð å % dÔ&:Ñ ;Ô ;ðñ ô ñ ô ð ð ð ˜tÔ1°AÑ5¸Ñ<Ñ=ˆØ�Š˜˜ Ñ0Ñ1Ô1Ð1å# MÑ2Ô2ð 	ð 	ˆKØ�OŠOð ð ð ð å (­¨tÔ/CÑ)DÔ)DÑ EÔ Eðñ ô ñ ô ð ð ð ˆrB   )NN)rG   rH   rI   r  r   r   r]   r   r	   r   r
   rS   r   r   rª   rè  r  r  s   @r@   r!   r!   š  s¯   ø€ € € € € ðð ð '+ØIMð1ð 1àÐ'Ô(ð1ð ð1ð ˜(Ô#ð	1ð
 $ E¨$¨s°C¨x¬.¸%À¼*Ð*DÔ$EÔFð1ð 1ð 1ð 1ð 1ð 1ð.ð ð ð ð ð ð rB   r!   Fc
                 óê  — t          t          ¦  «        }
t          t          ¦  «        }t          t          ¦  «        }d„ t          |¦  «        D ¦   «         }| |z  d|dz
  |z
  z  z   ||z   z
  }|	r||z
  dz
  }||z   |z   }g }d}|	rt          nt          }t          |¦  «        D �]Q}||k     rl ||¦  «        }|
|         x}dz   |
|<   |                     t          |t          j        |¦  «        ¦  «         ||dz
  k    r| 	                    d g|z  ¦  «         Œu||cxk    r
||z   k     �rn nþ ||¦  «        }|
|         x}dz   |
|<   |                     t          |t          j        |¦  «        ¦  «          ||¦  «        }||         x}dz   ||<   |                     t          |||¦  «        ¦  «         |                     |¦  «         |	r]||z
  |k    rT |||         ¦  «        }||         x}dz   ||<   |                     t          |t          j
        |¦  «        ¦  «         |dz  }�Œ‡|	s|                     d ¦  «          ||¦  «        }||         x}dz   ||<   |                     t          |||¦  «        ¦  «         |                     |¦  «         |	r]||z
  |k    rT |||         ¦  «        }||         x}dz   ||<   |                     t          |t          j
        |¦  «        ¦  «         |dz  }�ŒS|	r||t          |¦  «        k     ri |||         ¦  «        }||         x}dz   ||<   |                     t          |t          j
        |¦  «        ¦  «         |dz  }|	r|t          |¦  «        k     °i|S )Nc                 ó   — g | ]}d ‘ŒS rR   rK   rì  s     r@   rl   z&_get_1f1b_rank_ops.<locals>.<listcomp>ë  s   € Ð(CÐ(CÐ(C°!¨Ð(CÐ(CÐ(CrB   r&   r   r   )r   r]   r‡   r;   r=   r®   rM   r%   r:   rÀ   r<   r^   )rò  rq  Ú
warmup_opsÚfwd_bwd_opsÚcooldown_opsrŽ   Úforward_stage_indexÚbackward_stage_indexÚnum_1f1b_microbatchesÚenable_zero_bubbleÚfwd_stage_mb_indexÚbwd_stage_mb_indexÚweight_stage_mb_indexré  rô  Ú	total_opsÚbackward_op_idsÚweight_op_countÚFULL_BACKWARD_OR_BACKWARD_INPUTrõ   Úfwd_stage_indexr²   r-  Úbwd_stage_indexr.  Úweight_stage_indexÚweight_mb_indexs                              r@   Ú_get_1f1b_rank_opsr	  Ø  s¨  € õ *5µSÑ)9Ô)9ÐÝ)4µSÑ)9Ô)9ÐÝ,7½Ñ,<Ô,<Ðð )DÐ(Cµu¸T±{´{Ð(CÑ(CÔ(C€Hð 	˜Ñ&¨¨m¸aÑ.?À$Ñ.FÑ)GÑGØ	�dÑ	ñ€Oð ð 3Ø'¨$Ñ.°Ñ2ˆà˜[Ñ(¨<Ñ7€Ià€OØ€Oð -Ð?�ˆµ-ð $õ �IÑÔð M%ñ M%ˆà�
Š?ˆ?Ø1Ð1°"Ñ5Ô5ˆOð /¨Ô?Ð?�Øñ3Ð˜Ñ/ð �OŠOÝ˜Õ)9Ô)AÀ8ÑLÔLñô ð ð �Z !‘^Ò#Ð#à—’  ¨Ñ 8Ñ9Ô9Ð9øà˜2Ð8Ð8Ò8Ð8 
¨[Ñ 8Ò8Ñ8Ð8Ð8Ð8Ø1Ð1°"Ñ5Ô5ˆOà 2°?Ô CÐC�Øñ3Ð˜Ñ/ð �OŠOÝ˜Õ)9Ô)AÀ<ÑPÔPñô ð ð 3Ð2°2Ñ6Ô6ˆOà 2°?Ô CÐC�Øñ3Ð˜Ñ/ð �OŠOÝ˜Ð)HÈ,ÑWÔWñô ð ð ×"Ò" 2Ñ&Ô&Ð&à!ð % b¨:¡oÐ9NÒ&NÐ&NØ%9Ð%9Ø# OÔ4ñ&ô &Ð"ð (=Ð=OÔ'PÐP�OØñ=Ð%Ð&8Ñ9ð —’ÝØ*Ý(Ô8Ø'ñô ñô ð ð   1Ñ$�ùð
 &ð &Ø—’ Ñ%Ô%Ð%à2Ð2°2Ñ6Ô6ˆOà 2°?Ô CÐC�Øñ3Ð˜Ñ/ð �OŠOÝ˜Ð)HÈ,ÑWÔWñô ð ð ×"Ò" 2Ñ&Ô&Ð&à!ð % b¨:¡oÐ9NÒ&NÐ&NØ%9Ð%9Ø# OÔ4ñ&ô &Ð"ð (=Ð=OÔ'PÐP�OØñ=Ð%Ð&8Ñ9ð —’ÝØ*Ý(Ô8Ø'ñô ñô ð ð   1Ñ$�ùà
ð 
 µ3°Ñ3GÔ3GÒ!GÐ!GØ1Ð1°/À/Ô2RÑSÔSÐà4Ð5GÔHÐHˆOØñ5ÐÐ0Ñ1ð 	�ŠÝØ"Õ$4Ô$DÀoñô ñ	
ô 	
ð 	
ð
 	˜1Ñˆð ð 
 µ3°Ñ3GÔ3GÒ!GÐ!Gð €OrB   c                   óò   ‡ — e Zd ZdZ	 	 	 	 ddee         dedee         dee	e
df                  deeee
f                  d	eeeeef         e	e         f                  fˆ fd
„Zdeee                  fd„Zˆ xZS )r    a…  
    The Interleaved 1F1B schedule.
    See https://arxiv.org/pdf/2104.04473 for details.
    Will perform one forward and one backward on the microbatches in steady
    state and supports multiple stages per rank. When microbatches are ready for
    multiple local stages, Interleaved 1F1B prioritizes the earlier microbatch
    (also called "depth first").

    This schedule is mostly similar to the original paper.
    It differs by being relaxing the requirement of num_microbatch % pp_size == 0.
    Using the flex_pp schedule, we will have num_rounds = max(1, n_microbatches // pp_group_size) and
    it works as long as n_microbatches % num_rounds is 0. As a few examples, support

    1. pp_group_size = 4, n_microbatches = 10. We will have num_rounds = 2 and n_microbatches % 2 is 0.
    2. pp_group_size = 4, n_microbatches = 3. We will have num_rounds = 1 and n_microbatches % 1 is 0.
    NrÁ   rš   r›   rœ   .r�   rž   c                 óê  •— |d         j         | _        t          ¦   «                              ||||||¬¦  «         t	          |¦  «        | _        |d         j        | _        t          d|| j        z  ¦  «        | _	        || j	        z  | _
        || j	        z  dk    rt          d| j	        › d|› d�¦  «        ‚i | _        t          | j        ¦  «        D ]!}|                      |¦  «        }|| j        |<   Œ"d S )Nr   ©rÁ   rš   r›   rœ   r�   rž   r   z_Interleaved 1F1B requires the number of microbatches to be a multiple of the number of rounds (ú), but got ú.)r…  rq  rû   rª   r^   rò  r†  rŽ   rv   Únumber_of_roundsÚmicrobatches_per_roundr×   r`   r‡   rè  ©
r>   rÁ   rš   r›   rœ   r�   rž   rŽ   ré  r©   s
            €r@   rª   z ScheduleInterleaved1F1B.__init__s  s.  ø€ ð $ AœYÔ1ˆÔÝ‰Œ×ÒØØ)ØØ+Ø/Ø/ð 	ñ 	
ô 	
ð 	
õ " &™kœkˆÔØ˜1”IÔ(ˆŒ	Ý # A ~¸Ô9KÑ'KÑ LÔ LˆÔØ&4¸Ô8MÑ&MˆÔ#Ø˜DÔ1Ñ1°QÒ6Ð6Ýð-Ø59Ô5Jð-ð -à)ð-ð -ð -ñô ð ð CEˆÔÝ˜$Ô,Ñ-Ô-ð 	1ð 	1ˆDØ×=Ò=¸dÑCÔCˆHØ(0ˆDÔ Ñ%Ð%ð	1ð 	1rB   rb   c           
      ó  ‡ ‡‡	— ˆ fd„} |‰¦  «        Š	‰ j         ‰ j        z  }|‰	z
  }||z
  }‰	|z   |z   }t                               d‰‰	|||¦  «         ˆˆ fd„}ˆˆ ˆ	fd„}t	          ‰ j         ‰ j        ‰	||‰||¦  «        S )Nc                 óŒ   •— ‰j         dz
  ‰j        z  }d}||‰j        dz
  | z
  z  z   }t          |‰j        ‰j         z  ¦  «        S )Nr   r&   ©rò  r  rq  r+  r    ©rŽ   Úwarmups_ops_last_stageÚmultiply_factorr÷  r>   s       €r@   Úget_rank_warmup_opszVScheduleInterleaved1F1B._calculate_single_rank_operations.<locals>.get_rank_warmup_ops˜  óc   ø€ ð Ô# aÑ'ØÔ+ñ&,Ð"ð  ˆOØ/°/ØÔ# aÑ'¨4Ñ/ñ3ñ ˆJõ
 �z 4Ô#7¸$Ô:MÑ#MÑNÔNÐNrB   ú=rank %s, warmup_ops %s, 1f1b %s, cooldown_ops %s total_ops %sc                 óB   •— | ‰j         z  ‰j        z  }|‰j        z  ‰z   S rR   ©r  rò  rq  ©rÑ   Úlocal_indexrŽ   r>   s     €€r@   rú  zVScheduleInterleaved1F1B._calculate_single_rank_operations.<locals>.forward_stage_index¹  ó+   ø€ à 4Ô#>Ñ>À$ÔBUÑUˆKØ $Ô"4Ñ4¸Ñ<Ð<rB   c                 ó^   •— ‰j         dz
  | ‰z
  ‰j        z  ‰j         z  z
  }|‰j        z  ‰z   S ©Nr   ©rò  r  rq  ©rÑ   r  rŽ   r>   r÷  s     €€€r@   rû  zWScheduleInterleaved1F1B._calculate_single_rank_operations.<locals>.backward_stage_index¾  óK   ø€ àÔ#Øñà˜:Ñ%¨$Ô*EÑEØÔ%ñ&ñ&ð ð   $Ô"4Ñ4¸Ñ<Ð<rB   ©rò  r    r§   ré   r	  rq  )
r>   rŽ   r  Úmicrobatch_opsrø  rù  r  rú  rû  r÷  s
   ``       @r@   rè  z9ScheduleInterleaved1F1B._calculate_single_rank_operations—  s  øøø€ ð	Oð 	Oð 	Oð 	Oð 	Oð )Ð(¨Ñ.Ô.ˆ
ØÔ,¨tÔ/CÑCˆà$ zÑ1ˆà%¨Ñ3ˆà Ñ,¨|Ñ;ˆ	å�ŠØKØØØØØñ	
ô 	
ð 	
ð	=ð 	=ð 	=ð 	=ð 	=ð 	=ð
	=ð 	=ð 	=ð 	=ð 	=ð 	=ð 	=õ "ØÔØÔØØØØØØ ñ	
ô 	
ð 		
rB   rã   ©rG   rH   rI   r  r   r   r]   r   r	   r   r   r
   rS   r   r   rª   rM   rè  r  r  s   @r@   r    r    a  sþ   ø€ € € € € ðð ð* '+ØAEØBFØIMð"1ð "1àÐ'Ô(ð"1ð ð"1ð ˜(Ô#ð	"1ð
 " %¨¸Ð(<Ô"=Ô>ð"1ð $ D¨¨oÐ)=Ô$>Ô?ð"1ð $ E¨$¨s°C¨x¬.¸%À¼*Ð*DÔ$EÔFð"1ð "1ð "1ð "1ð "1ð "1ðH9
¸¸hÀwÔ>OÔ9Pð 9
ð 9
ð 9
ð 9
ð 9
ð 9
ð 9
ð 9
rB   r    c                   óø   ‡ — e Zd ZdZ	 	 	 	 ddee         dedee         dee	e
df                  deeee
f                  d	eeeeef         e	e         f                  fˆ fd
„Zdeee                  fd„Zd„ Zˆ xZS )r"   aw  
    The Interleaved Zero Bubble schedule.
    See https://arxiv.org/pdf/2401.10241 for details.
    Will perform one forward and one backward on inputs for the microbatches in steady
    state and supports multiple stages per rank. Uses the backward for weights to fill in
    the pipeline bubble.

    In particular this is implementing the ZB1P schedule in the paper.
    NrÁ   rš   r›   rœ   .r�   rž   c                 ó8  •— |d         j         | _        t          ¦   «                              ||||||¬¦  «         t	          |¦  «        | _        |d         j        | _        t          d|| j        z  ¦  «        | _	        || j	        z  | _
        || j	        z  dk    rt          d| j	        › d|› d�¦  «        ‚i | _        t          | j        ¦  «        D ]!}|                      |¦  «        }|| j        |<   Œ"|                      | j        | j        z  ¦  «        | _        d S )Nr   r  r   zZZero bubble requires the number of microbatches to be a multiple of the number of rounds (r  r  )r…  rq  rû   rª   r^   rò  r†  rŽ   rv   r  r  r×   r`   r‡   rè  Ú_add_bubbles_to_actionsr  s
            €r@   rª   z&ScheduleInterleavedZeroBubble.__init__Þ  sR  ø€ ð $ AœYÔ1ˆÔÝ‰Œ×ÒØØ)ØØ+Ø/Ø/ð 	ñ 	
ô 	
ð 	
õ " &™kœkˆÔØ˜1”IÔ(ˆŒ	Ý # A ~¸Ô9KÑ'KÑ LÔ LˆÔØ&4¸Ô8MÑ&MˆÔ#Ø˜DÔ1Ñ1°QÒ6Ð6Ýð-Ø59Ô5Jð-ð -à)ð-ð -ð -ñô ð ð CEˆÔÝ˜$Ô,Ñ-Ô-ð 	1ð 	1ˆDØ×=Ò=¸dÑCÔCˆHØ(0ˆDÔ Ñ%Ð%ð
 #×:Ò:ØÔ $Ô"4Ñ4ñ
ô 
ˆÔÐÐrB   rb   c                 ó  ‡ ‡‡
— ˆ fd„} |‰¦  «        Š
‰ j         ‰ j        z  }|‰
z
  }||z
  }‰
|z   |z   }t                               d‰‰
|||¦  «         ˆˆ fd„}ˆˆ ˆ
fd„}‰}	t	          ‰ j         ‰ j        ‰
||‰|||	d¬¦
  «
        S )Nc                 óŒ   •— ‰j         dz
  ‰j        z  }d}||‰j        dz
  | z
  z  z   }t          |‰j        ‰j         z  ¦  «        S r!  r  r  s       €r@   r  z\ScheduleInterleavedZeroBubble._calculate_single_rank_operations.<locals>.get_rank_warmup_ops
  r  rB   r  c                 óB   •— | ‰j         z  ‰j        z  }|‰j        z  ‰z   S rR   r  r  s     €€r@   rú  z\ScheduleInterleavedZeroBubble._calculate_single_rank_operations.<locals>.forward_stage_index,  r  rB   c                 ó^   •— ‰j         dz
  | ‰z
  ‰j        z  ‰j         z  z
  }|‰j        z  ‰z   S r!  r"  r#  s     €€€r@   rû  z]ScheduleInterleavedZeroBubble._calculate_single_rank_operations.<locals>.backward_stage_index1  r$  rB   T)rý  r%  )r>   rŽ   r  r&  rø  rù  r  rú  rû  rü  r÷  s   ``        @r@   rè  z?ScheduleInterleavedZeroBubble._calculate_single_rank_operations	  s  øøø€ ð	Oð 	Oð 	Oð 	Oð 	Oð )Ð(¨Ñ.Ô.ˆ
ØÔ,¨tÔ/CÑCˆà$ zÑ1ˆà%¨Ñ3ˆà Ñ,¨|Ñ;ˆ	å�ŠØKØØØØØñ	
ô 	
ð 	
ð	=ð 	=ð 	=ð 	=ð 	=ð 	=ð
	=ð 	=ð 	=ð 	=ð 	=ð 	=ð 	=ð !%Ðå!ØÔØÔØØØØØØ Ø!Ø#ð
ñ 
ô 
ð 	
rB   c                 ób  — | j         }d„ }t          ¦   «         }i }i }i }d}t          | j        ¦  «        D ]}	g ||	<   d||	<   d||	<   Œ	 d}
t          ¦   «         }t          | j        ¦  «        D �]}	||	         }|t	          ||	         ¦  «        k    rŒ%d}
||	         |         �¥||	         |         }|€J ‚|\  }}} ||||||¦  «        sR||	                              ||	         |         ¦  «         |�|                     |||f¦  «         ||	xx         dz  cc<   Œ®||	                              d ¦  «         ||	xx         dz  cc<   ŒÚ||	xx         dz  cc<   ||	                              d ¦  «         �Œ|                     |¦  «         |
rn�ŒE|dk    rt           	                    d||¦  «         |S )Nc                 ó´   — |t           j        k    r| dk    r| dz
  ||f|vrdS n4|t           j        k    r$| |dz
  k    r| t           j        |f|vS | dz   ||f|vS dS )Nr   r   TF)r%   r:   r=   )r¯   rõ   Ú
microbatchÚnum_stages_globalÚseen_opss        r@   Úneed_bubblezJScheduleInterleavedZeroBubble._add_bubbles_to_actions.<locals>.need_bubbleL  s‡   € ØÕ%Ô-Ò-Ð-Ø˜A’:�: 5¨1¡9¨b°*Ð"=ÀXÐ"MÐ"MØ˜4øØÕ'Ô5Ò5Ð5ØÐ-°Ñ1Ò1Ð1Ø!Õ#3Ô#;¸ZÐHÐPXÐXÐXØ ™	 2 zÐ2¸(ÐBÐBØ�5rB   r   TFr   z?Non zero bubbles added: total_bubbles_added=%s bubbles_added=%s)
r`   r=  r‡   rq  r^   r®   r>  Úupdater§   r‰  )r>   r2  rf   r4  r3  ÚresultÚnext_pointerÚbubbles_addedÚtotal_bubbles_addedrŽ   Úshould_stopÚtemp_seen_opsÚ	timestampÚtemp_actionrN   rõ   r1  s                    r@   r*  z5ScheduleInterleavedZeroBubble._add_bubbles_to_actionsI  sF  € ØÔ%ˆð	ð 	ð 	õ <?¹5¼5ˆØ57ˆØ')ˆØ(*ˆØÐå˜$Ô,Ñ-Ô-ð 	$ð 	$ˆDØˆF�4‰LØ!"ˆL˜ÑØ"#ˆM˜$ÑÐð 	ØˆKåDGÁEÄEˆMå˜dÔ0Ñ1Ô1ð .ñ .�Ø(¨Ô.�	Ø¥ G¨D¤MÑ 2Ô 2Ò2Ð2Øà#�à˜4”= Ô+Ð7Ø")¨$¤-°	Ô":�KØ&Ð2Ð2Ð2Ø2=Ñ/�K  ZØ&˜;Ø# R¨Ð5FÈñô ð 	1ð ˜tœ×+Ò+¨G°D¬M¸)Ô,DÑEÔEÐEØ%Ð1Ø)×-Ò-¨{¸BÀ
Ð.KÑLÔLÐLØ$ TÐ*Ð*Ô*¨aÑ/Ð*Ð*Ñ*Ð*à˜tœ×+Ò+¨DÑ1Ô1Ð1Ø% dÐ+Ð+Ô+¨qÑ0Ð+Ð+Ñ+Ð+à  Ð&Ð&Ô&¨!Ñ+Ð&Ð&Ñ&Ø˜4”L×'Ò'¨Ñ-Ô-Ð-Ñ-à�OŠO˜MÑ*Ô*Ð*Øð ØñA 	ðD  Ò"Ð"Ý�NŠNØQØ#Øñô ð ð
 ˆrB   rã   )rG   rH   rI   r  r   r   r]   r   r	   r   r   r
   rS   r   r   rª   rM   rè  r*  r  r  s   @r@   r"   r"   Ó  s  ø€ € € € € ðð ð '+ØAEØBFØIMð)
ð )
àÐ'Ô(ð)
ð ð)
ð ˜(Ô#ð	)
ð
 " %¨¸Ð(<Ô"=Ô>ð)
ð $ D¨¨oÐ)=Ô$>Ô?ð)
ð $ E¨$¨s°C¨x¬.¸%À¼*Ð*DÔ$EÔFð)
ð )
ð )
ð )
ð )
ð )
ðV>
¸¸hÀwÔ>OÔ9Pð >
ð >
ð >
ð >
ð@@ð @ð @ð @ð @ð @ð @rB   r"   c                   ó  ‡ — e Zd ZdZ	 	 	 	 	 ddee         dedee         dee	e
df                  deeee
f                  d	eeeeef         e	e         f                  d
eeeef                  fˆ fd„Zdeee                  fd„Zˆ xZS )r#   a£  
    The Zero Bubble schedule (ZBV variant).
    See https://arxiv.org/pdf/2401.10241 Section 6 for details.

    This schedules requires exactly two stages per rank.

    This schedule will perform one forward and one backward on inputs for the microbatches in steady
    state and supports multiple stages per rank. Uses backward with respect to weights to fill in
    the pipeline bubble.

    This ZB-V schedule would have the "zero bubble" property only if time forward == time backward input == time backward weights.
    In practice, this is not likely true for real models so alternatively
    a greedy scheduler could be implemented for unequal/unbalanced time.
    NrÁ   rš   r›   rœ   .r�   rž   r  c           	      ó¬  •— |d         j         | _        t          ¦   «                              |||||||¬¦  «         t	          |¦  «        | _        | j        dk    rt          d| j        › d�¦  «        ‚|d         j        | _        |d         j	        | _	        i | _
        t          | j        ¦  «        D ]!}|                      |¦  «        }	|	| j
        |<   Œ"d S )Nr   )rÁ   rš   r›   rœ   r�   rž   r  r&   z0ZBV requires exactly 2 stages per rank, but got r  )r…  rq  rû   rª   r^   rò  r×   r†  rŽ   rý   r`   r‡   rè  )r>   rÁ   rš   r›   rœ   r�   rž   r  rŽ   ré  r©   s             €r@   rª   zScheduleZBVZeroBubble.__init__œ  s  ø€ ð $ AœYÔ1ˆÔÝ‰Œ×ÒØØ)ØØ+Ø/Ø/Ø&?ð 	ñ 	
ô 	
ð 	
õ " &™kœkˆÔØÔ !Ò#Ð#Ýð*ØÔ&ð*ð *ð *ñô ð ð
 ˜1”IÔ(ˆŒ	Ø  œ)Ô.ˆŒð
 CEˆÔÝ˜$Ô,Ñ-Ô-ð 	1ð 	1ˆDØ×=Ò=¸dÑCÔCˆHØ(0ˆDÔ Ñ%Ð%ð	1ð 	1rB   rb   c                 óö  ‡ — t          d‰ j        z  dz
  ‰ j        ¦  «        }d„ t          |¦  «        D ¦   «         }d\  }}}}d‰ j        |z
  z  dz
  }|}	‰ j        dz
  |z
  }
t          |¦  «        D ]1}|                     t          |	t          |¬¦  «        ¦  «         |dz  }Œ2|}t          |¦  «        D ]`}|                     t          |
t          |¬¦  «        ¦  «         |dz  }|                     t          |	t          |¬¦  «        ¦  «         |dz  }Œa‰ j        |z
  }t          |¦  «        D ]Š}|                     t          |
t          |¬¦  «        ¦  «         |dz  }|                     t          |
t          |¬¦  «        ¦  «         |                     t          |
t          |¬¦  «        ¦  «         |dz  }Œ‹||k     s||k     �r$||k     r/|                     t          |	t          |¬¦  «        ¦  «         |dz  }|                     t          |	t          |¬¦  «        ¦  «         |                     t          |	t          |¬¦  «        ¦  «         |dz  }|                     t          |
t          |¬¦  «        ¦  «         |dz  }|                     t          |
t          |¬¦  «        ¦  «         |                     t          |
t          |¬¦  «        ¦  «         |dz  }||k     �°||k     �°$||}}|}t          |¦  «        D ]`}|                     t          |	t          |¬¦  «        ¦  «         |dz  }|                     t          |
t          |¬¦  «        ¦  «         |dz  }Œa‰ j        |z
  }t          |¦  «        D ]`}|                     t          |	t          |¬¦  «        ¦  «         |dz  }|                     t          |	t          |¬¦  «        ¦  «         |dz  }Œa||k     r5|                     t          |
t          |¬¦  «        ¦  «         |dz  }||k     °5||k     r5|                     t          |	t          |¬¦  «        ¦  «         |dz  }||k     °5||k    r||k    sJ ‚||k    r||k    sJ ‚ˆ fd„|D ¦   «         }|S )Nr&   r   c                 ó   — g | ]}d ‘ŒS rR   rK   rì  s     r@   rl   zKScheduleZBVZeroBubble._calculate_single_rank_operations.<locals>.<listcomp>Æ  rí  rB   )r   r   r   r   )rO   rP   c                 óJ   •— g | ]}|�|j         �|j         ‰j        k     r|nd ‘Œ S rR   )rP   r    )re   rE   r>   s     €r@   rl   zKScheduleZBVZeroBubble._calculate_single_rank_operations.<locals>.<listcomp>,	  sT   ø€ ð 	
ð 	
ð 	
ð ð Ð%ØÔ+Ð7ØÔ+¨dÔ.BÒBÐBð �ð ð	
ð 	
ð 	
rB   )
rv   rq  r    r‡   rý   r®   rM   r0   r1   r2   )r>   rŽ   Ún_microré  Úf0_cntÚf1_cntÚb0_cntÚb1_cntÚ	warmup_n1Ústage_id_chunk0Ústage_id_chunk1r1  Ú	warmup_n2Ú	warmup_n3Úw0_cntÚw1_cntÚcooldown_n1Úcooldown_n2s   `                 r@   rè  z7ScheduleZBVZeroBubble._calculate_single_rank_operationsÂ  sn  ø€ õ �a˜$Ô,Ñ,¨qÑ0°$Ô2FÑGÔGˆØ,GÐ,G½5À¹;¼;Ð,GÑ,GÔ,Gˆð *4Ñ&ˆ�˜ à˜Ô+¨dÑ2Ñ3°aÑ7ˆ	ØˆØœ/¨AÑ-°Ñ4ˆå�yÑ!Ô!ð 	ð 	ˆAØ�OŠOÝ˜½!ÈfÐUÑUÔUñô ð ð �a‰KˆFˆFØˆ	Ý�yÑ!Ô!ð 	ð 	ˆAØ�OŠOÝ˜½!ÈfÐUÑUÔUñô ð ð �a‰KˆFØ�OŠOÝ˜½!ÈfÐUÑUÔUñô ð ð �a‰KˆFˆFØÔ&¨Ñ-ˆ	Ý�yÑ!Ô!ð 	ð 	ˆAØ�OŠOÝ˜½!ÈfÐUÑUÔUñô ð ð �a‰KˆFØ�OŠOÝ˜½!ÈfÐUÑUÔUñô ð ð �OŠOÝ˜½!ÈfÐUÑUÔUñô ð ð �a‰KˆFˆFà�vŠoˆo ¨'Ò!1Ñ!1Ø˜ÒÐØ—’ÝØ'½!Èfðñ ô ñô ð ð
 ˜!‘�Ø�OŠOÝ˜½!ÈfÐUÑUÔUñô ð ð �OŠOÝ˜½!ÈfÐUÑUÔUñô ð ð �a‰KˆFà�OŠOÝ˜½!ÈfÐUÑUÔUñô ð ð �a‰KˆFØ�OŠOÝ˜½!ÈfÐUÑUÔUñô ð ð �OŠOÝ˜½!ÈfÐUÑUÔUñô ð ð �a‰KˆFð5 �vŠo‰o ¨'Ò!1Ñ!1ð8   �ˆØˆÝ�{Ñ#Ô#ð 	ð 	ˆAØ�OŠOÝ˜½!ÈfÐUÑUÔUñô ð ð �a‰KˆFØ�OŠOÝ˜½!ÈfÐUÑUÔUñô ð ð �a‰KˆFˆFØÔ(¨4Ñ/ˆÝ�{Ñ#Ô#ð 	ð 	ˆAØ�OŠOÝ˜½!ÈfÐUÑUÔUñô ð ð �a‰KˆFØ�OŠOÝ˜½!ÈfÐUÑUÔUñô ð ð �a‰KˆFˆFØ�vŠoˆoØ�OŠOÝ˜½!ÈfÐUÑUÔUñô ð ð �a‰KˆFð	 �vŠoˆoð
 �vŠoˆoØ�OŠOÝ˜½!ÈfÐUÑUÔUñô ð ð �a‰KˆFð	 �vŠoˆoð ˜ÒÐ F¨fÒ$4Ð$4Ð$4Ð4Ø˜ÒÐ F¨fÒ$4Ð$4Ð$4Ð4ð	
ð 	
ð 	
ð 	
ð #ð	
ñ 	
ô 	
ˆð ˆrB   )NNNNNr'  r  s   @r@   r#   r#   Œ  s!  ø€ € € € € ðð ð& '+ØAEØBFØIMØ>Bð$1ð $1àÐ'Ô(ð$1ð ð$1ð ˜(Ô#ð	$1ð
 " %¨¸Ð(<Ô"=Ô>ð$1ð $ D¨¨oÐ)=Ô$>Ô?ð$1ð $ E¨$¨s°C¨x¬.¸%À¼*Ð*DÔ$EÔFð$1ð $,¨D°°c°¬NÔ#;ð$1ð $1ð $1ð $1ð $1ð $1ðLt¸¸hÀwÔ>OÔ9Pð tð tð tð tð tð tð tð trB   r#   Úschedule_namec           	      óX  — t           t          t          t          t          t
          t          t          dœ}d„ |                     ¦   «         D ¦   «         }|  	                    ¦   «         }||vr4t          d| › dt          |                     ¦   «         ¦  «        › �¦  «        ‚|||                  S )z–
    Maps a schedule name (case insensitive) to its corresponding class object.

    Args:
        schedule_name (str): The name of the schedule.
    )Ú1F1BÚInterleaved1F1BÚGPipeÚ	LoopedBFSÚInterleavedZeroBubbler   r   ÚZBVZeroBubblec                 ó8   — i | ]}|                      ¦   «         |“ŒS rK   )Úlower)re   Úks     r@   r\  z&get_schedule_class.<locals>.<dictcomp>J	  s"   € Ð@Ð@Ð@ q�a—g’g‘i”i Ð@Ð@Ð@rB   zUnknown schedule name 'z'. The valid options are )r   r    r   r!   r"   r   r   r#   r­  rZ  r×   rŠ   )rQ  Úschedule_mapÚlowercase_keysÚlowercase_schedule_names       r@   r   r   9	  s´   € õ Ý2ÝÝ&Ý!>Ý"8Ý!6Ý.ð	ð 	€Lð AÐ@¨L×,=Ò,=Ñ,?Ô,?Ð@Ñ@Ô@€NØ+×1Ò1Ñ3Ô3ÐØ nÐ4Ð4ÝØi mÐiÐiÍdÐS_×SdÒSdÑSfÔSfÑNgÔNgÐiÐiñ
ô 
ð 	
ð ˜Ð'>Ô?Ô@Ð@rB   c                 ó²  ‡ ‡‡‡	‡
— ˆ fd„t          ‰ ¦  «        D ¦   «         Š d„ t          ‰ ¦  «        D ¦   «         Š
d„ ‰
D ¦   «         Š	dt          dt          t                   fˆ	ˆ
fd„}dt          t                   dt          fˆ	ˆˆfd„}‰ �rÍd	}t          ‰ ¦  «        D ]m}t          ‰ |         ¦  «        d
k    rŒ‰ |         d
         } ||¦  «        r,|� |||¦  «         ‰ |                              d
¦  «         d}Œa ||d¦  «         Œnt          ‰ d¬¦  «        D ]}t          ‰ |         ¦  «        d
k    r‰ |= Œt          ‰ ¦  «        D ]‡}t          ‰ |         ¦  «        d
k    rŒ‰
|         d         �Œ+‰ |         d
         } ||¦  «        rC|�&|‰
|         d<   ‰	|                              |¦  «         ‰ |                              d
¦  «         Œˆt          ‰ d¬¦  «        D ]}t          ‰ |         ¦  «        d
k    r‰ |= Œ|sRt          dt          ‰
¦  «        ¦  «         ‰ D ]#}t          d|›d‰ |         d
         › �¦  «         Œ$t          d¦  «        ‚‰ �°Í‰
S )aÂ  This function dry-run simulates the actions in the schedule from the perspective of all ranks, and flags
    any deadlocks caused by missing or misordered communications.  It also simulates any bubbles in time where a rank
    can not execute any action due to waiting for unmet dependencies.  The total number of simulator steps can be used
    as a metric for unit tests involving IR optimization passes as reordering and merging of IR can reduce the number
    of simulated steps.

    The simulation is not high-fidelity and does not model overlapping of compute and communication, or cuda streams.
    Future work may be to enhance this and model the compute time, comms overlap, and even memory.
    c                 ó6   •— i | ]}|d „ ‰|         D ¦   «         “ŒS )c                 ó   — g | ]}|®|‘ŒS rR   rK   )re   rA  s     r@   rl   z6_simulate_comms_compute.<locals>.<dictcomp>.<listcomp>`	  s   € Ð@Ð@Ð@�Q°!°-ˆq°-°-°-rB   rK   )re   rŽ   r`   s     €r@   r\  z+_simulate_comms_compute.<locals>.<dictcomp>_	  s?   ø€ ð ð ð àð 	Ð@Ð@˜.¨Ô.Ð@Ñ@Ô@ðð ð rB   c                 ó   — i | ]}|g “ŒS rK   rK   r[  s     r@   r\  z+_simulate_comms_compute.<locals>.<dictcomp>c	  s'   € ð 2ð 2ð 2Øˆˆbð2ð 2ð 2rB   c                 ó,   — i | ]}|t          ¦   «         “ŒS rK   r^  r[  s     r@   r\  z+_simulate_comms_compute.<locals>.<dictcomp>g	  s   € Ð.QÐ.QÐ.Q¸t¨tµS±U´UÐ.QÐ.QÐ.QrB   rŽ   rE   c                 ó|   •— ‰|                                |¦  «         |�‰|                               |¦  «         d S d S rR   )r®   r>  )rŽ   rE   Ú_prev_ops_rankÚ	_schedules     €€r@   Úadd_to_schedulez0_simulate_comms_compute.<locals>.add_to_schedulei	  sH   ø€ Ø�$Œ×Ò˜vÑ&Ô&Ð&ØÐØ˜4Ô ×$Ò$ VÑ,Ô,Ð,Ð,Ð,ð ÐrB   rb   c                 ó®  •— | €dS | j         }‰ ‰
|¦  «                 }| j        t          k    rZ| j         dk    rdS t          | j         t          | j        ¦  «        |v rdS t          | j         dz
  t          | j        ¦  «        |v rdS dS | j        t          t          fv r„| j         ‰	dz
  k    rdS t          | j         t          | j        ¦  «        |v rdS t          | j         dz   t          | j        ¦  «        |v rdS t          | j         dz   t          | j        ¦  «        |v rdS dS | j        t          k    rdS | j        t          k    r$t          | j         t          | j        ¦  «        }||v S | j        t          k    r3|dz
  }t          |t          | j        ¦  «        }|‰ ‰
|¦  «                 v S | j        t          k    rHt          | j         t          | j        ¦  «        }t          | j         t          | j        ¦  «        }||v p||v S | j        t          k    r3|dz   }t          |t          | j        ¦  «        }|‰ ‰
|¦  «                 v S t          d| › �¦  «        ‚)NTr   r   FzUnsupported action type )rN   rO   r0   rM   r6   rP   r;   r=   r8   r<   r5   r7   r×   )rE   rb  Úprev_opsÚ
expected_fÚpeer_stage_idxÚexpected_sendÚ
expected_bÚexpected_bwre  rý   rX  s           €€€r@   rk  z3_simulate_comms_compute.<locals>._ready_to_schedulen	  s‰  ø€ Øˆ>Ø�4àÔ&ˆ	Ø! - -°	Ñ":Ô":Ô;ˆØÔ"¥aÒ'Ð'ØÔ! QÒ&Ð&Ø�tå˜Ô*­F°FÔ4KÑLÔLÐPXÐXÐXà�tå˜Ô*¨QÑ.µ°6Ô3JÑKÔKÈxÐWÐWà�tØ�5ØÔ$­½Ð(GÐGÐGØÔ! Z°!¡^Ò3Ð3Ø�tÝ�vÔ)­6°6Ô3JÑKÔKÈxÐWÐWØ�tå˜Ô*¨QÑ.µÀÔ@WÑXÔXØðð ð �tå˜Ô*¨QÑ.µ¸vÔ?VÑWÔWØðð ð �tØ�5ØÔ$­Ò7Ð7Ø�4ØÔ$­Ò.Ð.Ý  Ô!3µQ¸Ô8OÑPÔPˆJØ Ð)Ð)ØÔ$­Ò.Ð.Ø&¨™]ˆNÝ# NµF¸FÔ<SÑTÔTˆMØ  N°=°=ÀÑ3PÔ3PÔ$QÐQÐQØÔ$­Ò.Ð.Ý ØÔ"¥N°FÔ4Kñô ˆJõ "ØÔ"¥M°6Ô3Jñô ˆKð  Ð)ÐD¨[¸HÐ-DÐDØÔ$­Ò.Ð.Ø&¨™]ˆNÝ# NµF¸FÔ<SÑTÔTˆMØ  N°=°=ÀÑ3PÔ3PÔ$QÐQÐQåÐ@¸Ð@Ð@ÑAÔAÐArB   Fr   NT)ÚreverserÖ  zWIP comms schedule:
rl  z next action= zSchedule is not progressing)r‰   r]   r   rM   rm  r^   rì   r>  rÞ  r—   r×   )r`   rX  rý   rg  rk  ro  rŽ   rE   rj   re  rf  s   ```      @@r@   rÎ  rÎ  S	  sJ  øøøøø€ ðð ð ð å˜>Ñ*Ô*ðñ ô €Nð2ð 2Ý# NÑ3Ô3ð2ñ 2ô 2€Ið /RÐ.QÀyÐ.QÑ.QÔ.Q€Nð-�cð -­8µGÔ+<ð -ð -ð -ð -ð -ð -ð -ð
8B¥8­GÔ#4ð 8B½ð 8Bð 8Bð 8Bð 8Bð 8Bð 8Bð 8Bð 8Bðt ñ +<ØˆÝ˜>Ñ*Ô*ð 	,ð 	,ˆDÝ�> $Ô'Ñ(Ô(¨AÒ-Ð-Øà# DÔ)¨!Ô,ˆFØ!Ð! &Ñ)Ô)ð ,ØÐ%Ø#�O D¨&Ñ1Ô1Ð1Ø˜tÔ$×(Ò(¨Ñ+Ô+Ð+Ø��à�  dÑ+Ô+Ð+Ð+å˜°Ð5Ñ5Ô5ð 	&ð 	&ˆAÝ�> !Ô$Ñ%Ô%¨Ò*Ð*Ø" 1Ð%øõ ˜>Ñ*Ô*ð 	,ð 	,ˆDÝ�> $Ô'Ñ(Ô(¨AÒ-Ð-Øà˜Œ˜rÔ"Ð.Øà# DÔ)¨!Ô,ˆFØ!Ð! &Ñ)Ô)ð ,ØÐ%Ø*0�I˜d”O BÑ'Ø" 4Ô(×,Ò,¨VÑ4Ô4Ð4Ø˜tÔ$×(Ò(¨Ñ+Ô+Ð+øå˜°Ð5Ñ5Ô5ð 	&ð 	&ˆAÝ�> !Ô$Ñ%Ô%¨Ò*Ð*Ø" 1Ð%øàð 	<ÝÐ)Õ+AÀ)Ñ+LÔ+LÑMÔMÐMØ&ð Ið I�ÝÐG˜ÐGÐG¨n¸TÔ.BÀ1Ô.EÐGÐGÑHÔHÐHÐHÝÐ:Ñ;Ô;Ð;ðW ñ +<ðZ ÐrB   c                 ó‚  — g }t          | ¦  «        D ]g}t          | |         ¦  «        D ]O\  }}|€Œ|                     t          |¦  «        |j        t
          t          t          fv rdndd|||ddœ¦  «         ŒPŒhddl}t          |d¦  «        5 }| 
                    d	|i|¦  «         ddd¦  «         dS # 1 swxY w Y   dS )
aï  
    This function dumps a schedule IR into a chrometrace format so it can be visualized.

    It is currently very basic and only serves as a graphical alternative to dumping the schedule IR as text.

    As future work we may extend this to include more accurate heuristics for durations, or let users input durations,
    add 'flow events' to let the UI show the connection between sends and recvs, and model cuda streams for comm/compute
    as separate streams on the chrometrace view.
    NÚcomputationÚcommunicationÚXr   )rÓ   ÚcatÚphÚpidÚtidÚtsÚdurr   r�  ÚtraceEvents)r‰   r�   r®   rS   rO   r0   r9   r2   Újsonr“  Údump)Úscheduler˜  ÚeventsrŽ   ÚtimesteprE   r{  Úfs           r@   Ú_dump_chrometracer�  Ø	  s?  € ð €FÝ�xÑ Ô ð ð ˆÝ )¨(°4¬.Ñ 9Ô 9ð 	ð 	ÑˆH�fØˆ~ØØ�MŠMå ™KœKð "Ô2µq½!½Q°iÐ?Ð?ð &˜à,àØØØ"Øðð ñô ð ð ð	ð$ €K€K€Kå	ˆh˜Ñ	Ô	ð . Ø�	Š	�= &Ð)¨1Ñ-Ô-Ð-ð.ð .ð .ñ .ô .ð .ð .ð .ð .ð .ð .ð .øøøð .ð .ð .ð .ð .ð .s   ÂB4Â4B8Â;B8rR   )r'   )r   F)Wr…   r”  r‹   ÚloggingÚreÚabcr   r   Úcollectionsr   r   Úenumr   Útypingr   r	   r
   r   r   r   r   r   r   r   rä   Útorch.distributedÚdistributedrê   Útorch.distributed.fsdpr   r   Útorch.profilerr   r1  r   r   r   r¯   r   r   Ú__all__Ú	getLoggerrG   r§   r%   r:   r;   r<   r3   r4   r5   r6   r7   r8   r=   r0   r1   r2   r9   ÚcompilerZ   rM   r]   rS   r—   r™   ÚP2POprî   r÷   r   r  r   r   rS  rW  rp  r}  r   r¿  r!   r	  r    r"   r#   r   rÎ  r�  rK   rB   r@   ú<module>r�     sP  ðð €€€Ø 
€
€
€
Ø Ð Ð Ð Ø €€€Ø 	€	€	€	Ø #Ð #Ð #Ð #Ð #Ð #Ð #Ð #Ø ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ø Ð Ð Ð Ð Ð ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð €€€Ø  Ð  Ð  Ð  Ð  Ð  Ø <Ð <Ð <Ð <Ð <Ð <Ð <Ð <Ø *Ð *Ð *Ð *Ð *Ð *à TÐ TÐ TÐ TÐ TÐ TÐ TÐ TÐ TÐ TØ %Ð %Ð %Ð %Ð %Ð %ð ð 'Ø&Ð&Ð&Ð&Ð&Ð&ð
ð 
ð 
€ð 
ˆÔ	˜8Ñ	$Ô	$€ð3Eð 3Eð 3Eð 3Eð 3E�tñ 3Eô 3Eð 3Eðl Ô
"€Ø!Ô0€Ø"Ô2€Ø
Ô
"€Ø
Ô
"€Ø	Ô	 €Ø	Ô	 €Ø	Ô	 €Ø	Ô	 €Ø Ô.€ð €Ø€Ø€Ø€ð �”
ØFñô €ð
 
ð  
ð  
ð  
ð  
ˆjñ  
ô  
ð  
ðJ (,ð;ð ;Ø˜˜d 8¨GÔ#4Ô5Ð5Ô6ð;à ”}ð;ð 	ð;ð ;ð ;ð ;ð|n
ð n
ð n
ð n
ð n
˜ñ n
ô n
ð n
ðb1ð 1˜˜TœZÔ(ð 1°¸´ð 1ð 1ð 1ð 1ð 6:ðð Ø�$”*ÔðØ%-¨c¤]ðà	ˆ#ˆtŒyˆ.Ôðð ð ð ð6Dð Dð Dð Dð DÐ.ñ Dô Dð DðN0ð 0ð 0ð 0ð 0Ð1ñ 0ô 0ð 0ðfRð Rð Rð Rð RÐ*ñ Rô Rð RðjO1ð O1ð O1ð O1ð O1Ð)ñ O1ô O1ð O1ðh ðCð CØ˜( 7Ô+Ô,ðCàðCð 
ˆ'„]ðCð Cð Cð CðL Ø˜( 7Ô+Ô,ð à	ˆ'„]ð ð  ð  ð  ðFfØ˜#˜t Gœ}Ð,Ô-ðfà˜S˜E 3˜JÔ'ðfð ðfð 
ˆ#ˆt�GŒ}Ð
Ôð	fð fð fð fðR@2Ø�#�t˜H WÔ-Ô.Ð.Ô/ð@2àð@2ð ð@2ð ð	@2ð @2ð @2ð @2ðFn2ð n2ð n2ð n2ð n2Ð-ñ n2ô n2ð n2ðb	w2ð w2ð w2ð w2ð w2Ð4ñ w2ô w2ð w2ðt	;ð ;ð ;ð ;ð ;Ð-ñ ;ô ;ð ;ðN ØðFð Fð Fð FðRo
ð o
ð o
ð o
ð o
Ð3ñ o
ô o
ð o
ðdvð vð vð vð vÐ$9ñ vô vð vðrjð jð jð jð jÐ1ñ jô jð jðZA cð Að Að Að Að4BØ#+¨S¨E°3¨JÔ#7ðBØEHðBð Bð Bð BðJ!.ð !.ð !.ð !.ð !.rB   