+
    –°³jÎ=  ã                   óò   € R t ^ RIt^ RIHtHt ^ RIHt ^ RIHt ^ RI	H
t
Ht ^ RIt^ RIHtHtHtHtHtHtHtHtHtHtHtHt ]! RR7       ! R	 R
4      4       t]! RR7       ! R R]],          4      4       tR# )zj
Definition of CuTe inspired Layouts for DeviceMesh internal bookkeeping and functions to manipulate them
N)ÚIteratorÚSequence)Ú	dataclass)Úproduct)ÚNoReturnÚoverload)Úas_tupleÚcoalesceÚ
complementÚcompositionÚflattenÚIntTupleÚis_intÚis_tupleÚLayoutÚmake_layoutÚmatch_structureÚsuffix_productT)Úfrozenc                   ó  a € ] tR t^t o RtRV 3R lR lltV 3R lR ltV 3R lR ltV 3R	 lR
 ltV 3R lR lt	V 3R lR lt
V 3R lR ltV 3R lR ltV 3R lR ltV 3R lR ltV 3R lR lt]V 3R lR l4       tV 3R ltRtV tR# )Ú_FlatLayouta›  
A canonical CuTe layout for a single dimension of a DeviceMesh

Utility class for representing an integer layout by borrowing ideas from CuTe Layout Algebra.
See https://github.com/NVIDIA/cutlass/blob/main/media/docs/cpp/cute/02_layout_algebra.md for more details.

Each layout is represented as a list of sizes and strides. We use it as a way for mechanical bookkeeping
of the integers such as ranks in a SPMD mesh, and the transformation on top of it.

Lots of methods of layout like coalesce, composition, complement, etc. are borrowed from pycute.
https://github.com/NVIDIA/cutlass/blob/6dd13d42784ee5bfa232d2441e6b9a021c5c6290/python/pycute/layout.py#L137,L257

Note this is a CuTe-inspired layout, because CuTe uses co-lexicographic way in linearization while PyTorch
is using lexicographic. So even though the CuTe documentation can still be referenced, the implementation will be
different from that of PyCute's.

This layout is _not_ itself subdivided into multiple dimensions. It might
internally sometimes use multidimensional tuple to represent "irregular"
layouts (e.g., flattening non-adjacent dims), but this should be considered
an opaque implementation detail.

This class guarantees that all equivalent layouts are encoded as the same
normalized representation, and thus compare equal. This is achieved by
flattening and coalescing compatible adjacent dimensions (which includes
removing all dimensions of size 1).

