§
    ž²Åj•‚  ã                  ór  — d dl mZ d dlZd dlZd dlZd dlZd dlmZ d dl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mZmZmZmZ  ej        e¦  «        Zej          !                    ed
¦  «        Z"erddl#m$Z$ d,d„Z%d,d„Z&d,d„Z'd-d„Z(d.d„Z)d/d„Z*d„ Z+d„ Z,d,d„Z-d0d"„Z.d1d$„Z/d%„ Z0d2d+„Z1dS )3é    )ÚannotationsN)Údefaultdict)ÚDictÚListÚSetÚTYPE_CHECKING)ÚStorageWeakRefé   )ÚconfigÚir)ÚWeakDep)Úcontains_collectiveÚcontains_waitÚfind_recursive_deps_of_nodeÚfind_recursive_users_of_nodeÚis_collectiveÚis_fallback_opÚis_waitÚoverlap)ÚBaseSchedulerNodeÚsnodesúList[BaseSchedulerNode]Úreturnc                ó(   — t          | ddd¬¦  «        S )z7
    Greedily schedules waits as late as possible.
    FT©Úraise_commsÚ
sink_waitsÚreorder_for_overlap©Ú_schedule_for_comm©r   s    úFC:\Projects\Historical\venv\Lib\site-packages\torch/_inductor/comms.pyr   r   #   s$   € õ Ø˜E¨dÈðñ ô ð ó    c                ó(   — t          | ddd¬¦  «        S )z8
    Greedily schedules comms as early as possible.
    TFr   r   r!   s    r"   r   r   ,   s$   € õ Ø˜D¨UÈðñ ô ð r#   c                ó(   — t          | ddd¬¦  «        S )aÀ  
    This achieves the following overall scheduling procedure:
        Step 1: Given that we've currently scheduled comm N, we now schedule all compute nodes
            that are required for comm N + 1 but do not depend on comm N, to run at the same time with comm N.
        Step 2: If all those compute nodes are sufficient to overlap comm N, we're done.
            Otherwise, we now need to look elsewhere to find compute that overlaps with comm N.
            We prioritize compute nodes that are needed sooner.
        Step 3: We schedule the compute nodes dependent on comm N and required for comm N + 1.
        Step 4: We schedule comm N + 1.
        Repeat this for subsequent comm nodes.
    Tr   r   r!   s    r"   Úreorder_compute_for_overlapr&   5   s$   € õ Ø˜D¨TÀtðñ ô ð r#   r   Úboolr   r   c                óB  ‡‡‡‡‡‡‡‡‡‡‡‡— i }i Ši i i cŠŠŠt          | ¦  «        D ]�\  }}|                     ¦   «         D ]}|||<   Œ|                     ¦   «         D ]}|‰|<   Œ|‰|                     ¦   «         <   |                     ¦   «         }	t          j        ‰|	<   d‰|	<   |‰|	<   Œ‚d}
| D ]•}|rit          |¦  «        rZ|
‰|                     ¦   «         <   |j        D ]5}‰|                              ¦   «         }t          ‰|         |
¦  «        ‰|<   Œ6|
dz  }
Œm|r&t          |¦  «        rd‰|                     ¦   «         <   Œ– G ˆˆˆˆfd„d¦  «        Šd„ | D ¦   «         Šg Št          t          ¦  «        Šd„ | D ¦   «         Š‰                     ¦   «         D ]V\  }}t          |¦  «        dk    rt          j        ‰ ‰|¦  «        ¦  «         |D ]}‰|                              |¦  «         ŒŒWg Šˆˆˆˆˆfd„Šˆfd„Šˆˆˆˆfd	„}t          ‰¦  «        rPt          j        ‰¦  «        j        }|rt          |¦  «        r ||¦  «         n ‰|¦  «         t          ‰¦  «        °P‰                     ¦   «         D ]%\  }}t          |¦  «        dk    sJ d
‰› �¦   «         ‚Œ&‰S )aÂ  
    Schedule `snodes` for various comm optimization objectives.

    Args:
        snodes: the nodes to be scheduled.
        raise_comms: whether to greedily schedule collectives as early as possible
        sink_wait: whether to greedily schedule waits as late as possible
        reorder_compute_for_overlap: whether to reorder compute nodes to
            optimize for compute/communication overlapping.

    Returns:
        The new schedule order.

    Some notes on the synergy between different options:
        - `raise_comms` provides more overlapping oppurtunies for `reorder_compute_for_overlap`.
        - When both `raise_comms` and `sink_waits` is `True`, `raise_comms` is prioritized.
    r   r
   c                  ó(   •— e Zd Zdˆ ˆˆˆfd„Zd„ ZdS )ú$_schedule_for_comm.<locals>.Runnabler   ÚNonec                óÞ   •— || _         t          t          |                     ¦   «         ¦  «        ¦  «        }‰|                              ¦   «         }‰|         ‰|         ‰|         f| _        d S ©N)ÚsnodeÚnextÚiterÚget_operation_namesÚget_nameÚscore)Úselfr.   ÚnameÚ
fused_nameÚname_to_fused_nodeÚscores_0Úscores_1Úscores_2s       €€€€r"   Ú__init__z-_schedule_for_comm.<locals>.Runnable.__init__Š   sf   ø€ ØˆDŒJÝ�˜U×6Ò6Ñ8Ô8Ñ9Ô9Ñ:Ô:ˆDØ+¨DÔ1×:Ò:Ñ<Ô<ˆJà˜Ô$Ø˜Ô$Ø˜Ô$ðˆDŒJˆJˆJr#   c                ó"   — | j         |j         k     S r-   ©r3   )r4   Úothers     r"   Ú__lt__z+_schedule_for_comm.<locals>.Runnable.__lt__”   s   € Ø”: ¤Ò+Ð+r#   N)r   r+   )Ú__name__Ú
__module__Ú__qualname__r;   r?   )r7   r8   r9   r:   s   €€€€r"   ÚRunnabler*   ‰   sQ   ø€ € € € € ð	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð	,ð 	,ð 	,ð 	,ð 	,r#   rC   c                ó2   — i | ]}|d „ |j         D ¦   «         “ŒS )c                ó   — h | ]	}|j         ’Œ
S © )r5   )Ú.0Údeps     r"   ú	<setcomp>z0_schedule_for_comm.<locals>.<dictcomp>.<setcomp>˜   s   € Ð=Ð=Ð=˜S�”Ð=Ð=Ð=r#   )Úunmet_dependencies©rG   r.   s     r"   ú
<dictcomp>z&_schedule_for_comm.<locals>.<dictcomp>—   s9   € ð 5ð 5ð 5ØBGˆÐ=Ð= EÔ$<Ð=Ñ=Ô=ð5ð 5ð 5r#   c                ó.   — i | ]}|t          |¦  «        “ŒS rF   )Úestimate_op_runtimerK   s     r"   rL   z&_schedule_for_comm.<locals>.<dictcomp>�   s#   € ÐKÐKÐK¸5�UÕ/°Ñ6Ô6ÐKÐKÐKr#   c                ó  •— ‰                      | ¦  «         |                      ¦   «         D ]_}‰|         D ]T} ‰|                               |¦  «         t          ‰|          ¦  «        dk    rt	          j        ‰ ‰| ¦  «        ¦  «         ŒUŒ`dS )zU
        Schedules `snode` and put all unblocked nodes onto the ready queue.
        r   N)ÚappendÚget_buffer_namesÚremoveÚlenÚheapqÚheappush)r.   Úbuf_namerC   Úbuffer_usersÚreadyÚ	scheduledÚ
