+
    –°³jš  ã                  óè  a € 0 t $ ^ RIHt ^ RIt^ RIt^ RIHtHt ^ RIH	t	 ^ RI
HtHtHtHtHtHt ^ RIt^ RIHt ^ RIHt ^ RIHt ^ R	IHtHt ]'       d   ^ R
IHt ^ RIHt ]P<                  ! ]4      t  ! R R]4      t!]"]"]#R3,          ]R,          3,          t$R]%R&    ! R R]&4      t']! RRR7       ! R R4      4       t(]! RRR7       ! R R](4      4       t)](]),          t*R]%R&   ]! RR7       ! R R4      4       t+]! RRR7       ! R R4      4       t,]! RRR7       ! R R 4      4       t-R! R" lt.R# R$ lt/ ! R% R&4      t0 ! R' R(]	4      t1R)R*/R+ R, llt2R- t3RMR. R/ llt4RMR0 R1 llt5]! RR7       ! R2 R34      4       t6R4 R5 lt7]R6R/R7 R8 ll4       t8]R9 R: l4       t8R6R*/R; R< llt8RNR= R> llt9]ROR? R@ ll4       t:]RORA RB ll4       t:RNRC RD llt:RER*RFR*/RG RH llt;RERRFR*/RI RJ llt<RK RL lt=R# )Pé    )ÚannotationsN)Ú	dataclassÚfield)ÚEnum)ÚcastÚLiteralÚoverloadÚProtocolÚTYPE_CHECKINGÚ	TypeAlias)Úfx)Ú_MeshLayout)ÚDTensor)Útree_flattenÚtree_unflatten)Ú
DeviceMesh)Ú	Placementc                  ó&   € ] tR t^tRtR R ltRtR# )ÚGetMeshCallbackzGCallback to create/retrieve a DeviceMesh from its cache key components.c               ó$   € V ^8„  d   QhRRRRRR/# )é   Úmesh_dim_namesútuple[str, ...]Úmesh_layoutú_MeshLayout | NoneÚreturnr   © )Úformats   "Úd/home/luca/screen-checking/.venv/lib/python3.14/site-packages/torch/distributed/pipelining/_utils.pyÚ__annotate__ÚGetMeshCallback.__annotate__   s(   € ÷ ñ à'ðð (ðð 
ñ	ó    c                	ó   € R # ©Nr   )Úselfr   r   s   &&&r   Ú__call__ÚGetMeshCallback.__call__   s   € ñ r"   r   N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r&   Ú__static_attributes__r   r"   r   r   r      s   † ÙQ÷ñ r"   r   .r   ÚMeshCacheKeyc                  ó   € ] tR t^,tRtRtR# )ÚPipeliningMetadataErrorz<Raised on metadata mismatches during pipeline communication.r   N)r(   r)   r*   r+   r,   r-   r   r"   r   r0   r0   ,   s   † ÝFr"   r0   T)ÚfrozenÚslotsc                  ór   € ] tR t^0t$ RtR]R&   R]R&   R]R&   R]R	&   ]R
 R l4       tR R ltR R lt	Rt