Nc                ó8   <€ V ^8„  d   QhRS[ RS[ R,          RR/# )é   ÚshapeÚstrideNÚreturn)r   )ÚformatÚ__classdict__s   "€Ú_/home/luca/screen-checking/.venv/lib/python3.14/site-packages/torch/distributed/_mesh_layout.pyÚ__annotate__Ú_FlatLayout.__annotate__=   s&   ø€ ÷ 8ñ 8™hð 8±¸4µð 8È4ñ 8ó    c                óN  € \        V4      '       g)   \        V4      '       g   \        R \        V4       24      hVe   TM
\	        V4      p\        V4      '       g)   \        V4      '       g   \        R\        V4       24      h\        W4      '       g   \        RV RV R24      h\        \        W4      4      p\        VP                  4      p\        VP                  4      pVR8X  d   VR	8X  d   R
pR
p\        P                  V RV4       \        P                  V RV4       R# )z"shape must be a tuple or int, got Nz#stride must be a tuple or int, got zsizes z and strides z don't matchr   r   ©é   )é    © )r   r   Ú	TypeErrorÚtyper   r   Ú
ValueErrorr	   r   r   r   r   ÚobjectÚ__setattr__)Úselfr   r   Úcoalesced_layoutÚ
flat_shapeÚflat_strides   &&&   r   Ú__init__Ú_FlatLayout.__init__=   sý   € Ü˜�Š¤v¨e§}¢}ÜÐ@ÄÀeÃÀÐNÓOÐOØ!Ò-‘´>À%Ó3HˆÜ˜×Ò¬¨v¯ªÜÐAÄ$ÀvÃ,ÀÐPÓQÐQÜ˜u×-Ò-Ü˜v e W¨M¸&¸ÀÐNÓOÐOä#¤F¨5Ó$9Ó:ÐÜÐ-×3Ñ3Ó4ˆ
ÜÐ.×5Ñ5Ó6ˆð ˜Ô +°Ô"5ØˆJØˆKô 	×Ñ˜4 ¨*Ô5Ü×Ñ˜4 ¨;Ö7r!   c                ó    <€ V ^8„  d   QhRS[ /# ©r   r   )r   )r   r   s   "€r   r   r    T   s   ø€ ÷ 
ñ 
™ñ 
r!   c                ó   € \        R 4      h)zWYou should never need to know the length of the internal representation of a FlatLayout©ÚRuntimeError©r,   s   &r   Ú__len__Ú_FlatLayout.__len__T   s   € ÜØeó
ð 	
r!   c                ó&   <€ V ^8„  d   QhRS[ RS[/# ©r   Úir   )Úintr   )r   r   s   "€r   r   r    Y   s   ø€ ÷ 
ñ 
™Sð 
¡Xñ 
r!   c                ó   € \        R 4      h)zOYou should never need to index into the internal representation of a FlatLayoutr5   ©r,   r<   s   &&r   Ú__getitem__Ú_FlatLayout.__getitem__Y   s   € ÜØ]ó
ð 	
r!   c                ó    <€ V ^8„  d   QhRS[ /# r3   ©r   )r   r   s   "€r   r   r    ^   s   ø€ ÷ /ñ /™6ñ /r!   c                ó~   € V P                   '       g   \        ^^ 4      # \        V P                   V P                  4      # r#   )r   r   r   r7   s   &r   Ú	to_pycuteÚ_FlatLayout.to_pycute^   s,   € Ø�z�zˆzÜ˜!˜Q“<ÐÜ�d—j‘j $§+¡+Ó.Ð.r!   c                ó    <€ V ^8„  d   QhRS[ /# r3   ©r=   )r   r   s   "€r   r   r    c   s   ø€ ÷ %ñ %‘sñ %r!   c                óB   € \         P                  ! V P                  4      # ©N)ÚmathÚprodr   r7   s   &r   ÚnumelÚ_FlatLayout.numelc   s   € Ü�yŠy˜Ÿ™Ó$Ð$r!   c                ó"   <€ V ^8„  d   QhRRRR/# )r   ÚlayoutÚ_MeshLayoutr   r&   )r   r   s   "€r   r   r    f   s   ø€ ÷ (ñ ( -ð (°Mñ (r!   c                ó  € \        V P                  4       VP                  4       4      p\        \        VP                  4      \        VP
                  4      4       UUu. uF  w  r4\        W44      NK  	  ppp\        V4      # u uppi )u  
By-dimension composition allows one layout to "select from" or "filter through" another layout.
Think of it as function composition: (self âˆ˜ layout)(input) = self(layout(input))
between two layouts. This function is a wrapper of pycute's composition.

Mental model about how to understand the composition logic:
- The LEFT layout (self) defines the "output space" - what indices are possible
- The RIGHT layout (layout parameter) acts as a "selector" - which specific indices to pick
- The composition only generates indices that the left layout could originally produce,
  but the right layout determines which indices to be picked.
- The stride of the composition layout will not be smaller than the stride of the right layout,
  because when picking the indices the composition will at least follow the right layout's stride
  to move forward.

Example:
  self = (6,2):(2,1)      # sizes=(6,2), strides=(2,1)
  layout = (3:2)          # sizes=(3,), stride=(2,)
  self o layout = (3:2)

Returns:
  Layout being composed.
)r   rE   Úzipr   r   r   r   rQ   )r,   rP   Úresultr   r   Úresult_axess   &&    r   r   Ú_FlatLayout.compositionf   st   € ô. ˜TŸ^™^Ó-¨v×/?Ñ/?Ó/AÓBˆô "%¤X¨f¯l©lÓ%;¼XÀfÇmÁmÓ=TÔ!Uô
á!U‘�ô ˜Ö&Ù!Uð 	ñ 
ô ˜;Ó'Ð'ùó	
s   ÁBc                ó$   <€ V ^8„  d   QhRS[ RR/# )r   Ú
world_sizer   r   rH   )r   r   s   "€r   r   r    „   s   ø€ ÷ 8ñ 8¡Sð 8¨]ñ 8r!   c                óv   € \        V P                  4       V4      p\        VP                  VP                  4      # )uÇ  
Compute the "complement layout" relative to a given world_size.
A complement layout fills in the "missing" factor so that: self repeat a layout of complement(self, world_size)
will get a complete world_size. We use âŠ— to denote the repeat operation.