unmet_depss     €€€€€r"   Úschedulez$_schedule_for_comm.<locals>.schedule§   s£   ø€ ð 	×Ò˜ÑÔÐØ×.Ò.Ñ0Ô0ð 	;ð 	;ˆHØ% hÔ/ð ;ð ;�Ø˜5Ô!×(Ò(¨Ñ2Ô2Ð2Ý�z %Ô(Ñ)Ô)¨QÒ.Ð.Ý”N 5¨(¨(°5©/¬/Ñ:Ô:Ð:øð;ð	;ð 	;r#   c                 ój   •— d„ ‰D ¦   «         } t          | ¦  «        dk    rdS t          | d„ ¬¦  «        S )zh
        Return the next node in the ready queue that's neither a collective or
        a wait.
        c                ób   — g | ],}t          |j        ¦  «        °t          |j        ¦  «        °*|‘Œ-S rF   )r   r.   r   ©rG   Úxs     r"   ú
<listcomp>zI_schedule_for_comm.<locals>.get_overlapping_candidate.<locals>.<listcomp>·   sM   € ð 
ð 
ð 
àÝ& q¤wÑ/Ô/ð
õ 9FÀaÄgÑ8NÔ8Nð
Øð
ð 
ð 
r#   r   Nc                ó   — | j         S r-   r=   ©r_   s    r"   ú<lambda>zG_schedule_for_comm.<locals>.get_overlapping_candidate.<locals>.<lambda>¾   s   € ¨Q¬W€ r#   ©Úkey)rS   Úmin)Ú
candidatesrX   s    €r"   Úget_overlapping_candidatez5_schedule_for_comm.<locals>.get_overlapping_candidate²   sP   ø€ ð

ð 
àð
ñ 
ô 
ˆ
õ
 ˆz‰?Œ?˜aÒÐØ�4Ý�:Ð#4Ð#4Ð5Ñ5Ô5Ð5r#   c                ó*  •— t          | ¦  «        sJ ‚ ‰| ¦  «         ‰|          }|dk    rS ‰¦   «         x}�G‰                     |¦  «          ‰|j        ¦  «         |‰|j                 z  }|dk    r ‰¦   «         x}­Gt          j        ‰¦  «         dS )zÈ
        Schedules collective node `snode`, along with one or more compute nodes
        to overlap with it. The strategy is described in the comment of
        `reorder_compute_for_overlap`.
        r   N)r   rR   r.   rT   Úheapify)r.   Úcollective_costÚ	candidaterh   rX   r[   Úsnode_to_costs      €€€€r"   Úschedule_collective_for_overlapz;_schedule_for_comm.<locals>.schedule_collective_for_overlapÀ   s½   ø€ õ # 5Ñ)Ô)Ð)Ð)Ð)Øˆ�‰Œˆà'¨Ô.ˆà˜aÒÐØ7Ð7Ñ9Ô9Ð9�ÐFà�LŠL˜Ñ#Ô#Ð#ØˆH�Y”_Ñ%Ô%Ð%Ø˜}¨Y¬_Ô=Ñ=ˆOð ˜aÒÐØ7Ð7Ñ9Ô9Ð9�ÐFõ
 	Œ�eÑÔÐÐÐr#   z;Detected unscheduled nodes. Nodes with unmet dependencies: )Ú	enumeraterQ   r1   r2   ÚsysÚmaxsizer   Ú	ancestorsrf   r   r   ÚsetÚitemsrS   rT   rU   ÚaddÚheappopr.   )r   r   r   r   Úbuf_name_to_snodeÚidxr.   rV   Úop_nameÚ	node_nameÚcomm_idxÚancÚanc_fused_nameÚdepsrH   rn   rC   rW   rh   r7   rX   r[   rY   r8   r9   r:   rm   rZ   s                   @@@@@@@@@@@@r"   r    r    H   sÒ  øøøøøøøøøøøø€ ðL ÐØÐØ#% r¨2Ð €Hˆh˜Ý Ñ'Ô'ð "ð "‰
ˆˆUØ×.Ò.Ñ0Ô0ð 	0ð 	0ˆHØ*/Ð˜hÑ'Ð'à×0Ò0Ñ2Ô2ð 	0ð 	0ˆGØ*/Ð˜wÑ'Ð'Ø/4Ð˜5Ÿ>š>Ñ+Ô+Ñ,à—N’NÑ$Ô$ˆ	Ý!œkˆ�ÑØˆ�ÑØ!ˆ�ÑÐà€HØð +ð +ˆØð 	+Õ.¨uÑ5Ô5ð 	+Ø)1ˆH�U—^’^Ñ%Ô%Ñ&Ø”ð Sð S�Ø!3°CÔ!8×!AÒ!AÑ!CÔ!C�Ý+.¨x¸Ô/GÈÑ+RÔ+R�˜Ñ(Ð(Ø˜‰MˆHˆHØð 	+�M¨%Ñ0Ô0ð 	+Ø)*ˆH�U—^’^Ñ%Ô%Ñ&øð,ð ,ð ,ð ,ð ,ð ,ð ,ð ,ð ,ð ,ñ ,ô ,ð ,ð5ð 5ØKQð5ñ 5ô 5€Jð €EÝ6AÅ#Ñ6FÔ6F€LØKÐKÀFÐKÑKÔK€Mà!×'Ò'Ñ)Ô)ð )ð )‰ˆˆtÝˆt‰9Œ9˜Š>ˆ>ÝŒN˜5 ( (¨5¡/¤/Ñ2Ô2Ð2Øð 	)ð 	)ˆCØ˜Ô×!Ò! %Ñ(Ô(Ð(Ð(ð	)ð €Ið	;ð 	;ð 	;ð 	;ð 	;ð 	;ð 	;ð 	;ð 	;ð6ð 6ð 6ð 6ð 6ðð ð ð ð ð ð ð õ& ˆe‰*Œ*ð Ý”˜eÑ$Ô$Ô*ˆØð 	Õ#6°uÑ#=Ô#=ð 	Ø+Ð+¨EÑ2Ô2Ð2Ð2àˆH�U‰OŒOˆOõ ˆe‰*Œ*ð ð "×'Ò'Ñ)Ô)ð 
ð 
‰ˆˆtÝ�4‰yŒy˜AŠ~ˆ~ˆ~ð;Ø.8ð;ð ;ñ Œ~ˆ~ˆ~ð Ðr#   Únodesc                óî  — t           j                             ¦   «         s| S t          d„ | D ¦   «         ¦  «        rt	          | ||¦  «        } d„ | D ¦   «         }t          dt          |¦  «        ¦  «        D ]€}t          t          ||          	                    ¦   «         ¦  «        ¦  «        }||dz
            	                    ¦   «         D ],}||          
                    t          ||¬¦  «        ¦  «         Œ-Œ�| S )zÌ
    Decide global ordering of comms, by just enforcing the ordering that's in the input graph
    (might not be the same ordering as the eager mode program).
    TODO: Come up with a better approach
    c              3  ó¨   K  — | ]M}t          |j        t          j        j        j        j        t          j        j        j        j        h¦  «        V — ŒNd S r-   )r   ÚnodeÚtorchÚopsÚfsdpÚall_gather_copy_inÚdefaultÚ	chunk_catr^   s     r"   ú	<genexpr>z2decide_global_ordering_of_comms.<locals>.<genexpr>î   sf   è è € ð 	ð 	ð õ 	ØŒFå”	”Ô1Ô9Ý”	”Ô(Ô0ðñ	