R# )Ú_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               ó    € V ^8„  d   QhRRRR/# )r   Útensorútorch.Tensorr   r4   r   )r   s   "r   r    Ú_TensorMeta.__annotate__?   s   € ÷ 
ñ 
˜Lð 
¨[ñ 
r"   c                óº   € \        V \        4      '       d   \        R4      h\        V P                  V P                  4       V P                  V P                  R7      # )zÞ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.©r6   r8   r9   r;   )Ú
isinstancer   r0   r4   r6   r8   r9   r;   ©r=   s   &r   Úfrom_tensorÚ_TensorMeta.from_tensor>   sP   € ô �fœg×&Ò&Ü)Ø\óð ô Ø—,‘,Ø—=‘=“?Ø—,‘,Ø ×.Ñ.ô	
ð 	
r"   c               ó    € V ^8„  d   QhRRRR/# )r   Údeviceútorch.device | strr   r>   r   )r   s   "r   r    r?   V   s   € ÷ ñ Ð 2ð °|ñ r"   c                ó~   € \        W4      pVP                  4       '       d   VP                  V P                  4       V# )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_r;   )r%   rG   Úts   && r   Ú	to_tensorÚ_TensorMeta.to_tensorV   s6   € ô # 4Ó0ˆØ×Ñ× Ò Ø×Ñ˜T×/Ñ/Ô0Øˆr"   c               ó    € V ^8„  d   QhRRRR/# ©r   Úotherr4   r   ú	list[str]r   )r   s   "r   r    r?   d   s   € ÷ ñ ˜kð ¨iñ r"   c                ó¾  € W8X  d   . # . pV P                   VP                   8w  d,   VP                  RV P                    RVP                    24       V P                  VP                  8w  d,   VP                  RV P                   RVP                   24       V P                  VP                  8w  d,   VP                  RV P                   RVP                   24       V# )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: )r6   Úappendr8   r9   ©r%   rR   Údiffss   && r   Úget_diffÚ_TensorMeta.get_diffd   s°   € ð Œ=Øˆ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"   r   N)r(   r)   r*   r+   r,   Ú__annotations__ÚstaticmethodrD   rN   rY   r-   r   r"   r   r4   r4   0   sB   ‡ ñð ÓØÓØÓØÓàô
ó ð
õ.÷ñ r"   r4   c                  óî   € ] tR t^|t$ Rt]! R R7      tR]R&   ]! RR7      tR]R&   ]! RR7      t	R	]R
&   ]! RR7      t
R]R&   ]! RR7      tR]R&   ]R R l4       t]R R l4       tR R ltR R ltRtR# )Ú_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                 	ó.   € \         P                  ! . 4      # r$   )ÚtorchÚSizer   r"   r   Ú<lambda>Ú_DTensorMeta.<lambda>Š   s   € ¼U¿ZºZÈ¼^r"   )Údefault_factoryr5   Úglobal_shape)Údefaultr7   Úglobal_strideztuple[Placement, ...]Ú
placementsr   r   Nr   r   c               ó    € V ^8„  d   QhRRRR/# )r   Údtensorr   r   r^   r   )r   s   "r   r    Ú_DTensorMeta.__annotate__™   s   € ÷ 
ñ 
˜gð 
¨,ñ 
r"   c                ó|  € V P                   p\        V P                  P                  V P                  P	                  4       V P
                  V P                  V P                  V P	                  4       V P                  P                  VP                  '       d   \        VP                  4      MRVP                  R7	      # )z�Create metadata from a DTensor.

Args:
    dtensor: The DTensor to extract metadata from.

Returns:
    Metadata capturing both local and global attributes.
)	r6   r8   r9   r;   re   rg   rh   r   r   r   )Údevice_meshr^   Ú_local_tensorr6   r8   r9   r;   Ú_specrh   r   ÚtupleÚ_layout)rj   rm   s   & r   Úfrom_dtensorÚ_DTensorMeta.from_dtensor˜   s�   € ð ×)Ñ)ˆäà×'Ñ'×-Ñ-Ø×(Ñ(×/Ñ/Ó1Ø—-‘-Ø!×/Ñ/à Ÿ™Ø!Ÿ.™.Ó*à—}‘}×/Ñ/à5@×5O×5OÐ5O”�k×0Ñ0Ô1ÐUWà#×+Ñ+ô
ð 	
r"   c               ó   € V ^8„  d   QhRR/# )r   r   r.   r   )r   s   "r   r    rk   ¶   s   € ÷ 7ñ 7 ñ 7r"   c                ó2   € V P                   V P                  3# )z<Cache key ``(mesh_dim_names, mesh_layout)`` for mesh lookup.)r   r   ©r%   s   &r   Úmesh_cache_keyÚ_DTensorMeta.mesh_cache_keyµ   s   € ð ×#Ñ# T×%5Ñ%5Ð6Ð6r"   c               ó$   € V ^8„  d   QhRRRRRR/# )r   rG   rH   Úmeshr   r   r   r   )r   s   "r   r    rk   º   s"   € ÷ !ñ !Ð!3ð !¸:ð !È'ñ !r"   c           	     ó  € \        W4      p\        P                  ! VVV P                  V P                  V P
                  RR7      pV P                  '       d(   VP                  4       '       d   VP                  R4      p\        \        V4      # )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)rm   rh   r6   r8   Ú	run_checkT)
