Ë
    ÄÓ^j™  ã                  ó  — U d dl mZ d dlZd dl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 d dlZd dlmZ d dlmZ d dlmZ d d	lmZmZ erd d
lmZ d dlmZ  ej:                  e«      Z G d„ de«      Z e!e!e"df   edz  f   Z#de$d<    G d„ de%«      Z& edd¬«       G d„ d«      «       Z' edd¬«       G d„ de'«      «       Z(e'e(z  Z)de$d<    ed¬«       G d„ d«      «       Z* edd¬«       G d„ d«      «       Z+ edd¬«       G d„ d «      «       Z,	 	 	 	 	 	 d<d!„Z-	 	 	 	 d=d"„Z. G d#„ d$«      Z/ G d%„ d&e«      Z0d'd(œd>d)„Z1d*„ Z2	 d?	 	 	 	 	 	 	 d@d+„Z3	 d?	 	 	 	 	 	 	 dAd,„Z4 ed¬«       G d-„ d.«      «       Z5dBd/„Z6edd0œ	 	 	 	 	 dCd1„«       Z7e	 	 	 	 	 	 dDd2„«       Z7d'd0œ	 	 	 	 	 dEd3„Z7dFdGd4„Z8e	 dH	 	 	 	 	 dId5„«       Z9e	 dH	 	 	 	 	 dJd6„«       Z9	 dF	 	 	 	 	 dKd7„Z9d'd'd8œ	 	 	 	 	 	 	 	 	 	 	 dLd9„Z:dd'd8œ	 	 	 	 	 	 	 	 	 	 	 dMd:„Z;	 	 	 	 	 	 	 	 	 	 dNd;„Z<y)Oé    )ÚannotationsN)Ú	dataclassÚfield)ÚEnum)ÚcastÚLiteralÚoverloadÚProtocolÚTYPE_CHECKINGÚ	TypeAlias)Úfx)Ú_MeshLayout)ÚDTensor)Útree_flattenÚtree_unflatten)Ú
DeviceMesh)Ú	Placementc                  ó$   — e Zd ZdZ	 	 	 	 	 	 dd„Zy)ÚGetMeshCallbackzGCallback to create/retrieve a DeviceMesh from its cache key components.c                 ó   — y ©N© )ÚselfÚmesh_dim_namesÚmesh_layouts      ún/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/torch/distributed/pipelining/_utils.pyÚ__call__zGetMeshCallback.__call__   s   € ð ó    N)r   útuple[str, ...]r   ú_MeshLayout | NoneÚreturnr   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r      s&   „ ÙQðà'ðð (ðð 
ô	r   r   .r   ÚMeshCacheKeyc                  ó   — e Zd ZdZy)ÚPipeliningMetadataErrorz<Raised on metadata mismatches during pipeline communication.N)r"   r#   r$   r%   r   r   r   r(   r(   ,   s   „ ÚFr   r(   T)ÚfrozenÚslotsc                  ó\   — e Zd ZU dZded<   ded<   ded<   ded	<   edd
„«       Zdd„Zdd„Zy)Ú_TensorMetazðTensor metadata for recv buffer allocation and validation.

    For plain tensors, these are the tensor's actual attributes.
    For DTensors, these are LOCAL shard attributes; global attributes
    are stored in :class:`_DTensorMeta`.
    ú
torch.SizeÚshapeútuple[int, ...]Ústrideztorch.dtypeÚdtypeÚboolÚrequires_gradc                ó®   — t        | t        «      rt        d«      ‚t        | j                  | j                  «       | j                  | j                  ¬«      S )a  Create metadata from a plain tensor.

        Args:
            tensor: A plain ``torch.Tensor`` (not DTensor).

        Returns:
            Metadata capturing shape, stride, dtype, and requires_grad.

        Raises:
            TypeError: If ``tensor`` is a DTensor.
        zJExpected plain tensor, got DTensor. Use _DTensorMeta.from_dtensor instead.©r.   r0   r1   r3   )Ú
isinstancer   r(   r,   r.   r0   r1   r3   ©Útensors    r   Úfrom_tensorz_TensorMeta.from_tensor>   sM   € ô �fœgÔ&Ü)Ø\óð ô Ø—,‘,Ø—=‘=“?Ø—,‘,Ø ×.Ñ.ô	
ð 	
r   c                ót   — t        | |«      }|j                  «       r|j                  | j                  «       |S )zÅReconstruct a tensor on ``device`` from this metadata.

        Args:
            device: Target device for the tensor.

        Returns:
            An empty strided tensor on ``device``.
        )Ú_make_tensor_from_metaÚis_floating_pointÚrequires_grad_r3   )r   ÚdeviceÚts      r   Ú	to_tensorz_TensorMeta.to_tensorV   s5   € ô # 4¨Ó0ˆØ×ÑÔ Ø×Ñ˜T×/Ñ/Ô0Øˆr   c                ó°  — | |k(  rg S g }| j                   |j                   k7  r+|j                  d| j                   › d|j                   › �«       | j                  |j                  k7  r+|j                  d| j                  › d|j                  › �«       | j                  |j                  k7  r+|j                  d| j                  › d|j                  › �«       |S )zÓReturn field-by-field differences with ``other``.

        Args:
            other: Metadata to compare against.

        Returns:
            List of human-readable difference strings (empty if equal).
        zshape mismatch: ú vs zstride mismatch: zdtype mismatch: )r.   Úappendr0   r1   ©r   ÚotherÚdiffss      r   Úget_diffz_TensorMeta.get_diffd   s²   € ð �5Š=ØˆIàˆØ�:‰:˜Ÿ™Ò$Ø�L‰LÐ+¨D¯J©J¨<°t¸E¿K¹K¸=ÐIÔJØ�;‰;˜%Ÿ,™,Ò&Ø�L‰LÐ,¨T¯[©[¨M¸¸e¿l¹l¸^ÐLÔMØ�:‰:˜Ÿ™Ò$Ø�L‰LÐ+¨D¯J©J¨<°t¸E¿K¹K¸=ÐIÔJð ˆr   N)r8   útorch.Tensorr!   r,   )r>   útorch.device | strr!   rH   ©rE   r,   r!   ú	list[str])	r"   r#   r$   r%   Ú__annotations__Ústaticmethodr9   r@   rG   r   r   r   r,   r,   0   s=   … ñð ÓØÓØÓØÓàò