ô 	
ð	ð 	ð 	ð 	ð 	ð 	r#   c                ó0   — g | ]}t          |¦  «        ¯|‘ŒS rF   )r   )rG   Úns     r"   r`   z3decide_global_ordering_of_comms.<locals>.<listcomp>ú   s&   € Ð=Ð=Ð=˜Õ&9¸!Ñ&<Ô&<Ð=�!Ð=Ð=Ð=r#   r
   ©Úmutating_buf)rƒ   ÚdistributedÚis_availableÚanyÚenforce_comm_ordering_for_fsdpÚrangerS   r/   r0   rQ   Úadd_fake_depr   )r   Úname_to_bufr7   Ú
comm_nodesÚir�   Úbufs          r"   Údecide_global_ordering_of_commsr˜   â   s  € õ Ô×)Ò)Ñ+Ô+ð Øˆõ ð 	ð 	ð ð	ñ 	ô 	ñ 	ô 	ð 
Wõ /¨u°kÐCUÑVÔVˆà=Ð=˜UÐ=Ñ=Ô=€Jå�1•c˜*‘o”oÑ&Ô&ð Pð Pˆå�D ¨A¤×!?Ò!?Ñ!AÔ!AÑBÔBÑCÔCˆØ˜a !™eÔ$×5Ò5Ñ7Ô7ð 	Pð 	PˆCØ�qŒM×&Ò&¥w¨sÀÐ'NÑ'NÔ'NÑOÔOÐOÐOð	Pð €Lr#   r.   r   Úfloatc                ó®   — t           j        dk    r|                      ¦   «         }n/t          t           j        ¦  «        sJ ‚t          j        | ¦  «        }|S )z:
    Returns estimated op runtime in nanoseconds (ns)
    r‡   )r   rN   Úget_estimated_runtimeÚcallable)r.   Úruntimes     r"   rN   rN     sQ   € õ Ô! YÒ.Ð.Ø×-Ò-Ñ/Ô/ˆˆå�Ô2Ñ3Ô3Ð3Ð3Ð3ÝÔ,¨UÑ3Ô3ˆØ€Nr#   c                ó`  — d}t          | j        t          j        ¦  «        rd| j        j        › d�}d}| j                             ¦   «         }t          |t          j        ¦  «        rd|j        › d|j        › d�}| j         	                    ¦   «         pd}| j        j
        j        › |› |› d|› d�S )NÚ z (ú)z (size=z	, stride=)Ú
isinstancer‚   r   ÚExternKernelOutÚpython_kernel_nameÚget_output_specÚLayoutÚsizeÚstrideÚmaybe_get_nameÚ	__class__r@   )r.   ÚdetailÚout_tensor_infoÚlayoutrz   s        r"   Únode_summaryr­     s½   € Ø€FÝ�%”*�bÔ0Ñ1Ô1ð 7Ø6�e”jÔ3Ð6Ð6Ð6ˆØ€OØŒZ×'Ò'Ñ)Ô)€FÝ�&�"œ)Ñ$Ô$ð KØJ F¤KÐJÐJ¸&¼-ÐJÐJÐJˆØ”
×)Ò)Ñ+Ô+Ð1¨r€IØŒjÔ"Ô+ÐT¨VÐT°_ÐTÐTÈ	ÐTÐTÐTÐTr#   c                ó‚  — d}d }| D �]}|€‡t          |¦  «        r|t          |¦  «        z  }|j        }n5t          |j        ¦  «        rt	          d¦  «        ‚|t          |¦  «        z  }t
                               t          |¦  «        › ¦  «         ŒŒt          |¦  «        rt	          d¦  «        ‚t          |j        ¦  «        r+t
                               t          |¦  «        › ¦  «         d }Œét
                               dt          |¦  «        › �¦  «         �Œt
                               d|dz  dz  › �¦  «         d S )Ng        z8Wait is not expected when there is no collective runningzkFound two collectives running at the same time. `visualize_overlap` needs to be updated to handle this casez| zEst. runtime (ms): iè  )r   rN   r‚   r   ÚAssertionErrorÚoverlap_logÚdebugr­   )ÚorderÚtotal_est_runtimeÚcur_comm_noder.   s       r"   Úvisualize_overlaprµ     sr  € Ø"ÐØ€MØð >ñ >ˆØÐ Ý" 5Ñ)Ô)ð @Ø!Õ%8¸Ñ%?Ô%?Ñ?Ð!Ø %¤