rJ   r   Ú
from_localrh   re   rg   r;   rK   rL   r   )r%   rG   rz   Úlocal_tensorÚdts   &&&  r   Ú
to_dtensorÚ_DTensorMeta.to_dtensorº   s{   € ô .¨dÓ;ˆô ×ÒØØØ—‘Ø×#Ñ#Ø×%Ñ%Øô
ˆð ××Ð "×"6Ñ"6×"8Ò"8Ø×"Ñ" 4Ó(ˆBÜ”G˜RÓ Ð r"   c               ó    € V ^8„  d   QhRRRR/# rQ   r   )r   s   "r   r    rk   Ó   s   € ÷ *ñ *˜kð *¨iñ *r"   c                óP  € W8X  d   . # \         P                  W4      p\        V\        4      '       Eda   V P                  VP                  8w  d,   VP                  RV P                   RVP                   24       V P                  VP                  8w  d,   VP                  RV P                   RVP                   24       V P                  VP                  8w  d,   VP                  RV P                   RVP                   24       V P                  VP                  8w  d,   VP                  RV P                   RVP                   24       V P                  VP                  8w  d,   VP                  RV P                   RVP                   24       V# VP                  R4       V# )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: rU   zglobal_stride mismatch: zplacements mismatch: zmesh_dim_names mismatch: zmesh_layout mismatch: z!type: _DTensorMeta vs _TensorMeta)
r4   rY   rB   r^   re   rV   rg   rh   r   r   rW   s   && r   rY   Ú_DTensorMeta.get_diffÓ   s„  € ð Œ=ØˆIô
 ×$Ñ$ TÓ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)   r*   r+   r,   r   re   r[   rg   rh   r   r   r\   rr   Úpropertyrw   r€   rY   r-   r   r"   r   r^   r^   |   sœ   ‡ ñ	ñ  %Ñ5KÔL€L�*ÓLÙ%*°2Ô%6€M�?Ó6ñ ).Øô)€JÐ%ó ñ
 ',°BÔ&7€N�OÓ7Ù&+Øô'€KÐ#ó ð ô
ó ð
ð8 ô7ó ð7õ!÷2*ñ *r"   r^   Ú
TensorMeta)r2   c                  óx   € ] tR tRt$ RtRtR]R&   RtR]R&   RtR]R&   Rt	R]R	&   R
 R lt
R R ltR R ltRtR# )Ú
_StageMetai  zPConsolidated 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               ó   € V ^8„  d   QhRR/# ©r   r   r:   r   )r   s   "r   r    Ú_StageMeta.__annotate__  s   € ÷ 
ñ 
˜ñ 
r"   c                ó  € \         ;QJ dH    R V P                  V P                  V P                  V P                  3 4       F  '       g   K   R# 	  R# ! R V P                  V P                  V P                  V P                  3 4       4      # )z)Check if any metadata field is populated.c              3  ó*   "  € T F	  pVR Jx € K  	  R # 5ir$   r   )Ú.0Úvs   & r   Ú	<genexpr>Ú%_StageMeta.has_any.<locals>.<genexpr>  s   é € ð 
áU�ð �T�MÛUùs   ‚TF)ÚanyrŠ   r‹   r�   rŽ   rv   s   &r   Úhas_anyÚ_StageMeta.has_any  sw   € ç‹sñ 
à—k‘k 4§<¡<°×1AÑ1AÀ4×CTÑCTÑUó
�sŒsð 	
Šsð 	
ˆsñ 
à—k‘k 4§<¡<°×1AÑ1AÀ4×CTÑCTÑUó
ó 
ð 	
r"   c               ó   € V ^8„  d   QhRR/# r�   r   )r   s   "r   r    r‘     s   € ÷ ñ ˜dñ r"   c                óÒ   € V P                   V P                  3 FJ  pV'       g   K  \        ;QJ d    R V 4       F  '       g   K   RM	  RM! R V 4       4      '       g   KI   R# 	  R# )z3Check if any input/output metadata is DTensor type.c              3  óT   "  € T F  q'       g   K  \        V\        4      x € K   	  R # 5ir$   )rB   r^   )r”   Úms   & r   r–   Ú*_StageMeta.has_dtensors.<locals>.<genexpr>  s   é € ÐMÁ%¸QË1Ô8œZ¨¬<×8Ð8Ã%ùs   ‚	(�(TF)rŠ   r‹   r˜   )r%   Úmetass   & r   Úhas_dtensorsÚ_StageMeta.has_dtensors  sF   € à—k‘k 4§<¡<Ó0ˆEß‰uŸ›ÑMÁ%ÓMŸŸšÑMÁ%ÓM×MÔMÚñ 1ñ r"   c               ó   € V ^8„  d   QhRR/# r�   r   )r   s   "r   r    r‘     s   € ÷ Dñ D¨ñ Dr"   c                óJ   € V P                   RJ;'       d    V P                  RJ# )z-Check if forward metadata is fully populated.N)rŠ   r‹   rv   s   &r   Úis_complete_for_forwardÚ"_StageMeta.is_complete_for_forward  s"   € à�{‰{ $Ð&×CÐC¨4¯<©<¸tÐ+CÐCr"   r   )r(   r)   r*   r+   r,   rŠ   r[   r‹   r�   rŽ   r™   r¡   r¥   r-   r   r"   r   rˆ   rˆ     sG   ‡ áZà,0€FÐ)Ó0Ø-1€GÐ*Ó1Ø8<€KÐ5Ó<Ø9=€LÐ6Ó=õ
õ÷Dñ Dr"   rˆ   c                  ó&   € ] tR tRt$ RtR]R&   RtR# )Ú_StageForwardMetai"  zLForward metadata transmitted from stage *i* to stage *i+1* during inference.útuple[TensorMeta, ...]Úforward_metasr   N©r(   r)   r*   r+   r,   r[   r-   r   r"   r   r¨   r¨   "  s   ‡ áVà)×)r"   r¨   c                  ó&   € ] tR tRt$ RtR]R&   RtR# )Ú_StageBackwardMetai)  u®   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_metasr   Nr«   r   r"   r   r­   r­   )  s   ‡ ñð÷ r"   r­   c               ó$   € V ^8„  d   QhRRRRRR/# )r   Úmetar4   rG   rH   r   r>   r   )r   s   "r   r    r    6  s&   € ÷ ñ Ø
ðàðð ñr"   c                ór   € \         P                  ! V P                  V P                  V P                  VR7      # )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.
)Úsizer8   r9   rG   )r`   Úempty_stridedr6   r8   r9   )r±   rG   s   &&r   rJ   rJ   6  s/   € ô ×ÒØ�Z‰ZØ�{‰{Ø�j‰jØô	ð r"   c               ó    € V ^8„  d   QhRRRR/# )r   Útensor_metasr©   r   r®   r   )r   s   "r   r    r    K  s   € ÷ 6ñ 6Ø(ð6à"ñ6r"   c                ót   a€ R R lo\         ;QJ d    . V3R lV  4       F  NK  	  5# ! V3R lV  4       4      # )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               ó    € V ^8„  d   QhRRRR/# )r   rž   r†   r   zTensorMeta | Noner   )r   s   "r   r    Ú(_derive_grad_metas.<locals>.__annotate__T  s   € ÷ 

ñ 

�jð 

Ð%6ñ 

r"   c                ó´   € V P                   '       g   R # \        V \        4      '       d   R # \        V P                  V P
                  V P                  RR7      # )NFrA   )r;   rB   r^   r4   r6   r8   r9   )rž   s   &r   Ú
derive_oneÚ&_derive_grad_metas.<locals>.derive_oneT  sC   € Ø��ˆÙÜ�aœ×&Ò&ÙÜØ—'‘'Ø—8‘8Ø—'‘'Øô	
ð 	
r"   c              3  ó4   <"  € T F  pS! V4      x € K  	  R # 5ir$   r   )r”   rž   r»   s   & €r   r–   Ú%_derive_grad_metas.<locals>.<genexpr>`  s   øé € Ð5© 1‘˜A—�«ùs   ƒ)rp   )r¶   r»   s   &@r   Ú_derive_grad_metasr¿   K  s,   ø€ õ