ó ð
ó.ôr   r,   c                  óÔ   — e Zd ZU dZ ed„ ¬«      Zded<    ed¬«      Zded	<    ed¬«      Zd
ed<    ed¬«      Z	ded<    ed¬«      Z
ded<   edd„«       Zedd„«       Zdd„Zdd„Zy)Ú_DTensorMetaaÔ  DTensor metadata extending :class:`_TensorMeta` with distribution info.

    Inherited fields (shape, stride, etc.) are LOCAL shard attributes.
    Additional fields capture global shape and placement information
    needed to reconstruct a :class:`DTensor` via ``DTensor.from_local()``.

    The :class:`DeviceMesh` is **not** stored (not serializable for P2P);
    it is looked up from :class:`_MeshCache` using
    ``(mesh_dim_names, mesh_layout)`` as the key.
    c                 ó,   — t        j                  g «      S r   )ÚtorchÚSizer   r   r   ú<lambda>z_DTensorMeta.<lambda>Š   s   € ¼U¿Z¹ZÈ»^€ r   )Údefault_factoryr-   Úglobal_shaper   )Údefaultr/   Úglobal_strideztuple[Placement, ...]Ú
placementsr   r   Nr    r   c                óp  — | j                   }t        | j                  j                  | j                  j	                  «       | j
                  | j                  | j                  | j	                  «       | j                  j                  |j                  rt        |j                  «      nd|j                  ¬«	      S )zÅCreate metadata from a DTensor.

        Args:
            dtensor: The DTensor to extract metadata from.

        Returns:
            Metadata capturing both local and global attributes.
        r   )	r.   r0   r1   r3   rU   rW   rX   r   r   )Údevice_meshrO   Ú_local_tensorr.   r0   r1   r3   Ú_specrX   r   ÚtupleÚ_layout)ÚdtensorrZ   s     r   Úfrom_dtensorz_DTensorMeta.from_dtensor˜   s�   € ð ×)Ñ)ˆäà×'Ñ'×-Ñ-Ø×(Ñ(×/Ñ/Ó1Ø—-‘-Ø!×/Ñ/à Ÿ™Ø!Ÿ.™.Ó*à—}‘}×/Ñ/à5@×5OÒ5O”�k×0Ñ0Ô1ÐUWà#×+Ñ+ô
ð 	
r   c                ó2   — | j                   | j                  fS )z<Cache key ``(mesh_dim_names, mesh_layout)`` for mesh lookup.)r   r   ©r   s    r   Úmesh_cache_keyz_DTensorMeta.mesh_cache_keyµ   s   € ð ×#Ñ# T×%5Ñ%5Ð6Ð6r   c                ó  — t        | |«      }t        j                  ||| j                  | j                  | j
                  d¬«      }| j                  r!|j                  «       r|j                  d«      }t        t        |«      S )zëReconstruct a DTensor on ``device`` with placements.

        Args:
            device: Target device for the local tensor.
            mesh: The ``DeviceMesh`` to attach.

        Returns:
            A DTensor on ``device``.
        F)rZ   rX   r.   r0   Ú	run_checkT)
r;   r   Ú
from_localrX   rU   rW   r3   r<   r=   r   )r   r>   ÚmeshÚlocal_tensorÚdts        r   Ú
to_dtensorz_DTensorMeta.to_dtensorº   sw   € ô .¨d°FÓ;ˆô ×ÑØØØ—‘Ø×#Ñ#Ø×%Ñ%Øô
ˆð ×Ò "×"6Ñ"6Ô"8Ø×"Ñ" 4Ó(ˆBÜ”G˜RÓ Ð r   c                ó0  — | |k(  rg S t         j                  | |«      }t        |t        «      �rV| j                  |j                  k7  r+|j                  d| j                  › d|j                  › �«       | j                  |j                  k7  r+|j                  d| j                  › d|j                  › �«       | j                  |j                  k7  r+|j                  d| j                  › d|j                  › �«       | j                  |j                  k7  r+|j                  d| j                  › d|j                  › �«       | j                  |j                  k7  r+|j                  d| j                  › d|j                  › �«       |S |j                  d«       |S )zçReturn field-by-field differences, including DTensor-specific fields.

        Args:
            other: Metadata to compare against.

        Returns:
            List of human-readable difference strings (empty if equal).
        zglobal_shape mismatch: rB   zglobal_stride mismatch: zplacements mismatch: zmesh_dim_names mismatch: zmesh_layout mismatch: z!type: _DTensorMeta vs _TensorMeta)