��Ý˜œÑ$Ô$ð @Ý$ØNñô ð ð "Õ%8¸Ñ%?Ô%?Ñ?Ð!Ý×Ò¥¨eÑ!4Ô!4Ð6Ñ7Ô7Ð7Ð7å" 5Ñ)Ô)ð 	>Ý$ðRñô ð õ ˜œÑ$Ô$ð >Ý×!Ò!¥\°%Ñ%8Ô%8Ð":Ñ;Ô;Ð;Ø $��å×!Ò!Ð"<¥|°EÑ':Ô':Ð"<Ð"<Ñ=Ô=Ð=Ñ=Ý×ÒØ?Ð/°$Ñ6¸Ñ=Ð?Ð?ñô ð ð ð r#   c                óô  — | }t           j        D �]g}t          |t          ¦  «        r$|t	          ¦   «         v rt	          ¦   «         |         }t
          j                             ¦   «         dk    rmt           	                    d|› d�¦  «         	 t          |¦  «         n># t          $ r1}t           	                    t          |¦  «        ¦  «         Y d }~nd }~ww xY w ||¦  «        }t
          j                             ¦   «         dk    rot           	                    d|› d�¦  «         	 t          |¦  «         �Œ(# t          $ r2}t           	                    t          |¦  «        ¦  «         Y d }~�Œ_d }~ww xY w�Œi|S )Nr   z.==== Visualize overlap before reordering pass z ====z-==== Visualize overlap after reordering pass )r   Ú'reorder_for_compute_comm_overlap_passesr¡   ÚstrÚglobalsrƒ   rŽ   Úget_rankr°   r±   rµ   Ú	Exception)r   r²   ÚpÚes       r"   Ú$reorder_compute_and_comm_for_overlapr¾   <  s›  € ð €EåÔ;ð *ñ *ˆÝ�a�ÑÔð 	 !¥w¡y¤y . .Ý‘	”	˜!”ˆAÝÔ×%Ò%Ñ'Ô'¨1Ò,Ð,Ý×ÒØIÀÐIÐIÐIñô ð ð*Ý! %Ñ(Ô(Ð(Ð(øÝð *ð *ð *Ý×!Ò!¥# a¡&¤&Ñ)Ô)Ð)Ð)Ð)Ð)Ð)Ð)øøøøð*øøøà��%‘”ˆÝÔ×%Ò%Ñ'Ô'¨1Ò,Ð,Ý×ÒØHÀÐHÐHÐHñô ð ð*Ý! %Ñ(Ô(Ð(Ñ(øÝð *ð *ð *Ý×!Ò!¥# a¡&¤&Ñ)Ô)Ð)Ð)Ð)Ð)Ð)Ñ)øøøøð*øøøñ -ð €Ls0   ÂBÂ
CÂ&'CÃCÄ&D7Ä7
E3Å'E.Å.E3Úgraphútorch.fx.Graphc           
     ó*  ‡‡‡‡‡‡— t          | j        ¦  «        Št          t           ¦  «        Št          t           ¦  «        Št          ‰¦  «        D ]½\  }}|j        dk    r­|j        t          j        j        j	        j
        k    r‰|j        d         j        dk    sJ d|› d|j        d         › d�¦   «         ‚|j        d         }|j        d         }|dk    r‰|                              |¦  «         Œ¢‰|                              |¦  «         Œ¾ˆˆˆfd„}t          t           ¦  «        }t          ‰¦  «        D ]…\  }}|j        dk    ru|j        t          j        j        j        j
        k    rQ|}|j        d         Š‰j        dk    sJ d	‰› d
| › d�¦   «         ‚ |‰¦  «        r|‰                              |¦  «         Œ†d„ }d„ Š‰D ]y}|j        dk    rlt          |j        t          j        j        ¦  «        rH|j        j        j        r7 ||¦  «        s, ‰||                     ¦   «         ¦  «        rJ d|› d�¦   «         ‚Œz|                     ¦   «         D �]\  Š}	t          |	¦  «        D �] \  }
}‰|         }|j        d         ‰u sJ ‚|j        \  }Š|dz   }|
t-          |	¦  «        dz
  k     r|	|
dz            nt-          ‰¦  «        dz
  }‰||…         }t/          ˆˆfd„|D ¦   «         ¦  «        rJ d‰› d|› d| › d�¦   «         ‚|D ]b}|j        dk    rU‰|j        v rL|j        t          j        j        j	        j
        k    r(t1          ˆˆfd„|j        D ¦   «         ¦  «        }||_        Œc�Œ�Œ|                     ¦   «         D ]7\  Š}	t          |	¦  «        D ]"\  }
}‰|         }|                      |¦  «         Œ#Œ8‰D ]U}|j        dk    rH|j        t          j        j        j	        j
        k    r$|j        d         |v r|                      |¦  «         ŒVdS )aŠ  
    This FX graph pass replaces uses of FSDP2 unsharded params with their corresponding
    graph intermediates that were fsdp.copy_ into the unsharded params in the original graph.

    NOTE: Can only apply this pass to any of the FSDP2 unsharded params that have this pattern
    (or repetition of): `resize_(full) -> copy_ -> resize_(0)`. Because of this, for partial-graph case
    where `resize_(full) -> copy_` is in one graph and `resize_(0)` is in another graph, we can't
    remove these resize and copy ops and thus we will have worse performance there.

    In other words, "do we try to remove all the resize_(full) -> copy_ -> resize_(0) nodes for this unsharded param"
    is actually a per-unsharded-param decision, since for each unsharded param, we look at its resize sequence pattern
    (in `check_resize_pattern()`) to determine if its set of resize and copy nodes can be removed.
    Úcall_functionr   Úplaceholderz1Resize can only operate on graph inputs, but got z# which is resizing non-graph-input ú
r
   c                óÊ  •— ‰                      | g ¦  «        }‰                      | g ¦  «        }t          |¦  «        t          |¦  «        k    s@t                               d| › dt          |¦  «        › dt          |¦  «        › d�¦  «         dS t	          ||¦  «        D ]D\  }}||k    r9t                               d| › d‰|         › d|› d	‰|         › d|› d
�¦  «          dS ŒEdS )NzH
Unequal number of resize-to-full and resize-to-0 nodes for graph input z:
z vs. zK.
Skipping `remove_fsdp2_unsharded_param_graph_input_usage` FX graph pass.
Fz
For graph input z: resize-to-full node z
 at index z 