÷ Œ5Ô5©Ó5�5Ð5ˆ5Ô5©Ó5Ó5Ð5r"   c                  óf   € ] tR tRtRtRR R lltR R ltR R	 ltR
 R ltR R lt	R R lt
RtR# )Ú
_MeshCacheic  zÚ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               ó    € V ^8„  d   QhRRRR/# )r   Úget_mesh_cbzGetMeshCallback | Noner   ÚNoner   )r   s   "r   r    Ú_MeshCache.__annotate__j  s   € ÷ (ñ (Ð$:ð (Àdñ (r"   c                	ó    € / V n         Wn        R # r$   ©Ú_cacheÚ_get_mesh_cb)r%   rÃ   s   &&r   Ú__init__Ú_MeshCache.__init__j  s   € Ø68ˆŒØ'Ör"   c               ó    € V ^8„  d   QhRRRR/# )r   Úkeyr.   r   r   r   )r   s   "r   r    rÅ   n  s   € ÷  ñ  ˜Lð  ¨Zñ  r"   c                óþ   € WP                   9   d   V P                   V,          # Vw  r#V P                  f   \        RV RV R24      hV P                  W#4      pVf   \        RV RV R24      hW@P                   V&   V# )zã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É   r0   )r%   rÍ   r   r   rz   s   &&   r   Úget_meshÚ_MeshCache.get_meshn  s²   € ð —+‘+ÔØ—;‘;˜sÕ#Ð#à&)Ñ#ˆà×ÑÒ$Ü)Ø=¸nÐ=Mð NØ*˜mð ,NðOóð ð × Ñ  Ó=ˆØŠ<Ü)ð"Ø"0Ð!1°À¸}ð MGðHóð ð
  �‰�CÑØˆr"   c               ó$   € V ^8„  d   QhRRRRRR/# )r   rÍ   r.   rz   r   r   rÄ   r   )r   s   "r   r    rÅ   �  s!   € ÷  ñ  �|ð  ¨:ð  ¸$ñ  r"   c                ó"   € W P                   V&   R# )zAdd a mesh to the cache.N©rÈ   )r%   rÍ   rz   s   &&&r   ÚputÚ_MeshCache.put�  s   € à�‰�CÓr"   c               ó    € V ^8„  d   QhRRRR/# )r   Útensorsútuple[torch.Tensor | None, ...]r   rÄ   r   )r   s   "r   r    rÅ   ”  s   € ÷ 	,ñ 	,Ð+Jð 	,Ètñ 	,r"   c                ó  € V F  p\        V\        4      '       g   K  VP                  pVP                  '       d   \	        VP                  4      MRpVP
                  pWE3pW`P                  9  g   Kq  W0P                  V&   K�  	  R# )zJExtract and cache meshes from any :class:`DTensor` instances in *tensors*.Nr   )rB   r   rm   r   rp   rq   rÈ   )r%   r×   r=   rz   Ú	dim_namesr   rÍ   s   &&     r   Úupdate_from_tensorsÚ_MeshCache.update_from_tensors”  si   € ãˆFÜ˜&¤'×*Ô*Ø×)Ñ)�Ø:>×:M×:MÐ:MœE $×"5Ñ"5Ô6ÐSU�	Ø"Ÿl™l�Ø Ð.�ØŸk™kÖ)Ø'+—K‘K Ó$ó r"   c               ó    € V ^8„  d   QhRRRR/# )r   rÍ   r.   r   r:   r   )r   s   "r   r    rÅ   Ÿ  s   € ÷ "ñ " ð "°ñ "r"   c                	ó   € WP                   9   # r$   rÓ   )r%   rÍ   s   &&r   Ú__contains__Ú_MeshCache.__contains__Ÿ  s   € Ø—k‘kÑ!Ð!r"   c               ó   € V ^8„  d   QhRR/# )r   r   Úintr   )r   s   "r   r    rÅ   ¢  s   € ÷  ñ  ˜ñ  r"   c                	ó,   € \        V P                  4      # r$   )ÚlenrÈ   rv   s   &r   Ú__len__Ú_MeshCache.__len__¢  s   € Ü�4—;‘;ÓÐr"   rÇ   r$   )r(   r)   r*   r+   r,   rÊ   rÏ   rÔ   rÛ   rß   rå   r-   r   r"   r   rÁ   rÁ   c  s+   † ñ÷(õ õD õ	,õ"÷ ñ  r"   rÁ   c                  ó8   € ] tR tRtRtRtRt]R R l4       tRt	R# )	ÚInferenceModei«  a±  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               ó$   € V ^8„  d   QhRRRRRR/# )r   r±   rˆ   Ústage_has_backwardr:   r   r   )r   s   "r   r    ÚInferenceMode.__annotate__¿  s!   € ÷ ñ  ð Àð È$ñ r"   c                ó¶   € VP                  4       '       g   R# VP                  4       '       g   R# V'       g   R# VP                  e   VP                  f   R# R# )z÷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¡   r�   rŽ   )Úclsr±   rì   s   &&&r   Úneeds_dynamicÚInferenceMode.needs_dynamic¾  sS   € ð ×+Ñ+×-Ò-Ùð × Ñ ×"Ò"Ù÷ "Ùð ×ÑÒ# t×'8Ñ'8Ò'@Ùñ r"   r   N)
r(   r)   r*   r+   r,   ÚSTATICÚDYNAMICÚclassmethodrð   r-   r   r"   r   rè   rè   «  s%   † ñð €FØ€Gàôó ôr"   rè   ÚdetachFc               ó   € V ^8„  d   QhRR/# )r   rõ   r:   r   )r   s   "r   r    r    ã  s   € ÷ ñ  $ñ r"   c               ó
  € \        V 4      w  r#V'       di   V Uu. uFN  p\        V\        P                  4      '       d*   VP	                  4       P                  VP                  4      MTNKP  	  pp\        WS4      pWe3# V# u upi )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   rB   r`   ÚTensorrõ   rL   r;   r   )Úargsrõ   Ú	flat_argsÚtreespecÚaÚflat_detachedÚnew_argss   &$     r   Úflatten_argsrÿ   ã  sŠ   € ô ' tÓ,Ñ€Içñ
 ó	