r,   rG   r6   rO   rU   rC   rW   rX   r   r   rD   s      r   rG   z_DTensorMeta.get_diffÓ   s…  € ð �5Š=ØˆIô
 ×$Ñ$ T¨5Ó1ˆô �eœ\Õ*Ø× Ñ  E×$6Ñ$6Ò6Ø—‘Ø-¨d×.?Ñ.?Ð-@ÀÀU×EWÑEWÐDXÐYôð ×!Ñ! U×%8Ñ%8Ò8Ø—‘Ø.¨t×/AÑ/AÐ.BÀ$Àu×GZÑGZÐF[Ð\ôð �‰ %×"2Ñ"2Ò2Ø—‘Ø+¨D¯O©OÐ+<¸DÀ×AQÑAQÐ@RÐSôð ×"Ñ" e×&:Ñ&:Ò:Ø—‘Ø/°×0CÑ0CÐ/DÀDÈ×I]ÑI]ÐH^Ð_ôð ×Ñ 5×#4Ñ#4Ò4Ø—‘Ø,¨T×-=Ñ-=Ð,>¸dÀ5×CTÑCTÐBUÐVôð ˆð �L‰LÐ<Ô=àˆr   )r_   r   r!   rO   )r!   r&   )r>   rI   rg   r   r!   r   rJ   )r"   r#   r$   r%   r   rU   rL   rW   rX   r   r   rM   r`   Úpropertyrc   rj   rG   r   r   r   rO   rO   |   s—   … ñ	ñ  %Ñ5KÔL€L�*ÓLÙ%*°2Ô%6€M�?Ó6ñ ).Øô)€JÐ%ó ñ
 ',°BÔ&7€N�OÓ7Ù&+Øô'€KÐ#ó ð ò
ó ð
ð8 ò7ó ð7ó!ô2*r   rO   Ú
TensorMeta)r*   c                  ób   — e Zd ZU dZdZded<   dZded<   dZded<   dZded<   dd	„Z	dd
„Z
dd„Zy)Ú
_StageMetazPConsolidated tensor metadata for a pipeline stage's forward and backward passes.Nútuple[TensorMeta, ...] | NoneÚinputsÚoutputsú$tuple[TensorMeta | None, ...] | NoneÚinput_gradsÚoutput_gradsc                ó~   — t        d„ | j                  | j                  | j                  | j                  fD «       «      S )z)Check if any metadata field is populated.c              3  ó$   K  — | ]  }|d u–— Œ
 y ­wr   r   )Ú.0Úvs     r   ú	<genexpr>z%_StageMeta.has_any.<locals>.<genexpr>  s   è ø€ ò 
àð �TŒMñ
ùs   ‚)Úanyrq   rr   rt   ru   rb   s    r   Úhas_anyz_StageMeta.has_any  s9   € äñ 
à—k‘k 4§<¡<°×1AÑ1AÀ4×CTÑCTÐUô
ó 
ð 	
r   c                ól   — | j                   | j                  fD ]  }|sŒt        d„ |D «       «      sŒ y y)z3Check if any input/output metadata is DTensor type.c              3  óB   K  — | ]  }|sŒt        |t        «      –— Œ y ­wr   )r6   rO   )rx   Úms     r   rz   z*_StageMeta.has_dtensors.<locals>.<genexpr>  s   è ø€ ÒM¸QÊ1œZ¨¬<×8ÑMùs   ‚ŠTF)rq   rr   r{   )r   Úmetass     r   Úhas_dtensorsz_StageMeta.has_dtensors  s6   € à—k‘k 4§<¡<Ð0ò 	ˆEÚœÑMÀ%ÔMÕMÙð	ð r   c                ó>   — | j                   duxr | j                  duS )z-Check if forward metadata is fully populated.N)rq   rr   rb   s    r   Úis_complete_for_forwardz"_StageMeta.is_complete_for_forward  s   € à�{‰{ $Ð&ÒC¨4¯<©<¸tÐ+CÐCr   )r!   r2   )r"   r#   r$   r%   rq   rL   rr   rt   ru   r|   r�   rƒ   r   r   r   ro   ro     sA   … áZà,0€FÐ)Ó0Ø-1€GÐ*Ó1Ø8<€KÐ5Ó<Ø9=€LÐ6Ó=ó
óôDr   ro   c                  ó   — e Zd ZU dZded<   y)Ú_StageForwardMetazLForward metadata transmitted from stage *i* to stage *i+1* during inference.útuple[TensorMeta, ...]Úforward_metasN©r"   r#   r$   r%   rL   r   r   r   r…   r…   "  s   … áVà)Ô)r   r…   c                  ó   — e Zd ZU dZded<   y)Ú_StageBackwardMetauº   Backward metadata transmitted from stage *i* to stage *i-1* during inference.

    Gradient placements may differ from forward activations
    (e.g., ``Replicate`` â†’ ``Partial``).
    útuple[TensorMeta | None, ...]Úbackward_metasNrˆ   r   r   r   rŠ   rŠ   )  s   … ñðô r   rŠ   c                óp   — t        j                  | j                  | j                  | j                  |¬«      S )zÙCreate a tensor from metadata.

    Args:
        meta: Metadata with shape, stride, and dtype.
        device: Target device for the tensor.

    Returns:
        Empty tensor preserving the exact memory layout.
    )Úsizer0   r1   r>   )rQ   Úempty_stridedr.   r0   r1   )Úmetar>   s     r   r;   r;   6  s/   € ô ×ÑØ�Z‰ZØ�{‰{Ø�j‰jØô	ð r   c                ó4   ‡— dd„Št        ˆfd„| D «       «      S )zÑDerive gradient metadata from tensor metadata.

    Returns metadata with the same shape/stride/dtype but ``requires_grad=False``.
    Entries where the source has ``requires_grad=False`` become ``None``.
    c                ó˜   — | j                   sy t        | t        «      ry t        | j                  | j
                  | j                  d¬«      S )NFr5   )r3   r6   rO   r,   r.   r0   r1   )r   s    r   Ú