Example:
  self = (4:1)   # size=4, stride=1
  world_size = 8
  Then:
    complete needed factor = 8 / 4 = 2
    complement(self, 8) = (2:1)

  Together they form:
    (4:1) âŠ— (2:1) = (4,2):(2,1)
  which has world_size = 4 * 2 = 8, as required.

In distributed terms, complement() is often used to derive the "other"
rank grouping when splitting processes into 2D meshes.

For a visualized explanation, see https://x.com/ezyang/status/1962364978393981433/
)r
   rE   r   r   r   )r,   rX   rT   s   && r   r
   Ú_FlatLayout.complement„   s,   € ô, ˜DŸN™NÓ,¨jÓ9ˆÜ˜6Ÿ<™<¨¯©Ó7Ð7r!   c                ó0   <€ V ^8„  d   QhRS[ S[,          /# r3   )Úlistr=   )r   r   s   "€r   r   r    �   s   ø€ ÷ %
ñ %
¡T©#¥Yñ %
r!   c           
     ó¦   € \        R V P                   4       !   Uu. uF(  p\        R \        WP                  4       4       4      NK*  	  up# u upi )aö  
This function computes the all ranks specified by the layout starting from zero.

How it works:
1. we enumerate every possible coordinate (like a nested for-loop).
If sizes = (2, 3), we get the following coordinates:
    (0,0), (0,1), (0,2), (1,0), (1,1), (1,2)

2. For each coordinate, we compute a linear rank index as:
    all_ranks_from_zero = sum(coord[i] * strides[i] for i in range(ndim))

Example A:
sizes = (2, 3)        # 2 rows, 3 cols
strides = (3, 1)        # row-major layout
coords = (0,0) -> 0*3 + 0*1 = 0
         (0,1) -> 0*3 + 1*1 = 1
         (0,2) -> 0*3 + 2*1 = 2
         (1,0) -> 1*3 + 0*1 = 3
         (1,1) -> 1*3 + 1*1 = 4
         (1,2) -> 1*3 + 2*1 = 5
result = [0, 1, 2, 3, 4, 5]

Example B:
sizes = (2, 3)
strides = (1, 2)        # non-standard / strided layout
coords = (0,0) -> 0*1 + 0*2 = 0
         (0,1) -> 0*1 + 1*2 = 2
         (0,2) -> 0*1 + 2*2 = 4
         (1,0) -> 1*1 + 0*2 = 1
         (1,1) -> 1*1 + 1*2 = 3
         (1,2) -> 1*1 + 2*2 = 5
result = [0, 2, 4, 1, 3, 5]
c              3   ó8   "  € T F  p\        V4      x € K  	  R # 5irJ   )Úrange)Ú.0Úss   & r   Ú	<genexpr>Ú2_FlatLayout.all_ranks_from_zero.<locals>.<genexpr>Á   s   é € Ð"@±Z°¤5¨§8 8³Zùó   ‚c              3   ó6   "  € T F  w  rW,          x € K  	  R # 5irJ   r&   )r`   Úcra   s   &  r   rb   rc   À   s   é € Ð:Ñ"9™$˜!�—’Ó"9ùs   ‚)r   r   ÚsumrS   r   )r,   Úcoords   & r   Úall_ranks_from_zeroÚ_FlatLayout.all_ranks_from_zero�   sM   € ôH !Ñ"@°T·Z²ZÓ"@ÒAó
áA�ô Ñ:¤# e¯[©[Ô"9Ó:Ö:ÙAñ
ð 	
ùò 
s   �.Ac                óF   <€ V ^8„  d   QhRS[ RS[S[S[ ,          ,          /# )r   rX   r   )r=   r\   )r   r   s   "€r   r   r    Ä   s#   ø€ ÷ 
ñ 
¡sð 
©t±D¹µI­ñ 
r!   c           	     óÂ   € V P                  V4      P                  4        UUu. uF)  pV P                  4        Uu. uF  q2V,           NK  	  upNK+  	  upp# u upi u uppi )uÛ  
Build global ranks specified by the layout via two-level ranks composition.

The nested list forms the Cartesian product of all ranks for one layout and offset
regarding filling up the world_size with the layout.
The final global ranks are the addition of these two. The result is a
list of lists: one sublist per layout. This rank list will be used to build
the communicator underlying the layout and the given `world_size`.

Example:
world_size = 16
self.size = 4
self.stride = 1
ranks = [0, 1, 2, 3]
offsets = [0, 4, 8, 12]
result = [
    [0+0, 0+1, 0+2, 0+3],  # â†’ [0, 1, 2, 3]
    [4+0, 4+1, 4+2, 4+3],  # â†’ [4, 5, 6, 7]
    [8+0, 8+1, 8+2, 8+3],  # â†’ [8, 9, 10,11]
    [12+0, 12+1, 12+2, 12+3],  # â†’ [12,13,14,15]
]
)r
   ri   )r,   rX   ÚoffsetÚranks   &&  r   Úglobal_ranksÚ_FlatLayout.global_ranksÄ   s\   € ð2 Ÿ/™/¨*Ó5×IÑIÔKô
áK�ð (,×'?Ñ'?Ô'AÓBÑ'A˜t�d�]ˆ]Ñ'AÔBÙKò
ð 	
ùÚBùó
s   £AºAÁAÁAc                ó    <€ V ^8„  d   QhRS[ /# r3   ©Úbool)r   r   s   "€r   r   r    à   s   ø€ ÷ Gñ G™dñ Gr!   c                ó\   € \        \        V P                  R R7      4      V P                  8H  # )T©Úreverse)ÚtupleÚsortedr   r7   s   &r   Úcheck_sortedÚ_FlatLayout.check_sortedà   s!   € Ü”V˜DŸK™K°Ô6Ó7¸4¿;¹;ÑFÐFr!   c                ó    <€ V ^8„  d   QhRS[ /# r3   rr   )r   r   s   "€r   r   r    ã   s   ø€ ÷ #
ñ #
¡$ñ #
r!   c                ó„  aa€ \        V P                  4      ^8  d   R# \        \        \        V P                  V P                  4      RR7      !  w  oo\
        ;QJ d9    VV3R l\        \        S4      ^,
          4       4       F  '       d   K   R# 	  R# ! VV3R l\        \        S4      ^,
          4       4       4      # )uä  
Check if the layout has any overlap between the ranks it generates. If there is overlap,
we return False, otherwise True.

The layout is supposed to be injective i.e, aside from indice 0, indices from each
dim of the layout must be non-overlapping.

Example 1 - Valid (no overlap):
Layout: sizes=(2,3), strides=(6,1)
- Dim 1: stride=1, span=3*1=3, covers indices [0,1,2]
- Dim 0: stride=6, span=2*6=12, covers indices [0,6]
â†’ No overlap since 6 > 3

Example 2 - Invalid (overlap):
Layout: sizes=(2,3), strides=(2,1)
- Dim 1: stride=1, span=3*1=3, covers indices [0,1,2]
- Dim 0: stride=2, span=2*2=4, covers indices [0,2]
â†’ Overlap! stride=2 < span=3, so indices [0,2] are duplicated

Example 3 - Invalid (overlap):
Layout: sizes=(4,2), strides=(1,1)
- Dim 1: stride=1, span=4, covers indices [0,1,2,3]
- Dim 0: stride=1, span=2, covers indices [0,1]
â†’ Overlap! stride is same for two dims, so indices [0,2] are duplicated

Returns:
    bool: True if no overlap, False if overlap detected
Tru   c              3   ó�   <"  € T F;  pSV,          SV^,           ,          SV^,           ,          ,          ,          ^ 8H  x € K=  	  R# 5i)r$   Nr&   )r`   r<   r   r   s   & €€r   rb   Ú/_FlatLayout.check_orthogonal.<locals>.<genexpr>  s;   øé € ð 
á+�ð �1�I˜  A¥�¨¨q°1­u­Õ5Õ6¸!Ö;Û+ùs   ƒAAF)Úlenr   rS   rx   r   Úallr_   )r,   r   r   s   &@@r   Úcheck_orthogonalÚ_FlatLayout.check_orthogonalã   s‘   ù€ ô: ˆt�z‰z‹?˜QÔÙÜœV¤C¨¯©°T·Z±ZÓ$@È$ÔOÑP‰ˆ�ß‹sõ 
äœ3˜v›;¨�?Ô+ó
�sŒsð 	
Šsð 	
ˆsõ 
äœ3˜v›;¨�?Ô+ó
ó 
ð 	
r!   c                óF   <€ V ^8„  d   QhRS[ S[S[S[3,          ,          /# r3   )r   rw   r=   )r   r   s   "€r   r   r    	  s!   ø€ ÷ ,ñ ,¡8©E±#±s°(­OÕ#<ñ ,r!   c                óB   € \        V P                  V P                  4      # )z5Iterate over (size, stride) pairs for each dimension.)rS   r   r   r7   s   &r   Úsizes_and_stridesÚ_FlatLayout.sizes_and_strides  s   € ô �4—:‘:˜tŸ{™{Ó+Ð+r!   c                óZ   <€ V ^8„  d   Qh/ S[ S[R3,          ;R&   S[ S[R3,          ;R&   # )r   .r   r   ©rw   r=   )r   r   s   "€r   r   r       s/   ø‡ ‚ ñ< ‘�c��?Ññ= ñ> ‘#�s�(�OÑò? r!   r&   rJ   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r0   r8   r@   rE   rM   r   r
   ri   ro   ry   r�   Úpropertyr…   Ú__annotate_func__Ú__static_attributes__Ú__classdictcell__©r   s   @r   r   r      s˜   ø‡ € ñ÷>8ò 8÷.
ð 
÷

ð 
÷
/ð /÷
%ð %÷(ð (÷<8ð 8÷2%
ð %
÷N
ð 
÷8Gð G÷#
ð #
ðJ ÷,ó ð,÷[ ƒ r!   r   c                   óX  a € ] tR tRt o RtV 3R lR lt]R"V 3R lR ll4       tV 3R lR	 lt]	V 3R
 lR l4       t
]	V 3R lR l4       t
V 3R lR lt
V 3R lR ltV 3R lR lt]V 3R lR l4       tV 3R lR ltV 3R lR ltV 3R lR ltV 3R lR ltV 3R lR ltV 3R  ltR!tV tR# )#rQ   i  a  
A multi-dimensional structure consisting of a series of dimension-less layouts

This class represents the layout of a full DeviceMesh, where the overall
top-level ndim and "logical" shape are well defined, but each individual
mesh axis is squashed and normalized into a canonical _FlatLayout.

It only contains methods that need to make use of this multi-dimensional
structure (i.e., which access the ndim or the top-level sizes). Everything
else should go on _FlatLayout and accessed by first calling .collapse().

c                ó4   <€ V ^8„  d   QhRS[ S[,          RR/# )r   Úaxesr   N)r   r   )r   r   s   "€r   r   Ú_MeshLayout.__annotate__  s    ø€ ÷ 6ñ 6™X¡kÕ2ð 6°tñ 6r!   c                óF   € \         P                  V R \        V4      4       R# )r•   N)r*   r+   rw   )r,   r•   s   &&r   r0   Ú_MeshLayout.__init__  s   € Ü×Ñ˜4 ¬¨t«Ö5r!   Nc                ó`   <€ V ^8„  d   QhRS[ S[R3,          RS[ S[R3,          R,          RR/# )r   Úsizes.ÚstridesNr   rQ   rˆ   )r   r   s   "€r   r   r–   #  s:   ø€ ÷ 
ñ 
Ù™#˜s˜(•Oð
Ù.3±C¸°H­oÀÕ.Dð
à	ñ
r!   c                ó6  € Vf   \        \        V4      4      p\        V4      \        V4      8w  d$   \        R\        V4       R\        V4       24      h\        ;QJ d    . R \        W4       4       F  NK  	  5M! R \        W4       4       4      pV ! V4      # )Nz1sizes and strides must have the same length, got z and c              3   óB   "  € T F  w  r\        V3V34      x € K  	  R # 5irJ   ©r   )r`   ra   Úds   &  r   rb   Ú1_MeshLayout.from_sizes_strides.<locals>.<genexpr>,  s"   é € ÐMÑ9L±°”[ ! ¨ t×,Ð,Ó9Lùs   ‚)r   r   r   r)   rw   rS   )Úclsrš   r›   r•   s   &&& r   Úfrom_sizes_stridesÚ_MeshLayout.from_sizes_strides"  s…   € ð Š?Üœn¨UÓ3Ó4ˆGÜˆu‹:œ˜W›Ô%ÜØCÄCÈÃJÀ<ÈuÔUXÐY`ÓUaÐTbÐcóð ÷ ŒuÑM¼¸UÔ9LÓM�u‰uÑM¼¸UÔ9LÓMÓMˆÙ�4‹yÐr!   c                ó    <€ V ^8„  d   QhRS[ /# r3   rH   )r   r   s   "€r   r   r–   /  s   ø€ ÷ ñ ™ñ r!   c                ó,   € \        V P                  4      # rJ   )r   r•   r7   s   &r   r8   Ú_MeshLayout.__len__/  s   € Ü�4—9‘9‹~Ðr!   c                ó&   <€ V ^8„  d   QhRS[ RS[/# r;   )r=   r   )r   r   s   "€r   r   r–   3  s   ø€ ×5Ñ5™SÐ5¡[Ñ5r!   c                ó   € R # rJ   r&   r?   s   &&r   r@   Ú_MeshLayout.__getitem__2  s   € Ù25r!   c                ó$   <€ V ^8„  d   QhRS[ RR/# )r   r<   r   rQ   )Úslice)r   r   s   "€r   r   r–   6  s   ø€ ×9Ñ9™UÐ9 }Ñ9r!   c                ó   € R # rJ   r&   r?   s   &&r   r@   r©   5  s   € Ù69r!   c                ó4   <€ V ^8„  d   QhRS[ S[,          RR/# )r   r<   r   z_FlatLayout | _MeshLayout)r=   r«   )r   r   s   "€r   r   r–   8  s    ø€ ÷ ñ ™S¡5�[ð Ð-Hñ r!   c                óŒ   € \        V\        4      '       d   \        V P                  V,          4      # V P                  V,          # rJ   )Ú
isinstancer«   rQ   r•   r?   s   &&r   r@   r©   8  s0   € Ü�aœ×ÒÜ˜tŸy™y¨�|Ó,Ð,Ø�y‰y˜�|Ðr!   c                ó0   <€ V ^8„  d   QhRS[ S[,          /# r3   )r   r   )r   r   s   "€r   r   r–   =  s   ø€ ÷ ñ ™(¡;Õ/ñ r!   c                ó,   € \        V P                  4      # rJ   )Úiterr•   r7   s   &r   Ú__iter__Ú_MeshLayout.__iter__=  s   € Ü�D—I‘I‹Ðr!   c                ó    <€ V ^8„  d   QhRS[ /# r3   rC   )r   r   s   "€r   r   r–   @  s   ø€ ÷ Fñ F™6ñ Fr!   c                ó‚   € \        V P                  4      ^ 8X  d   \        ^^ 4      # \        R V P                   4       !  # )r%   c              3   ó@   "  € T F  qP                  4       x € K  	  R # 5irJ   )rE   ©r`   Úaxiss   & r   rb   Ú(_MeshLayout.to_pycute.<locals>.<genexpr>C  s   é € ÐD¹)°$Ÿ^™^×-Ð-»)ùó   ‚)r   r•   r   r   r7   s   &r   rE   Ú_MeshLayout.to_pycute@  s3   € Üˆt�y‰y‹>˜QÔÜ˜!˜Q“<ÐÜÑD¸$¿)º)ÓDÑEÐEr!   c                ó4   <€ V ^8„  d   QhRS[ S[R3,          /# )r   r   .rˆ   )r   r   s   "€r   r   r–   F  s   ø€ ÷ 9ñ 9¡¡s¨C x¥ñ 9r!   c                ó‚   € \         ;QJ d    . R  V P                   4       F  NK  	  5# ! R  V P                   4       4      # )c              3   ó@   "  € T F  qP                  4       x € K  	  R # 5irJ   )rM   r¸   s   & r   rb   Ú._MeshLayout.top_level_sizes.<locals>.<genexpr>G  s   é € Ð8©i d—Z‘Z—\�\«iùr»   )rw   r•   r7   s   &r   Útop_level_sizesÚ_MeshLayout.top_level_sizesE  s,   € çŒuÑ8¨d¯iªiÓ8�uÐ8ˆuÑ8¨d¯iªiÓ8Ó8Ð8r!   c                ó    <€ V ^8„  d   QhRS[ /# r3   rH   )r   r   s   "€r   r   r–   I  s   ø€ ÷ /ñ /‘sñ /r!   c                óB   € \         P                  ! V P                  4      # rJ   )rK   rL   rÁ   r7   s   &r   rM   Ú_MeshLayout.numelI  s   € Ü�yŠy˜×-Ñ-Ó.Ð.r!   c                ó    <€ V ^8„  d   QhRS[ /# r3   rH   )r   r   s   "€r   r   r–   L  s   ø€ ÷ )ñ )™ñ )r!   c                ó>   € V P                  4       P                  4       # rJ   )rE   Úcosizer7   s   &r   rÈ   Ú_MeshLayout.cosizeL  s   € Ø�~‰~Ó×&Ñ&Ó(Ð(r!   c                ó    <€ V ^8„  d   QhRS[ /# r3   rž   )r   r   s   "€r   r   r–   O  s   ø€ ÷ 	,ñ 	,™+ñ 	,r!   c                ó  € \         ;QJ d    . R V P                   4       F  NK  	  5M! R V P                   4       4      p\         ;QJ d    . R V P                   4       F  NK  	  5M! R V P                   4       4      p\        W4      # )z©
Merge all axes into a single _FlatLayout.

This is used to "forget" the multi-dimensional structure of this object
and recover a "flat" (and coalesced) representation.
c              3   ó8   "  € T F  qP                   x € K  	  R # 5irJ   )r   r¸   s   & r   rb   Ú'_MeshLayout.collapse.<locals>.<genexpr>V  s   é € Ð8©i d—z–z«iùrd   c              3   ó8   "  € T F  qP                   x € K  	  R # 5irJ   )r   r¸   s   & r   rb   rÍ   W  s   é € Ð:±	¨Ÿž³	ùrd   )rw   r•   r   )r,   Úshapesr›   s   &  r   ÚcollapseÚ_MeshLayout.collapseO  s[   € ÷ ”Ñ8¨d¯iªiÓ8—‘Ñ8¨d¯iªiÓ8Ó8ˆß”%Ñ:°·	²	Ó:—%‘%Ñ:°·	²	Ó:Ó:ˆÜ˜6Ó+Ð+r!   c                ó.   <€ V ^8„  d   QhRS[ RS[ RRRR/# )r   ÚstartÚendrP   rQ   r   rH   )r   r   s   "€r   r   r–   Z  s)   ø€ ÷ %ñ %™Cð %¡cð %°=ð %À]ñ %r!   c                óp   € \        V P                  4      p\        VP                  4      WAV% \        V4      # )z�
Replace (out-of-place) the start:end slice with the given list of layouts

Returns the concatenation of self[:start] + layout + self[end:].
)r\   r•   rQ   )r,   rÓ   rÔ   rP   Únew_axess   &&&& r   ÚspliceÚ_MeshLayout.spliceZ  s/   € ô ˜Ÿ	™	“?ˆÜ" 6§;¡;Ó/ˆ�sÐÜ˜8Ó$Ð$r!   c                óN   <€ V ^8„  d   QhRS[ P                  RS[ P                  /# )r   Úrank_mapr   )ÚtorchÚTensor)r   r   s   "€r   r   r–   d  s#   ø€ ÷ /-ñ /-©¯©ð /-¹¿¹ñ /-r!   c                óà  € VP                   ^8w  d   \        hVP                  4       '       g   \        hVP                  4       V P	                  4       8  d   \        hV P                  4       pVP                  VP                  4       4      pVP                  VP                  VP                  ,           VP                  VP                  ,           4      P                  ! R.V P                  O5!  # )a¹  
Leverage layout as an index for mesh tensor that re-maps the indexes after layout
transformation to actual device ranks.

With this method, the cute layout serves as the backend of indices bookkeeping for the
mesh tensor when it comes to flatten, unflatten and slicing operations. The actual mesh
tensor still represents the actual device assignment and ranks. We need this function
to specify device allocation and create backend for a mesh. Although any transform of mesh tensors
can be treated as a view or subset of mesh tensor, we do need to use the actual view or
sub-tensor for DeviceMesh and its backend creation.

The shape of the `rank_map` must be 1D and contiguous.

Examples:

Case 1 - Consecutive ranks, full world:
    original_mesh_tensor = [[0,1],[2,3]]  # 2x2 mesh, ranks 0-3
    world_size = 4
    layout = Layout(2:2)
    Return: [[0,2],[1,3]]

Case 2 - Non-consecutive ranks:
    original_mesh_tensor = [[10,20],[30,40]]  # custom rank assignment
    world_size = 4
    layout = Layout(2:2)
    Return: [[[10,30],[20,40]]]

Args:
    rank_map: The concrete mesh tensor with actual device ranks

Returns:
    torch.Tensor: A tensor representing the actual device allocation from rank_map
éÿÿÿÿ)ÚndimÚAssertionErrorÚis_contiguousrM   rÈ   rÐ   r
   Ú
as_stridedr   r   ÚreshaperÁ   )r,   rÚ   Úself_layoutÚcomplement_layouts   &&  r   Úremap_to_tensorÚ_MeshLayout.remap_to_tensord  sË   € ðD �=‰=˜AÔÜ Ð Ø×%Ñ%×'Ò'Ü Ð Ø�>‰>Ó˜dŸk™k›mÔ+Ü Ð à—m‘m“oˆØ'×2Ñ2°8·>±>Ó3CÓDÐà×"Ñ"Ø×#Ñ# k×&7Ñ&7Õ7Ø×$Ñ$ {×'9Ñ'9Õ9ó
÷ ‰'ðð ð-ð ×+Ñ+ó-ð 	-r!   c                ó:   <€ V ^8„  d   Qh/ S[ S[R3,          ;R&   # )r   .r•   )rw   r   )r   r   s   "€r   r   r–     s   ø‡ ‚ ñ ‘˜SÐ Õ
!Ñ!ò r!   r&   rJ   )r‰   rŠ   r‹   rŒ   r�   r0   Úclassmethodr¢   r8   r   r@   r³   rE   rŽ   rÁ   rM   rÈ   rÐ   r×   ræ   r�   r�   r‘   r’   s   @r   rQ   rQ     sÃ   ø‡ € ñ÷6ð 6ð ÷
ñ 
ó ð
÷ð ð ß5ó Ø5àß9ó Ø9÷ð ÷
ð ÷Fð Fð
 ÷9ó ð9÷/ð /÷)ð )÷	,ð 	,÷%ð %÷/-ð /-÷m ƒ r!   rQ   )r�   rK   Úcollections.abcr   r   Údataclassesr   Ú	itertoolsr   Útypingr   r   rÛ   Útorch.distributed._pycuter   r	   r
   r   r   r   r   r   r   r   r   r   r   rQ   r&   r!   r   Ú<module>rï      s|   ðñó ß .Ý !Ý ß %ã ÷÷ ÷ ó ñ  �$Ô÷n,ð n,ó ðn,ñb �$ÔôD-�(˜;Õ'ó D-ó òD-r!   