ñ �ô ˜!œUŸ\™\×*Ò*ð �H‰H‹J×%Ñ% a§o¡oÔ6àòñ ð	 	ð 
ô " -Ó:ˆØÐ&Ð&àÐùò
s   šAB c                ó   € \        V RR7      # )zHFlatten and detach. Deprecated: use ``flatten_args(args, detach=True)``.T)rõ   )rÿ   )rù   s   &r   Úflatten_args_detachr  þ  s   € ä˜ TÔ*Ð*r"   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   Úpp_sizerâ   Ú
num_stagesÚstyleÚstrr   zdict[int, int]r   )r   s   "r   r    r      s,   € ÷ ñ ØðØ!ðØ*-ðàñr"   c                ól  € / pVR8X  d   \        V4       F  pW@,          W4&   K  	  V# VR8X  dy   W,          ^ 8w  d   \        RV RV  R24      h^ p\        V4       FF  pWSV&   V^,           V ,          ^ 8X  d   K  W@,          ^,          ^ 8X  d   V^,          pK=  V^,          pKH  	  V# \        RV R24      h)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.
Úloopr•   znum_stages z% must be evenly divisible by pp_size z for V scheduleszStyle z is not supported.)ÚrangeÚ
ValueError)r  r  r  ÚmappingÚstage_indexÚ
rank_indexs   &&&   r   Úgenerate_stage_to_rank_mappingr    sØ   € ð €GØ�„Ü  Ö,ˆKØ#.Õ#8ˆGÓ ñ -ð( €Nð% 
�#ŒØÕ 1Ô$ÜØ˜j˜\Ð)NÈwÈiÐWgÐhóð ð ˆ
Ü  Ö,ˆKØ#-�KÑ à˜a• 7Õ*¨aÔ/ÙØÕ&¨!Õ+¨qÔ0Ø˜a•’
à˜a•’
ñ -ð €Nô ˜6 % Ð(:Ð;Ó<Ð<r"   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   r  râ   r  r  r  r   zdict[int, list[int]]r   )r   s   "r   r    r    %  s,   € ÷ ñ ØðØ!ðØ*-ðàñr"   c                óä   € \        WV4      p/ pVP                  4        F&  w  rVWd9  d   . WF&   WF,          P                  V4       K(  	  VP                  4        F  pVP	                  4        K  	  V# )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  ÚitemsrV   ÚvaluesÚsort)r  r  r  Ústage_to_rankÚrank_to_stagesÚstage_idÚrankÚstagess   &&&     r   Úgenerate_rank_to_stage_mappingr  %  sq   € ô 3°7ÈÓN€Mð ,.€NØ'×-Ñ-Ö/‰ˆØÔ%Ø#%ˆNÑ ØÕ×#Ñ# HÖ-ñ 0ð !×'Ñ'Ö)ˆØ�‰Žñ *ð Ðr"   c                  ó:   € ] tR tRt$ RtR]R&   R]R&   R]R&   R	tR
# )ÚPipeInfoi?  z6
Captures information for a pipeline (`Pipe` object).
zfx.GraphÚgraphrâ   r  r:   Úhas_loss_and_backwardr   Nr«   r   r"   r   r  r  ?  s   ‡ ñð ƒOØƒOØ×r"   r  c               ó    € V ^8„  d   QhRRRR/# )r   r=   r>   r   r†   r   )r   s   "r   r    r    O  s   € ÷ /ñ / ð /°ñ /r"   c                ó‚   € \        V \        4      '       d   \        P                  V 4      # \        P                  V 4      # )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.
)rB   r   r^   rr   r4   rD   rC   s   &r   Úextract_tensor_metar   O  s3   € ô �&œ'×"Ò"Ü×(Ñ(¨Ó0Ð0ä×&Ñ& vÓ.Ð.r"   Ú
allow_nonec               ó$   € V ^8„  d   QhRRRRRR/# )r   r×   útuple[torch.Tensor, ...] | Noner!  úLiteral[False]r   r‰   r   )r   s   "r   r    r    d  s(   € ÷ (ñ (Ø,ð(ð ð(ð #ñ	(r"   c               ó   € R # r$   r   ©r×   r!  s   &$r   Úextract_tensor_metasr'  c  s   € ñ
 %(r"   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r×   ú&tuple[torch.Tensor | None, ...] | Noner!  úLiteral[True]r   rŒ   r   )r   s   "r   r    r    l  s(   € ÷ /ñ /Ø3ð/ð ð/ð *ñ	/r"   c               ó   € R # r$   r   r&  s   &$r   r'  r'  k  s   € ñ
 ,/r"   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r×   úAtuple[torch.Tensor | None, ...] | tuple[torch.Tensor, ...] | Noner!  r:   r   rŒ   r   )r   s   "r   r    r    s  s(   € ÷ !"ñ !"ØNð!"ð ð!"ð *ñ	!"r"   c               ó  € V f   R# . pRpV  FR  p\        V\        P                  4      '       d   VP                  \	        V4      4       K?  RpVP                  R4       KT  	  V'       g   V'       d   \        R4      h\        V4      # )aj  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.)rB   r`   rø   rV   r   r0   rp   )r×   r!  Úmetas_with_noneÚhas_nonerM   s   &$   r   r'  r'  s  s~   € ð" ‚Ùà/1€OØ€HÛˆÜ�aœŸ™×&Ò&Ø×"Ñ"Ô#6°qÓ#9Ö:àˆHØ×"Ñ" 4Ö(ñ ÷ Ÿ(Ü%ð7ó
ð 	
ô �Ó!Ð!r"   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r=   r>   rõ   r:   r   r   )r   s   "r   r    r    —  s!   € ÷ !ñ ! ð !°dð !À|ñ !r"   c                ó†   € V'       d   V P                  4       MT p\        V\        4      '       d   VP                  4       # V# )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õ   rB   r   Úto_local)r=   rõ   Úmaybe_detached_tensors   && r   Úto_local_if_dtensorr5  —  s7   € ÷ 06˜FŸM™MœO¸6ÐÜÐ'¬×1Ò1Ø$×-Ñ-Ó/Ð/Ø Ð r"   c               ó$   € V ^8„  d   QhRRRRRR/# )r   rù   zCtorch.Tensor | tuple[torch.Tensor, ...] | list[torch.Tensor] | Noner!  r$  r   r#  r   )r   s   "r   r    r    ¬  s&   € ÷ *ñ *Ø
Mð*àð*ð %ñ*r"   c                ó   € R # r$   r   ©rù   r!  s   &&r   Úvalidate_and_normalize_to_tupler9  «  s   € ñ '*r"   c               ó$   € V ^8„  d   QhRRRRRR/# )r   rù   zQtorch.Tensor | tuple[torch.Tensor | None, ...] | list[torch.Tensor | None] | Noner!  r*  r   r)  r   )r   s   "r   r    r    ³  s*   € ÷ 1ñ 1ðð1ð
 ð1ð ,ñ1r"   c                ó   € R # r$   r   r8  s   &&r   r9  r9  ²  s   € ñ .1r"   c               ó$   € V ^8„  d   QhRRRRRR/# )r   rù   z�torch.Tensor | tuple[torch.Tensor, ...] | tuple[torch.Tensor | None, ...] | list[torch.Tensor] | list[torch.Tensor | None] | Noner!  r:   r   r-  r   )r   s   "r   r    r    ¼  s+   € ÷ -
ñ -
ðð-
ð ð-
ð Gñ-
r"   c           	     ó  € V f   R# \        V \        P                  4      '       d   V 3# \        V \        \        34      '       dš   \        V 4       Fg  w  r#Vf   V'       g   \        RV R24      hK"  \        V\        P                  4      '       d   KD  \        RV R\        V4      P                   R24      h	  \        V \        4      '       d   \        V 4      # T # \        R\        V 4      P                   R24      h)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 Ú.)	rB   r`   rø   rp   ÚlistÚ	enumerater0   Útyper(   )rù   r!  ÚiÚargs   &&  r   r9  r9  ¼  sø   € ð, ‚|ÙÜ	�Dœ%Ÿ,™,×	'Ò	'ØˆwˆÜ	�Dœ5¤$˜-×	(Ò	(Ü –o‰FˆAØŠ{ß!Ü1Ø$ Q Cð (Vð Wóð ñ Ü˜c¤5§<¡<×0Ô0Ü-Ø    ;¬t°C«y×/AÑ/AÐ.Bð CXð Yóð ñ &ô )¨¬t×4Ò4Œu�T‹{Ð>¸$Ð>ä%ØJÌ4ÐPTË:×K^ÑK^ÐJ_Ð_`Ðaó
ð 	
r"   Úraise_on_mismatchÚwarn_on_mismatchc               ó0   € V ^8„  d   QhRRRRRRRRR	RR
R/# )r   Údescr  Úexpectedr†   Úactualztorch.Tensor | TensorMetarD  r:   rE  r   rS   r   )r   s   "r   r    r    ñ  sL   € ÷ Bñ BØ
ðBàðBð &ðBð
 ðBð ðBð ñBr"   c               óŠ  € \        V\        P                  4      '       d   \        V4      pMTp\	        V4      \	        V4      Jdƒ   R\	        V4      P
                   R\	        V4      P
                   2.pV'       d   \        V  RV^ ,           24      hV'       d+   \        P                  ! V  RV^ ,           R2\        ^R7       V# VP                  V4      pV'       db   V'       d    \        V  RRP                  V4       24      hV'       d3   \        P                  ! V  RRP                  V4       R2\        ^R7       V# )	a,  
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 ú: z: Metadata type mismatch. z.. Using dynamically inferred metadata instead.©Ú
stacklevelz; z: Metadata mismatch. )rB   r`   rø   r   rA  r(   r0   ÚwarningsÚwarnÚUserWarningrY   Újoin)rG  rH  rI  rD  rE  Úactual_metaÚ	type_diffrX   s   &&&$$   r   Úvalidate_metadatarU  ñ  s3  € ô> �&œ%Ÿ,™,×'Ò'Ü)¨&Ó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               ó0   € V ^8„  d   QhRRRRRRRRR	RR
R/# )r   rG  r  rH  r®   rI  z,tuple[torch.Tensor | TensorMeta | None, ...]rD  r:   rE  r   rS   r   )r   s   "r   r    r    6  sD   € ÷ 6ñ 6Ø
ð6à+ð6ð 9ð6ð
 ð6ð ð6ð ñ6r"   c          	     óh  € \        V4      \        V4      8w  dX   V  R\        V4       R\        V4       2pV'       d   \        V4      hV'       d   \        P                  ! V\        ^R7       V.# . p\        \        WRR7      4       F¥  w  pw  r‰Vf   V	f   K  Ve   V	fe   T  RT RVf   RMR	 R
V	f   RMR	 2pV'       d   \        V4      hV'       d   \        P                  ! V\        ^R7       VP                  V4       K~  \        V  RV R2VV	VVR7      p
VP                  V
4       K§  	  V# )a  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 rM  T©ÚstrictÚ[z]: expected rÄ   ÚmetadatarK  Ú])rD  rE  )
rä   r0   rO  rP  rQ  r@  ÚziprV   rU  Úextend)rG  rH  rI  rD  rE  ÚmsgÚ	all_diffsrB  ÚexpÚactrX   s   &&&$$      r   Úvalidate_tensors_metadatarc  6  s6  € ô. ˆ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ØØØ/Ø-ô
ˆð 	×Ñ˜Öñ+ Gð, Ðr"   c          
     ó,   € V ^8„  d   QhRRRRRRRRR	R
/# )r   r  râ   rù   ztuple[torch.Tensor, ...]ÚgradsrØ   Úis_inputr:   r   rÄ   r   )r   s   "r   r    r    o  sA   € ÷ Dñ DØðDà
"ðDð +ðDð ð	Dð
 
ñDr"   c                ó
  € V'       d   RMRpV R2pV R2p\        V4      \        V4      8w  d.   \        RV  RV R\        V4       RV R\        V4       R	24      h\        \        WR
R7      4       EF  w  pw  r‰VP                  '       g6   V	e2   \        RV  RV RV RV RV R\        V	4      P                   R24      hVP                  '       d2   V	f.   \        P                  ! RV  RV RV RV RV R2\        ^R7       \        V\        4      '       g   K«  VP                  '       g   K¿  V	f   KÅ  \        V	\        4      '       d   KÝ  \        RV  RV RV RV RV R\        V	4      P                   R24      h	  R# )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 rL  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).TrX  NrZ  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.rM  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ä   r0   r@  r]  r;   rA  r(   rO  rP  rQ  rB   r   )
r  rù   re  rf  ÚkindÚ	args_nameÚ
grads_namerB  rC  Úgrads
   &&&&      r   Ú'validate_static_arg_grad_correspondencerp  o  sÄ  € ÷4 ‰7 H€DØ�&˜�€IØ�6˜�€Jô ˆ4ƒy”C˜“JÔÜ%Ø�[�M  J <¨y¼¸U»¸ÐDUØˆk˜¤3 t£9 +ð .[ð\ó
ð 	
ô $¤C¨¸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 Cr"   )r  )F).)>Ú__conditional_annotations__Ú
__future__r   ÚloggingrO  Údataclassesr   r   Úenumr   Útypingr   r   r	   r
   r   r   r`   r   Útorch.distributed._mesh_layoutr   Útorch.distributed.tensorr   Útorch.utils._pytreer   r   Útorch.distributed.device_meshr   Ú(torch.distributed.tensor.placement_typesr   Ú	getLoggerr(   Úloggerr   rp   r  r.   r[   ÚRuntimeErrorr0   r4   r^   r†   rˆ   r¨   r­   rJ   r¿   rÁ   rè   rÿ   r  r  r  r  r   r'  r5  r9  rU  rc  rp  )rq  s   @r   Ú<module>r     sZ  øð÷ #Ð "ã Û ß (Ý ß 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÷0@ ñ @ ôP0�Dô 0ðp¨÷ ò6+÷
÷Dñ4 �Ô÷ ð  ó ð õ/ð( 
ð(ð "%ö(ó 
ð(ð 
ô/ó 
ð/ð!"ð ÷!"÷H!ð( 
ö*ó 
ð*ð 
ö1ó 
ð1÷-
ðjBð
 $ðBð #÷BðJ6ð
 #ð6ð #÷6÷rDr"   