derive_onez&_derive_grad_metas.<locals>.derive_oneT  s>   € Ø�ŠØÜ�aœÔ&ØÜØ—'‘'Ø—8‘8Ø—'‘'Øô	
ð 	
r   c              3  ó.   •K  — | ]  } ‰|«      –— Œ y ­wr   r   )rx   r   r“   s     €r   rz   z%_derive_grad_metas.<locals>.<genexpr>`  s   øè ø€ Ò5 1‘˜A—Ñ5ùs   ƒ)r   rm   r!   zTensorMeta | None)r]   )Útensor_metasr“   s    @r   Ú_derive_grad_metasr–   K  s   ø€ ó

ô Ó5¨Ô5Ó5Ð5r   c                  óB   — e Zd ZdZd	d
d„Zdd„Zdd„Zdd„Zdd„Zdd„Z	y)Ú
_MeshCachezæCache for :class:`DeviceMesh` objects keyed by ``(mesh_dim_names, mesh_layout)``.

    Assumes all pipeline stages share the same rank tensor (true for
    TorchTitan-style frameworks where meshes derive from a common world).
    Nc                ó    — i | _         || _        y r   )Ú_cacheÚ_get_mesh_cb)r   Úget_mesh_cbs     r   Ú__init__z_MeshCache.__init__j  s   € Ø68ˆŒØ'ˆÕr   c                óð   — || j                   v r| j                   |   S |\  }}| j                  €t        d|› d|› d�«      ‚| j                  ||«      }|€t        d|› d|› d�«      ‚|| j                   |<   |S )a  Return a cached mesh, or create one via the callback.

        Args:
            key: Cache key ``(mesh_dim_names, mesh_layout)``.

        Returns:
            The ``DeviceMesh``.

        Raises:
            PipeliningMetadataError: If not cached and no callback provided.
        z+Mesh not found in cache for mesh_dim_names=z, mesh_layout=z`, and no get_mesh callback provided. Provide a get_mesh callback or use DTensors in static mode.z>Mesh lookup failed: callback returned None for mesh_dim_names=z6. Ensure all stages use meshes from the same universe.)rš   r›   r(   )r   Úkeyr   r   rg   s        r   Úget_meshz_MeshCache.get_meshn  sº   € ð �$—+‘+ÑØ—;‘;˜sÑ#Ð#à&)Ñ#ˆ˜à×ÑÐ$Ü)Ø=¸nÐ=Mð NØ*˜mð ,NðOóð ð × Ñ  °Ó=ˆØˆ<Ü)ð"Ø"0Ð!1°À¸}ð MGðHóð ð
  ˆ�‰�CÑØˆr   c                ó"   — || j                   |<   y)zAdd a mesh to the cache.N©rš   )r   rŸ   rg   s      r   Úputz_MeshCache.put�  s   € àˆ�‰�CÒr   c                óî   — |D ]p  }t        |t        «      sŒ|j                  }|j                  rt	        |j                  «      nd}|j
                  }||f}|| j                  vsŒb|| j                  |<   Œr y)zJExtract and cache meshes from any :class:`DTensor` instances in *tensors*.r   N)r6   r   rZ   r   r]   r^   rš   )r   Útensorsr8   rg   Ú	dim_namesr   rŸ   s          r   Úupdate_from_tensorsz_MeshCache.update_from_tensors”  sn   € àò 	,ˆFÜ˜&¤'Õ*Ø×)Ñ)�Ø:>×:MÒ:MœE $×"5Ñ"5Ô6ÐSU�	Ø"Ÿl™l�Ø  +Ð.�Ø˜dŸk™kÒ)Ø'+�D—K‘K Ò$ñ	,r   c                ó   — || j                   v S r   r¢   )r   rŸ   s     r   Ú__contains__z_MeshCache.__contains__Ÿ  s   € Ø�d—k‘kÐ!Ð!r   c                ó,   — t        | j                  «      S r   )Úlenrš   rb   s    r   Ú__len__z_MeshCache.__len__¢  s   € Ü�4—;‘;ÓÐr   r   )rœ   zGetMeshCallback | Noner!   ÚNone)rŸ   r&   r!   r   )rŸ   r&   rg   r   r!   r­   )r¥   útuple[torch.Tensor | None, ...]r!   r­   )rŸ   r&   r!   r2   )r!   Úint)