happens after resize-to-0 node zd.
Skipping `remove_fsdp2_unsharded_param_graph_input_usage` FX graph pass for that unsharded param.
T)ÚgetrS   ÚlogÚwarningÚzip)Úgraph_inputÚresized_to_full_idxesÚresized_to_0_idxesÚresize_to_full_idxÚresize_to_0_idxÚ&graph_input_to_resized_to_0_node_idxesÚ)graph_input_to_resized_to_full_node_idxesÚ	node_lists        €€€r"   Úcheck_resize_patternzLremove_fsdp2_unsharded_param_graph_input_usage.<locals>.check_resize_pattern|  sm  ø€ ð !J× MÒ MØ˜ñ!
ô !
Ðð D×GÒGÈÐUWÑXÔXÐåÐ(Ñ)Ô)­SÐ1CÑ-DÔ-DÒDÐDÝ�KŠKðØHSðð åÐÑÔðð å"%Ð&8Ñ"9Ô"9ðð ð ñô ð ð �5õ 47Ø!Ð#5ñ4
ô 4
ð 	ð 	Ñ/Ð ð " _Ò4Ð4Ý—’ðØðð Ø4=Ð>PÔ4Qðð Ø]oðð à )¨/Ô :ðð àFUðð ð ñô ð ð �u�uð 5ð ˆtr#   z\
Assumed all FSDP2 `unsharded_param`s to be graph input, but it's not true!
Offending node: z	. Graph: c                ó’   — | j         t          j        j        j        j        k    p#| j         t          j        j        j        j        k    S r-   )Útargetrƒ   r„   r…   Úcopy_r‡   ÚinductorÚresize_storage_bytes_)r‚   s    r"   Úis_allowed_mutationzKremove_fsdp2_unsharded_param_graph_input_usage.<locals>.is_allowed_mutation¯  s6   € àŒK�5œ9œ>Ô/Ô7Ò7ð OØŒ{�eœiÔ0ÔFÔNÒNð	
r#   c                ó   ‡ — t          ‰ j        t          j        j        ¦  «        r(d„ t          ‰ j        j        j        ¦  «        D ¦   «         ng }ˆ fd„|D ¦   «         }d„ |D ¦   «         }t          ||z  ¦  «        dk    S )Nc                ó>   — g | ]\  }}|j         ®|j         j        ¯|‘ŒS r-   )Ú
alias_infoÚis_write)rG   r–   r_   s      r"   r`   zyremove_fsdp2_unsharded_param_graph_input_usage.<locals>.is_node_mutating_unsharded_param_or_its_alias.<locals>.<listcomp>¸  s8   € ð ð ð á�A�qØ”<Ð+°´Ô0EÐ+ð à+Ð+Ð+r#   c                ó~   •— h | ]9}t          ‰j        |         j        d                               ¦   «         ¦  «        ’Œ:S ©Úval)r	   ÚargsÚmetaÚuntyped_storage)rG   r–   r‚   s     €r"   rI   zxremove_fsdp2_unsharded_param_graph_input_usage.<locals>.is_node_mutating_unsharded_param_or_its_alias.<locals>.<setcomp>À  sK   ø€ ð %
ð %
ð %
àõ ˜4œ9 Qœ<Ô,¨UÔ3×CÒCÑEÔEÑFÔFð%
ð %
ð %
r#   c                óf   — h | ].}t          |j        d                               ¦   «         ¦  «        ’Œ/S rÞ   )r	   rá   râ   )rG   Úunsharded_params     r"   rI   zxremove_fsdp2_unsharded_param_graph_input_usage.<locals>.is_node_mutating_unsharded_param_or_its_alias.<locals>.<setcomp>Ä  sD   € ð (
ð (
ð (
àõ ˜?Ô/°Ô6×FÒFÑHÔHÑIÔIð(
ð (
ð (
r#   r   )	r¡   rÔ   rƒ   Ú_opsÚ
OpOverloadro   Ú_schemaÚ	argumentsrS   )r‚   Úunsharded_paramsÚmutated_arg_idxesÚmutated_node_arg_storagesÚstorages_of_unsharded_paramss   `    r"   Ú-is_node_mutating_unsharded_param_or_its_aliaszeremove_fsdp2_unsharded_param_graph_input_usage.<locals>.is_node_mutating_unsharded_param_or_its_aliasµ  s½   ø€ õ ˜$œ+¥u¤zÔ'<Ñ=Ô=ðð ð å% d¤kÔ&9Ô&CÑDÔDðñ ô ð ð ð 	ð%
ð %
ð %
ð %
à&ð%
ñ %
ô %
Ð!ð(
ð (
à#3ð(
ñ (
ô (
Ð$õ Ð,Ð/KÑKÑLÔLÈqÒPÐPr#   zdUser mutation on FSDP2 unsharded param is not allowed when Traceable FSDP2 is used. Violating node: c              3  ó2   •K  — | ]} ‰|‰g¦  «        V — Œd S r-   rF   )rG   r‚   rí   rä   s     €€r"   r‰   zAremove_fsdp2_unsharded_param_graph_input_usage.<locals>.<genexpr>ö  sG   øè è € ð ð àð >Ð=¸dÀ_ÐDUÑVÔVðð ð ð ð ð r#   z(Assumed no ops mutating unsharded param z in subgraph z, but it's not true!
Graph: c              3  ó(   •K  — | ]}|‰u r‰n|V — Œd S r-   rF   )rG   ÚargÚreplacementrä   s     €€r"   r‰   zAremove_fsdp2_unsharded_param_graph_input_usage.<locals>.<genexpr>  sE   øè è € ð %ð %àð (+¨oÐ'=Ð'=˜˜À3ð%ð %ð %ð %ð %ð %r#   N)Úlistr   r   ro   ÚoprÔ   rƒ   r„   rÖ   r×   r‡   rà   rP   r…   rÕ   r¡   rå   ræ   rç   Ú
is_mutableÚkeysrt   rS   r�   ÚtupleÚ
erase_node)r¿   rx   r‚   rÊ   Únew_sizerÒ   Ú'unsharded_param_to_fsdp_copy_node_idxesÚfsdp_copy_noderØ   Úfsdp_copy_node_idxesr–   Úfsdp_copy_node_idxÚ_Úsubgraph_start_idxÚsubgraph_end_idxÚsubgraph_nodesÚnew_argsrÏ   rÐ   rí   rÑ   rñ   rä   s                    @@@@@@r"   Ú.remove_fsdp2_unsharded_param_graph_input_usager  X  s¡  øøøøøø€ õ �U”[Ñ!Ô!€Iõ 1<½DÑ0AÔ0AÐ-Ý-8½Ñ->Ô->Ð*Ý˜yÑ)Ô)ð Pð P‰	ˆˆTàŒG�Ò&Ð&Ø”�uœyÔ1ÔGÔOÒOÐOð ”	˜!”” =Ò0Ð0Ð0ðØ26ðð Ø[_Ô[dÐefÔ[gðð ð ñ 1Ô0Ð0ð œ) Aœ,ˆKØ”y ”|ˆHØ˜!Š|ˆ|Ø9¸+ÔF×MÒMÈcÑRÔRÐRÐRà6°{ÔC×JÒJÈ3ÑOÔOÐOøð"ð "ð "ð "ð "ð "ð "õJ /:½$Ñ.?Ô.?Ð+Ý˜yÑ)Ô)ð Uð U‰	ˆˆTØŒ7�oÒ%Ð%¨$¬+½¼¼Ô9MÔ9UÒ*UÐ*UØ!ˆNØ"œi¨œlˆOàÔ" mÒ3Ð3Ð3ðà ðð à+0ðð ð ñ 4Ô3Ð3ð
 $Ð# OÑ4Ô4ð UØ7¸ÔH×OÒOÐPSÑTÔTÐTøð
ð 
ð 
ðQð Qð Qð, ð ð ˆàŒG�Ò&Ð&Ý˜4œ;­¬
Ô(=Ñ>Ô>ð 'à”Ô#Ô.ð 'ð (Ð'¨Ñ-Ô-ð 'ð
 EÐDØÐ=×BÒBÑDÔDñô ð ð ðØeiðð ð ñô ð øð, 
1×	6Ò	6Ñ	8Ô	8ð")ñ ")ñ 	ØØå%.Ð/CÑ%DÔ%Dð 	)ñ 	)Ñ!ˆAÐ!Ø&Ð'9Ô:ˆNØ!Ô& qÔ)¨_Ð<Ð<Ð<Ð<Ø+Ô0‰NˆAˆ{à!3°aÑ!7Ðð •sÐ/Ñ0Ô0°1Ñ4Ò4Ð4ð % Q¨¡UÔ+Ð+å˜‘^”^ aÑ'ð ð
 'Ð'9Ð:JÐ'JÔKˆNÝð ð ð ð ð à*ðñ ô ñ ô ð ð ðØ)8ðð ØGUðð àðð ð ñô ð ð 'ð 
)ð 
)�à”G˜Ò.Ð.Ø'¨4¬9Ð4Ð4Øœ¥u¤yÔ'9Ô'OÔ'WÒWÐWå$ð %ð %ð %ð %ð %à#'¤9ð%ñ %ô %ñ  ô  �Hð !)�D”Iøñ
)ñ)	)ðH 
1×	6Ò	6Ñ	8Ô	8ð-ð -ñ 	ØØå%.Ð/CÑ%DÔ%Dð 	-ð 	-Ñ!ˆAÐ!Ø&Ð'9Ô:ˆNØ×Ò˜^Ñ,Ô,Ð,Ð,ð	-ð
 ð #ð #ˆàŒG�Ò&Ð&Ø”�uœyÔ1ÔGÔOÒOÐOØ”	˜!”Ð GÐGÐGà×Ò˜TÑ"Ô"Ð"øð#ð #r#   r+   c                óæ  ‡	— 	 dd l Š	‰	j                             ¦   «         sJ ‚‰	j        j        j        r‰	j        j        j        sJ ‚n# t          t          t          f$ r Y d S w xY wddl
m}m}m}m}m} 	 ˆ	fd„} |¦   «         } | |‰	j        j        j        j         |t"          j         |‰	j        j        j        j         |d¦  «         |d¦  «         |d¦  «         |d¦  «         |d	¦  «         |d
¦  «         |d¦  «        ¦  «         |d¦  «        ¦  «         |d¦  «         |d¦  «        ¦  «        |d„ ¬¦  «        dˆ	fd„¦   «         } || ¦  «         |                     | ¦  «         d S )Nr   r
   )ÚCallFunctionÚ
KeywordArgÚMatchÚPatternMatcherPassÚregister_graph_patternc                ó   •— t          | j        ¦  «        }|D ]e}|j        t          j        k    rN|j        d         j        ‰j        j        j        j	        u r&|j        d         dk    r|  
                    |¦  «         Œfd S )Nr   r
   )rò   r   rÔ   ÚoperatorÚgetitemrà   r„   r…   r†   r‡   r÷   )ÚgrÑ   r‹   rƒ   s      €r"   Úremove_unused_getitemz8reinplace_fsdp_all_gather.<locals>.remove_unused_getitemA  sv   ø€ å˜œ‘M”Mˆ	Øð 	 ð 	 ˆAà”�HÔ,Ò,Ð,Ø”F˜1”IÔ$¨¬	¬Ô(IÔ(QÐQÐQØ”F˜1”I ’N�Nà—’˜Q‘”�øð	 ð 	 r#   Úall_gather_inputsÚinp_split_sizesÚall_gather_input_numelÚ
world_sizeÚrankÚdtypeÚdeviceÚitem_idxÚ
group_sizeÚ
group_namec                ó$   — | j         d         dk    S )Nr  r   )Úkwargs)Úmatchs    r"   rc   z+reinplace_fsdp_all_gather.<locals>.<lambda>c  s   €  %¤,¨zÔ":¸aÒ"?€ r#   )Ú	pass_dictÚextra_checkr  r  c                ó¼   •— ˆfd„}|                       ||d         |d         |d         |d         |d         |d         |d         |d	         |d
         g	¦  «         d S )Nc                 óÞ   •— | d d…         }| d         }| d         } ‰j         j        j        j        |Ž }|d         }|d         }‰j         j        j                             ||||¬¦  «        }|S )Néþÿÿÿéÿÿÿÿr   r
   )Úout)r„   r…   r†   r‡   Ú_c10d_functionalÚall_gather_into_tensor_out)	rà   Úcopy_in_argsr  r  r†   r  Ú	getitem_1Úall_gather_into_tensorrƒ   s	           €r"   ÚreplzEreinplace_fsdp_all_gather.<locals>.reinplace_all_gather.<locals>.replf  s‹   ø€ ð     œ9ˆLØ˜bœˆJØ˜bœˆJØ!J ¤¤Ô!BÔ!JØð"Ðð )¨Ô+ˆGØ*¨1Ô-ˆIà”	Ô*ÔE×MÒMØ˜Z¨¸ð Nñ ô ð #ð
 *Ð)r#   r  r  r  r  r  r  r  r  r  )Úreplace_by_example)r  rà   r  r'  rƒ   s       €r"   Úreinplace_all_gatherz7reinplace_fsdp_all_gather.<locals>.reinplace_all_gatherN  s‘   ø€ ð0	*ð 	*ð 	*ð 	*ð 	*ð$ 	× Ò ØàÐ*Ô+ØÐ(Ô)ØÐ/Ô0Ø�|Ô$Ø�v”Ø�w”Ø�xÔ Ø�|Ô$Ø�|Ô$ð
ñ	
ô 	
ð 	
ð 	
ð 	
r#   )r  r  )Ú5torch.distributed.fsdp._fully_shard._fsdp_collectivesrŽ   r�   r„   r"  r&  r#  ÚImportErrorÚAttributeErrorr¯   Úpattern_matcherr  r  r  r  r  r‡   r
  r  r…   r†   Úapply)
r¿   r  r  r  r  r  r  Ú
graph_passr)  rƒ   s
            @r"   Úreinplace_fsdp_all_gatherr0    sM  ø€ ð
ØDÐDÐDÐDàÔ ×-Ò-Ñ/Ô/Ð/Ð/Ð/ð ŒIÔ&Ô=ð	
à”	Ô*ÔEð	
ð 	
ðFð	
øõ �­Ð8ð ð ð Øˆˆðøøøðð ð ð ð ð ð ð ð ð ð ð ð ð ðð 	 ð 	 ð 	 ð 	 ð 	 ð $Ð#Ñ%Ô%€JàÐØˆØŒIÔ&Ô=ÔEØˆLÝÔ Ø�Ø”I”NÔ5Ô=Ø�JÐ2Ñ3Ô3Ø�JÐ0Ñ1Ô1Ø�JÐ7Ñ8Ô8Ø�J˜|Ñ,Ô,Ø�J˜vÑ&Ô&Ø�J˜wÑ'Ô'Ø�J˜xÑ(Ô(ñ	ô 	ð �
˜:Ñ&Ô&ñô ð ˆJ�|Ñ$Ô$ØˆJ�|Ñ$Ô$ñ#	
ô 	
ð& Ø?Ð?ð+ñ ô ð. 
ð  
ð  
ð  
ð  
ñ/ô ð. 
ðD Ð˜%Ñ Ô Ð Ø×Ò�UÑÔÐÐÐs   ƒAA ÁA"Á!A"c                óÌ   — t          | t          j        j        j        t          j        j        j        f¦  «        rJ ‚t          |                      ¦   «         dd …         ¦  «        S )Né   )r¡   rƒ   Ú	_inductorÚ	schedulerÚFusedSchedulerNodeÚGroupedSchedulerNodeÚintr2   )r.   s    r"   Ú
get_op_idxr8  ‹  s_   € ÝØåŒOÔ%Ô8ÝŒOÔ%Ô:ð	
ñô ð ð ð õ ˆu�~Š~ÑÔ   Ô#Ñ$Ô$Ð$r#   ú1List[torch._inductor.scheduler.BaseSchedulerNode]r”   ú4Dict[str, torch._inductor.scheduler.SchedulerBuffer]r7   úDict[str, BaseSchedulerNode]c           	     óÒ	  ‡‡‡ ‡!— ddl mŠ  g }t          ¦   «         }d}d}i }i }i Š!ˆ ˆ!fd„}	| D �]Û}
t          |
j        t
          j        j        j        j	        ¬¦  «        �rÂt          ˆfd„|
j        D ¦   «         ¦  «        �r¡d}|
}t          ¦   «         }t          |||‰¦  «         t
          j        j        j        j	        t
          j        j        j        j	        t
          j        j        j        j	        hŠt!          |||‰ˆˆ fd„¬	¦  «         t#          |d
„ ¬¦  «        }t%          |¦  «        }d}t'          t%          |¦  «        ¦  «        D ]G}||         }t)          |j        t
          j        j        j        j	        ¦  «        r|dz  }|dk    r|} nŒH|d |…         }d }t'          t%          |¦  «        dz
  ¦  «        D ]1}t+          ||dz            j        t,          j        ¦  «        r|dz   } nŒ2|€J ‚ |	|d |…         ¦  «        } |	||d …         ¦  «        }|||<   �Œõt)          |
j        t
          j        j        j        j	        ¦  «        r¸d}|
}t          ¦   «         }t!          |||‰¦  «         t#          |d„ ¬¦  «        }d }t'          t%          |¦  «        dz
  ¦  «        D ]1}t+          ||dz            j        t,          j        ¦  «        r|dz   } nŒ2|€J ‚ |	|d |…         ¦  «        } |	||d …         ¦  «        }|||<   �ŒÝt%          ‰!¦  «        dk    sJ ‚|rt%          |¦  «        dk    sJ ‚|rt%          |¦  «        dk    sJ ‚| D ]a}
|
                     ¦   «         ‰!v r‰!|
                     ¦   «                  }
|
|v rŒ7|                     |
¦  «         |                     |
¦  «         Œbd }|                     ¦   «         D ]„\  }}|�{t;          t=          |                     ¦   «         ¦  «        ¦  «        }|                      ¦   «         D ]8}| !                    tE          |                     ¦   «         |¬¦  «        ¦  «         Œ9|}Œ…d }|                     ¦   «         D ]„\  }}|�{t;          t=          |                     ¦   «         ¦  «        ¦  «        }|                      ¦   «         D ]8}| !                    tE          |                     ¦   «         |¬¦  «        ¦  «         Œ9|}Œ…|S )Nr
   )r4  Fc                ó¢   •— ‰j                              | ¦  «        }| D ]}|‰|                     ¦   «         <   Œ|‰|                     ¦   «         <   |S r-   )r6  Úcreater2   )Úsnodes_to_groupÚ
group_noder.   r4  Úsnode_name_to_final_snodes      €€r"   Ú_create_group_nodez:enforce_comm_ordering_for_fsdp.<locals>._create_group_node¥  s_   ø€ ØÔ3×:Ò:¸?ÑKÔKˆ
Ø$ð 	Eð 	EˆEØ:DÐ% e§n¢nÑ&6Ô&6Ñ7Ð7Ø;EÐ! *×"5Ò"5Ñ"7Ô"7Ñ8ØÐr#   )ró   c              3  ó€   •K  — | ]8}t          ‰|         j        t          j        j        j        j        ¦  «        V — Œ9d S r-   )r   r‚   rƒ   r„   r…   r†   r‡   )rG   r_   r7   s     €r"   r‰   z1enforce_comm_ordering_for_fsdp.<locals>.<genexpr>±  sZ   øè è € ð 
ð 
ð õ Ø" 1Ô%Ô*­E¬I¬NÔ,MÔ,Uñô ð
ð 
ð 
ð 
ð 
ð 
r#   Tc                óv   •— t          | ‰j        ¦  «        p"t          | ‰j        ¦  «        o| j        j        ‰v  S r-   )r¡   ÚNopKernelSchedulerNodeÚExternKernelSchedulerNoder‚   Úop_overload)r_   Úallowed_opsr4  s    €€r"   rc   z0enforce_comm_ordering_for_fsdp.<locals>.<lambda>Î  sA   ø€ Ý˜q )Ô"BÑCÔCð å" 1 iÔ&IÑJÔJð >ØœFÔ.°+Ð=ð	'€ r#   )Úcriteria_cbc                ó    — t          | ¦  «        S r-   ©r8  rb   s    r"   rc   z0enforce_comm_ordering_for_fsdp.<locals>.<lambda>Ù  ó   € µJ¸q±M´M€ r#   rd   r   c                ó    — t          | ¦  «        S r-   rK  rb   s    r"   rc   z0enforce_comm_ordering_for_fsdp.<locals>.<lambda>
  rL  r#   rŒ   )#rŸ   r4  rs   r   r‚   rƒ   r„   r"  r#  r‡   r�   rr   r   Úwait_tensorr…   Úsplit_with_sizes_copyr   ÚsortedrS   r’   r   r¡   r   Ú_WaitKernelrˆ   r2   rP   ru   rt   r/   r0   rQ   Úget_outputsr“   r   )"r   r”   r7   Ú	new_orderrY   Ú	ag_existsÚ	rs_existsÚ$ag_grouped_node_to_wait_grouped_nodeÚ$rs_grouped_node_to_wait_grouped_noderB  r.   Úag_snodeÚag_related_snode_setÚag_related_snodesÚend_idx_of_current_ag_blockÚcopy_out_countr–   Ú	cur_snodeÚwait_node_idxÚag_group_nodeÚag_wait_group_nodeÚrs_snodeÚrs_related_snode_setÚrs_related_snodesÚrs_group_nodeÚrs_wait_group_nodeÚprev_ag_waitÚwait_group_noder�   ÚoÚprev_rs_waitrH  r4  rA  s"     `                            @@@r"   r‘   r‘   –  sC  øøøø€ ð
 ÐÐÐÐÐà)+€IÝ‘”€IØ€IØ€IØ+-Ð(Ø+-Ð(Ø "Ððð ð ð ð ð ð ð lUñ lUˆåØŒJ�5œ9Ô5ÔPÔXð
ñ 
ô 
ñ j	Uåð 
ð 
ð 
ð 
ð ”_ð	
ñ 
ô 
ñ 
ô 
ñj	Uð ˆIØˆHÝEHÁUÄUÐ õ (ØØ$ØØ"ñ	ô ð õ ”	Ô*ÔEÔMÝ”	Ô*Ô6Ô>Ý”	”Ô4Ô<ðˆKõ
 )ØØ$ØØ"ðð ð ð ð ðñ ô ð õ !'Ø$Ð*AÐ*Að!ñ !ô !Ðõ +.Ð.?Ñ*@Ô*@Ð'ØˆNÝ�3Ð0Ñ1Ô1Ñ2Ô2ð ð �Ø-¨aÔ0�	Ý!Ø”N¥E¤I¤NÔ$HÔ$Pñô ð (ð # aÑ'�NØ! AÒ%Ð%Ø23Ð/Ø�Eð &ð !2Ð2NÐ3NÐ2NÔ OÐð !ˆMÝ�3Ð0Ñ1Ô1°AÑ5Ñ6Ô6ð ð �ÝÐ/°°A±Ô6Ô;½R¼^ÑLÔLð Ø$%¨¡E�MØ�Eðð !Ð,Ð,Ð,Ø.Ð.Ð/@ÀÀ-ÀÔ/PÑQÔQˆMð "4Ð!3Ð4EÀmÀnÀnÔ4UÑ!VÔ!VÐàBTÐ0°Ñ?Ñ?õ ˜EœJ­¬	¬Ô(@Ô(HÑIÔIð 	UØˆIØˆHõ FIÁUÄUÐ Ý(ØØ$ØØ"ñ	ô ð õ !'Ø$Ð*AÐ*Að!ñ !ô !Ðð
 !ˆMÝ�3Ð0Ñ1Ô1°AÑ5Ñ6Ô6ð ð �ÝÐ/°°A±Ô6Ô;½R¼^ÑLÔLð Ø$%¨¡E�MØ�Eðð !Ð,Ð,Ð,Ø.Ð.Ð/@ÀÀ-ÀÔ/PÑQÔQˆMð "4Ð!3Ð4EÀmÀnÀnÔ4UÑ!VÔ!VÐàBTÐ0°Ñ?ùåÐ(Ñ)Ô)¨AÒ-Ð-Ð-Ð-Øð =ÝÐ7Ñ8Ô8¸1Ò<Ð<Ð<Ð<Øð =ÝÐ7Ñ8Ô8¸1Ò<Ð<Ð<Ð<ð ð ð ˆØ�>Š>ÑÔÐ8Ð8Ð8Ø-¨e¯nªnÑ.>Ô.>Ô?ˆEØ�IÐÐØØ×Ò˜ÑÔÐØ�Š�eÑÔÐÐð €LØ*N×*TÒ*TÑ*VÔ*Vð 'ð 'Ñ&ˆ�ØÐ#Ý¥ ]×%CÒ%CÑ%EÔ%EÑ FÔ FÑGÔGˆLØ!×-Ò-Ñ/Ô/ð ð �Ø×*Ò*Ý˜AŸJšJ™LœL°|ÐDÑDÔDñô ð ð ð 'ˆˆð €LØ*N×*TÒ*TÑ*VÔ*Vð 'ð 'Ñ&ˆ�ØÐ#Ý¥ ]×%CÒ%CÑ%EÔ%EÑ FÔ FÑGÔGˆLØ!×-Ò-Ñ/Ô/ð ð �Ø×*Ò*Ý˜AŸJšJ™LœL°|ÐDÑDÔDñô ð ð ð 'ˆˆàÐr#   )r   r   r   r   )
r   r   r   r'   r   r'   r   r'   r   r   )r   r   r   r   )r.   r   r   r™   )r¿   rÀ   )r¿   rÀ   r   r+   )r   r9  r”   r:  r7   r;  r   r9  )2Ú
__future__r   rT   Úloggingr
  rp   Úcollectionsr   Útypingr   r   r   r   rƒ   Ú torch.multiprocessing.reductionsr	   rŸ   r   r   Údependenciesr   Úutilsr   r   r   r   r   r   r   Ú	getLoggerr@   rÇ   Ú_loggingÚgetArtifactLoggerr°   r4  r   r   r   r&   r    r˜   rN   r­   rµ   r¾   r  r0  r8  r‘   rF   r#   r"   ú<module>rt     so  ðð #Ð "Ð "Ð "Ð "Ð "à €€€Ø €€€Ø €€€Ø 
€
€
€
Ø #Ð #Ð #Ð #Ð #Ð #Ø 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1à €€€Ø ;Ð ;Ð ;Ð ;Ð ;Ð ;à Ð Ð Ð Ð Ð Ð Ð Ø !Ð !Ð !Ð !Ð !Ð !ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð €gÔ˜Ñ!Ô!€ØŒn×.Ò.¨x¸ÑCÔC€àð -Ø,Ð,Ð,Ð,Ð,Ð,ðð ð ð ðð ð ð ðð ð ð ð&Wð Wð Wð Wðt ð  ð  ð  ðF	ð 	ð 	ð 	ð	Uð 	Uð 	Uðð ð ð>ð ð ð ð8A#ð A#ð A#ð A#ðHlð lð lð lð^%ð %ð %ðlð lð lð lð lð lr#   