r"   r#   r$   r%   r�   r    r£   r§   r©   r¬   r   r   r   r˜   r˜   c  s&   „ ñô(ó óD ó	,ó"ô r   r˜   c                  ó*   — e Zd ZdZdZdZedd„«       Zy)ÚInferenceModeaÑ  Pipeline-level metadata inference mode, determined collectively across all PP ranks.

    The mode is set by the schedule (not individual stages) because
    ``has_backward`` is only known at schedule creation time and all
    stages must agree to avoid P2P hangs.

    .. attribute:: STATIC

        All stages have sufficient metadata; runtime inference is skipped.

    .. attribute:: DYNAMIC

        At least one stage requires runtime metadata inference.
    ÚstaticÚdynamicc                ó€   — |j                  «       sy|j                  «       sy|sy|j                  �|j                  €yy)a'  Determine whether dynamic metadata inference is needed for a stage.

        Args:
            meta: Stage metadata from user-provided args.
            stage_has_backward: Whether a backward pass will be performed.

        Returns:
            ``True`` if dynamic inference is needed.
        TF)rƒ   r�   rt   ru   )Úclsr�   Ústage_has_backwards      r   Úneeds_dynamiczInferenceMode.needs_dynamic¾  sM   € ð ×+Ñ+Ô-Øð × Ñ Ô"Øñ "Øð ×ÑÐ# t×'8Ñ'8Ð'@Øð r   N)r�   ro   r¶   r2   r!   r2   )r"   r#   r$   r%   ÚSTATICÚDYNAMICÚclassmethodr·   r   r   r   r±   r±   «  s%   „ ñð €FØ€Gàòó ñr   r±   F©Údetachc               óô   — t        | «      \  }}|rb|D �cg c]G  }t        |t        j                  «      r)|j	                  «       j                  |j                  «      n|‘ŒI }}t        ||«      }||fS |S c c}w )a;  Flatten ``args`` into a list, optionally detaching tensors.

    Args:
        args: Nested arguments to flatten.
        detach: If ``True``, detach tensors while preserving ``requires_grad``.

    Returns:
        ``(new_args, flat_detached_args)`` when ``detach=True``;
        ``flat_args`` list otherwise.
    )r   r6   rQ   ÚTensorr¼   r=   r3   r   )Úargsr¼   Ú	flat_argsÚtreespecÚaÚflat_detachedÚnew_argss          r   Úflatten_argsrÅ   ã  sˆ   € ô ' tÓ,Ñ€Iˆxáð
 ö	
ð ô ˜!œUŸ\™\Ô*ð �H‰H‹J×%Ñ% a§o¡oÔ6àñð
ˆð 
ô " -°Ó:ˆØ˜Ð&Ð&àÐùò
s   •AA5c                ó   — t        | d¬«      S )zHFlatten and detach. Deprecated: use ``flatten_args(args, detach=True)``.Tr»   )rÅ   )r¿   s    r   Úflatten_args_detachrÇ   þ  s   € ä˜ TÔ*Ð*r   c                ó  — i }|dk(  rt        |«      D ]
  }|| z  ||<   Œ |S |dk(  rU|| z  dk7  rt        d|› d| › d�«      ‚d}t        |«      D ])  }|||<   |dz   | z  dk(  rŒ|| z  dz  dk(  r|dz  }Œ%|dz  }Œ+ |S t        d	|› d
�«      ‚)zá
    Compute the stage id to rank mapping for either a looped or V-style schedule.

    Most commonly num_stages == pp_size * 2, but this function can be used to
    compute the mapping for any number of stages per rank.
    Úloopry   r   znum_stages z% must be evenly divisible by pp_size z for V schedulesé   é   zStyle z is not supported.)ÚrangeÚ
ValueError)Úpp_sizeÚ
num_stagesÚstyleÚmappingÚstage_indexÚ
rank_indexs         r   Úgenerate_stage_to_rank_mappingrÔ     sì   € ð €GØ�‚Ü  Ó,ò 	9ˆKØ#.°Ñ#8ˆG�KÒ ð	9ð( €Nð% 
�#ŠØ˜Ñ 1Ò$ÜØ˜j˜\Ð)NÈwÈiÐWgÐhóð ð ˆ
Ü  Ó,ò 	 ˆKØ#-ˆG�KÑ à˜a‘ 7Ñ*¨aÒ/ØØ˜wÑ&¨!Ñ+¨qÒ0Ø˜a‘‘
à˜a‘‘
ð	 ð €Nô ˜6 % Ð(:Ð;Ó<Ð<r   c                óØ   — t        | ||«      }i }|j                  «       D ]"  \  }}||vrg ||<   ||   j                  |«       Œ$ |j                  «       D ]  }|j	                  «        Œ |S )a  
    Compute the rank to stage id mapping for either a looped or V-style schedule.

    This function inverts the stage_to_rank_mapping to get which stages are assigned to each rank.

    Returns a dictionary mapping rank -> list of stage indices assigned to that rank.
    )rÔ   ÚitemsrC   ÚvaluesÚsort)rÎ   rÏ   rÐ   Ústage_to_rankÚrank_to_stagesÚstage_idÚrankÚstagess           r   Úgenerate_rank_to_stage_mappingrÞ   %  s…   € ô 3°7¸JÈÓN€Mð ,.€NØ'×-Ñ-Ó/ò .‰ˆ�$Ø�~Ñ%Ø#%ˆN˜4Ñ Ø�tÑ×#Ñ# HÕ-ð.ð !×'Ñ'Ó)ò ˆØ�‰�ðð Ðr   c                  ó0   — e Zd ZU dZded<   ded<   ded<   y)	ÚPipeInfoz>
    Captures information for a pipeline (`Pipe` object).
    zfx.GraphÚgraphr¯   rÏ   r2   Úhas_loss_and_backwardNrˆ   r   r   r   rà   rà   ?  s   … ñð ƒOØƒOØÔr   rà   c                óv   — t        | t        «      rt        j                  | «      S t        j                  | «      S )aª  Extract metadata from a tensor.

    Handles both plain Tensor and DTensor correctly: DTensors are
    dispatched to ``_DTensorMeta.from_dtensor`` which captures local
    shard attributes plus global shape/placement info, while plain
    tensors use ``_TensorMeta.from_tensor``.

    Args:
        tensor: A plain tensor or DTensor.

    Returns:
        ``_TensorMeta`` for plain tensors, ``_DTensorMeta`` for DTensors.
    )r6   r   rO   r`   r,   r9   r7   s    r   Úextract_tensor_metarä   O  s0   € ô �&œ'Ô"Ü×(Ñ(¨Ó0Ð0ä×&Ñ& vÓ.Ð.r   )Ú
allow_nonec                ó   — y r   r   ©r¥   rå   s     r   Úextract_tensor_metasrè   c  s   € ð
 %(r   c                ó   — y r   r   rç   s     r   rè   rè   k  s   € ð
 ,/r   c               óâ   — | €yg }d}| D ]J  }t        |t        j                  «      r|j                  t	        |«      «       Œ8d}|j                  d«       ŒL |s|rt        d«      ‚t        |«      S )aŠ  Extract metadata from a tuple of tensors.

    Args:
        tensors: Tuple of tensors (may include ``None`` when ``allow_none=True``).
        allow_none: If ``True``, preserve ``None`` elements (for gradients).

    Returns:
        Tuple of ``TensorMeta``, or ``None`` if ``tensors`` is ``None``.

    Raises:
        PipeliningMetadataError: If ``None`` found and ``allow_none=False``.
    NFTz_None values are not allowed in tensor metadata tuples. Use allow_none=True for optional values.)r6   rQ   r¾   rC   rä   r(   r]   )r¥   rå   Úmetas_with_noneÚhas_noner?   s        r   rè   rè   s  s€   € ð" €Øà/1€OØ€HØò )ˆÜ�aœŸ™Ô&Ø×"Ñ"Ô#6°qÓ#9Õ:àˆHØ×"Ñ" 4Õ(ð)ñ ™(Ü%ð7ó
ð 	
ô �Ó!Ð!r   c                ón   — |r| j                  «       n| }t        |t        «      r|j                  «       S |S )u£  Convert a DTensor to its local shard, or return a plain tensor as-is.

    When ``detach=True``, the tensor is detached before conversion â€”
    this applies to both DTensors and plain tensors.

    Args:
        tensor: A tensor that may be a DTensor.
        detach: If ``True``, detach before ``to_local()`` to avoid
            redistribution during backward.

    Returns:
        The local tensor component.
    )r¼   r6   r   Úto_local)r8   r¼   Úmaybe_detached_tensors      r   Úto_local_if_dtensorrð   —  s4   € ñ 06˜FŸM™MœO¸6ÐÜÐ'¬Ô1Ø$×-Ñ-Ó/Ð/Ø Ð r   c                 ó   — y r   r   ©r¿   rå   s     r   Úvalidate_and_normalize_to_tupleró   «  s   € ð '*r   c                 ó   — y r   r   rò   s     r   ró   ró   ²  s   € ð .1r   c           	     ó¸  — | €yt        | t        j                  «      r| fS t        | t        t        f«      rƒt        | «      D ]X  \  }}|€|st        d|› d�«      ‚Œt        |t        j                  «      rŒ5t        d|› dt        |«      j                  › d�«      ‚ t        | t        «      rt        | «      S | S t        dt        | «      j                  › d�«      ‚)a¬  Normalize ``args`` to a tuple and validate that all elements are tensors.

    Args:
        args: A single tensor, tuple/list of tensors, or ``None``.
        allow_none: If ``True``, permit ``None`` elements (for gradients).

    Returns:
        Tuple of tensors, or ``None`` if ``args`` is ``None``.

    Raises:
        PipeliningMetadataError: On non-tensor values
            (or ``None`` when ``allow_none=False``).
    Nz
Stage arg[zF] is None. Stage args must be tensors. Use kwargs for optional values.z] has type zC. All stage args must be tensors. Use kwargs for non-tensor inputs.z<Stage args must be a tensor, tuple, or list of tensors, got ú.)	r6   rQ   r¾   r]   ÚlistÚ	enumerater(   Útyper"   )r¿   rå   ÚiÚargs       r   ró   ró   ¼  só   € ð, €|ØÜ	�Dœ%Ÿ,™,Ô	'ØˆwˆÜ	�Dœ5¤$˜-Ô	(Ü “oò 	‰FˆAˆsØˆ{Ù!Ü1Ø$ Q Cð (Vð Wóð ð Ü˜c¤5§<¡<Õ0Ü-Ø    ;¬t°C«y×/AÑ/AÐ.Bð CXð Yóð ð	ô )¨¬tÔ4Œu�T‹{Ð>¸$Ð>ä%ØJÌ4ÐPTË:×K^ÑK^ÐJ_Ð_`Ðaó
ð 	
r   ©Úraise_on_mismatchÚwarn_on_mismatchc               ó*  — t        |t        j                  «      rt        |«      }n|}t	        |«      t	        |«      urmdt	        |«      j
                  › dt	        |«      j
                  › �g}|rt        | › d|d   › �«      ‚|r%t        j                  | › d|d   › d�t        d¬«       |S |j                  |«      }|rT|rt        | › dd	j                  |«      › �«      ‚|r1t        j                  | › d
d	j                  |«      › d�t        d¬«       |S )al  
    Compare expected metadata against actual tensor or metadata.

    This is the unified validation/comparison function that uses get_diff() from
    metadata classes. Works with both plain tensors and DTensors.

    For plain tensors: compares shape/stride/dtype/requires_grad.
    For DTensors: compares all properties including global shape and placements.

    Args:
        desc: Description for error/warning messages.
        expected: Expected tensor metadata (_TensorMeta or _DTensorMeta).
        actual: Actual tensor or metadata to compare against.
        raise_on_mismatch: If True, raise PipeliningMetadataError on mismatch.
        warn_on_mismatch: If True, issue a warning on mismatch.

    Returns:
        List of differences (empty if metadata matches).

    Raises:
        PipeliningMetadataError: If raise_on_mismatch=True and differences exist.
    ztype: expected ú, got ú: r   z: Metadata type mismatch. z.. Using dynamically inferred metadata instead.rË   ©Ú
stacklevelz; z: Metadata mismatch. )r6   rQ   r¾   rä   rù   r"   r(   ÚwarningsÚwarnÚUserWarningrG   Újoin)ÚdescÚexpectedÚactualrý   rþ   Úactual_metaÚ	type_diffrF   s           r   Úvalidate_metadatar  ñ  s0  € ô> �&œ%Ÿ,™,Ô'Ü)¨&Ó1‰àˆô ˆHƒ~œT +Ó.Ñ.àœd 8›n×5Ñ5Ð6°f¼TÀ+Ó=N×=WÑ=WÐ<XÐYð
ˆ	ñ Ü)¨T¨F°"°Y¸q±\°NÐ*CÓDÐDÙÜ�M‰MØ�&Ð2°9¸Q±<°.ð A?ð @äØõ	ð Ðð ×Ñ˜kÓ*€EáÙÜ)¨T¨F°"°T·Y±Y¸uÓ5EÐ4FÐ*GÓHÐHÙÜ�M‰MØ�&Ð-¨d¯i©i¸Ó.>Ð-?ð @?ð @äØõ	ð €Lr   c               ó  — t        |«      t        |«      k7  rJ| › dt        |«      › dt        |«      › �}|rt        |«      ‚|rt        j                  |t        d¬«       |gS g }t        t        ||d¬«      «      D ]Š  \  }\  }}	|€|	€Œ|�|	€R| › d|› d|€d	nd
› d|	€d	nd
› �}|rt        |«      ‚|rt        j                  |t        d¬«       |j                  |«       Œdt        | › d|› d�||	||¬«      }
|j                  |
«       ŒŒ |S )a2  Validate metadata for a tuple of tensors element-wise.

    Args:
        desc: Description prefix for error/warning messages.
        expected: Tuple of expected metadata (may include ``None`` for grads).
        actual: Tuple of actual tensors or metadata to compare against.
        raise_on_mismatch: If ``True``, raise on the first mismatch.
        warn_on_mismatch: If ``True``, issue warnings for mismatches.

    Returns:
        Aggregated list of difference strings.

    Raises:
        PipeliningMetadataError: If lengths differ or on mismatch.
    z: expected z tensors, got rË   r  T©Ústrictú[z]: expected r­   Úmetadatar   ú]rü   )
r«   r(   r  r  r  rø   ÚziprC   r  Úextend)r  r	  r
  rý   rþ   ÚmsgÚ	all_diffsrú   ÚexpÚactrF   s              r   Úvalidate_tensors_metadatar  6  s>  € ô. ˆ8ƒ}œ˜F›Ò#Ø��k¤# h£- °¼sÀ6»{¸mÐLˆÙÜ)¨#Ó.Ð.ÙÜ�M‰M˜#œ{°qÕ9Øˆuˆà€IÜ"¤3 x°ÀÔ#EÓFò  ‰ˆ‰:ˆC�Øˆ;˜3˜;ØØˆ;˜#˜+à�&˜˜!˜˜L°3°;©ÀJÐ(Oð PØ!$ ‘v°*Ð=ð?ð ñ !Ü-¨cÓ2Ð2ÙÜ—‘˜c¤;¸1Õ=Ø×Ñ˜SÔ!ØÜ!Øˆf�A�a�S˜ˆNØØØ/Ø-ô
ˆð 	×Ñ˜Õð+ ð, Ðr   c                ó¦  — |rdnd}|› d�}|› d�}t        |«      t        |«      k7  r-t        d| › d|› dt        |«      › d|› dt        |«      › d	�«      ‚t        t        ||d
¬«      «      D ]ã  \  }\  }}	|j                  s3|	�1t        d| › d|› d|› d|› d|› dt        |	«      j                  › d�«      ‚|j                  r.|	€,t        j                  d| › d|› d|› d|› d|› d�t        d¬«       t        |t        «      sŒ“|j                  sŒ |	€Œ£t        |	t        «      rŒ´t        d| › d|› d|› d|› d|› dt        |	«      j                  › d�«      ‚ y)u/  
    Validate the argsâ†”grads contract for static mode.

    Enforces four rules for each (arg, grad) pair:
      1. len(args) must equal len(grads).
      2. If arg.requires_grad is False, grad must be None.
      3. If arg.requires_grad is True and grad is None, emit a warning
         (this is legal at pipeline boundaries but may indicate a bug).
      4. If arg is a DTensor with requires_grad=True and grad is not None,
         grad must also be a DTensor.

    Args:
        stage_index: The stage index for error messages.
        args: Tuple of forward tensors.
        grads: Tuple of gradient tensors (can include None).
        is_input: True for input_args/input_grads, False for output_args/output_grads.

    Raises:
        PipeliningMetadataError: If any hard rule (1, 2, or 4) is violated.
    ÚinputÚoutputÚ_argsÚ_gradszStage r  z	 length (z) does not match zo). Each forward tensor must have a corresponding gradient entry (use None for tensors that don't require grad).Tr  Nr  z] has requires_grad=False, but z] is not None (zE). Non-differentiable tensors must have None as their gradient entry.z] has requires_grad=True, but zT] is None. This is legal at pipeline boundaries but may indicate a missing gradient.rË   r  z,] is a DTensor with requires_grad=True, but z] is za, expected DTensor or None. DTensor gradients may have different placements than forward tensors.)r«   r(   rø   r  r3   rù   r"   r  r  r  r6   r   )
rÒ   r¿   ÚgradsÚis_inputÚkindÚ	args_nameÚ
grads_namerú   rû   Úgrads
             r   Ú'validate_static_arg_grad_correspondencer&  o  s½  € ñ4 ‰7 H€DØ�&˜�€IØ�6˜�€Jô ˆ4ƒy”C˜“JÒÜ%Ø�[�M  J <¨y¼¸U»¸ÐDUØˆk˜¤3 t£9 +ð .[ð\ó
ð 	
ô $¤C¨¨e¸DÔ$AÓBò ‰ˆ‰;ˆC�à× Ò  TÐ%5Ü)Ø˜˜ R¨	 {°!°A°3ð 7Ø!�l ! A 3 o´d¸4³j×6IÑ6IÐ5Jð KUðVóð ð ×Ò  Ü�M‰MØ˜˜ R¨	 {°!°A°3ð 7Ø!�l ! A 3ð '7ð8ô Øõô �sœGÕ$Ø×!Ó!ØÑ Ü˜t¤WÕ-ä)Ø˜˜ R¨	 {°!°A°3ð 7Ø!�l ! A 3 e¬D°«J×,?Ñ,?Ð+@ð AXðYóð ñ5r   )r�   r,   r>   rI   r!   rH   )r•   r†   r!   r‹   )r¼   r2   )rÉ   )rÎ   r¯   rÏ   r¯   rÐ   Ústrr!   zdict[int, int])rÎ   r¯   rÏ   r¯   rÐ   r'  r!   zdict[int, list[int]])r8   rH   r!   rm   )r¥   útuple[torch.Tensor, ...] | Nonerå   úLiteral[False]r!   rp   )r¥   ú&tuple[torch.Tensor | None, ...] | Nonerå   úLiteral[True]r!   rs   )r¥   úAtuple[torch.Tensor | None, ...] | tuple[torch.Tensor, ...] | Nonerå   r2   r!   rs   )F)r8   rH   r¼   r2   r!   rH   ).)r¿   zCtorch.Tensor | tuple[torch.Tensor, ...] | list[torch.Tensor] | Nonerå   r)  r!   r(  )r¿   zQtorch.Tensor | tuple[torch.Tensor | None, ...] | list[torch.Tensor | None] | Nonerå   r+  r!   r*  )r¿   z�torch.Tensor | tuple[torch.Tensor, ...] | tuple[torch.Tensor | None, ...] | list[torch.Tensor] | list[torch.Tensor | None] | Nonerå   r2   r!   r,  )r  r'  r	  rm   r
  ztorch.Tensor | TensorMetarý   r2   rþ   r2   r!   rK   )r  r'  r	  r‹   r
  z,tuple[torch.Tensor | TensorMeta | None, ...]rý   r2   rþ   r2   r!   rK   )
rÒ   r¯   r¿   ztuple[torch.Tensor, ...]r   r®   r!  r2   r!   r­   )=Ú
__future__r   Úloggingr  Údataclassesr   r   Úenumr   Útypingr   r   r	   r
   r   r   rQ   r   Útorch.distributed._mesh_layoutr   Útorch.distributed.tensorr   Útorch.utils._pytreer   r   Útorch.distributed.device_meshr   Ú(torch.distributed.tensor.placement_typesr   Ú	getLoggerr"   Úloggerr   r]   r'  r&   rL   ÚRuntimeErrorr(   r,   rO   rm   ro   r…   rŠ   r;   r–   r˜   r±   rÅ   rÇ   rÔ   rÞ   rà   rä   rè   rð   ró   r  r  r&  r   r   r   ú<module>r:     s	  ðö #ã Û ß (Ý ß N× Nã Ý Ý 6Ý ,ß <ñ Ý8ÝBð 
ˆ×	Ñ	˜8Ó	$€ô�hô ð    c¨3 h¡°¸tÑ1CÐ CÑD€ˆiÓ DôG˜lô Gñ �$˜dÔ#÷Hð Hó $ðHñV �$˜dÔ#ô@�;ó @ó $ð@ðH $ lÑ2€
ˆIÓ 2ñ
 �Ô÷Dð Dó ðDñ6 �$˜dÔ#÷*ð *ó $ð*ñ �$˜dÔ#÷	ð 	ó $ð	ðØ
ðàðð óð*6Ø(ð6à"ó6÷0@ ñ @ ôP0�Dô 0ðp */õ ò6+ð 17ðØðØ!ðØ*-ðàóðF 17ðØðØ!ðØ*-ðàóñ4 �Ô÷ ð  ó ð ó/ð( 
ð "%ñ(Ø,ð(ð ð(ð #ò	(ó 
ð(ð 
ð/Ø3ð/ð ð/ð *ò	/ó 
ð/ð ñ!"ØNð!"ð ð!"ð *ó	!"ôH!ð( 
ð "%ð*Ø
Mð*àð*ð %ò*ó 
ð*ð 
ð !$ð1ðð1ð
 ð1ð ,ò1ó 
ð1ð  ð-
ðð-
ð ð-
ð Gó-
ðt $Ø"ñBØ
ðBàðBð &ðBð
 ðBð ðBð óBðT #Ø"ñ6Ø
ð6à+ð6ð 9ð6ð
 ð6ð ð6ð ó6ðrDØðDà
"ðDð +ðDð ð	Dð
 
ôDr   