Ë
    g^(h2  ã                   óŠ  — d dl mZ d dlmZ d dlZd dlmc mc mZ	 d dl
mZ d dlmZ d dlmZ d dlmZmZmZmZmZ ded	ed
ee   deeedf   eedf   f   fd„Zdej2                  d	ed
ee   deee   ee   f   fd„Zdej8                  j:                  dee   defd„Zded	ed
ee   deedf   fd„Z dejB                  fd„Z"y)é    )ÚSequence)ÚcastN)Ú	ShapeType)Ú
DeviceMesh)ÚDTensorSpec)Ú_StridedShardÚPartialÚ	PlacementÚ	ReplicateÚShardÚglobal_shapeÚmeshÚ
placementsÚreturn.c                 óh  — |j                  «       }|€yt        | «      }dgt        | «      z  }t        t        | «      «      D �cg c]  }dg|j                  z  ‘Œ }}dgt        | «      z  }t        |«      D ]¿  \  }	}
|j                  |	«      }t        |
t        «      sŒ(|
j                  }dgt        | «      z  }|t        |«      k  sJ d|› dt        |«      › �«       ‚|
j                  ||   |||	   d¬«      \  }}|||<   |||<   ||   ||   k  r	||   ||<   n||xx   ||   z  cc<   ||xx   |z  cc<   ŒÁ t        d„ |D «       «      }|�r7d	gt        | «      z  }d	gt        | «      z  }t        |«      D ]   \  }	}
|j                  |	«      }t        |
t        «      sŒ(|
j                  }||   rt        d
|
› d|	› d|› d�«      ‚||   rd||<   t        |
t        «      r!d||<   ||   |
j                  |z  z  ||   |	<   Œ‰||xx   |z  cc<   ||   ||   |	<   Œ¢ t        |«      D ����cg c]0  \  }}t        t!        ||«      D ��cg c]
  \  }}||z  ‘Œ c}}«      ‘Œ2 }}}}}t!        ||«      D ��cg c]
  \  }}||z  ‘Œ }}}t#        |«      t#        |«      fS c c}w c c}}w c c}}}}w c c}}w )a®  
    Compute the local tensor shape and the global offsets into the original tensor
    of a DTensor on its current global rank. This is useful for checkpointing purpose.

    Example (2 host with 4GPUs each):
    # Below is a DeviceMesh with mesh_shape of (2, 4)
    mesh = DeviceMesh(device_type="cuda",
                        mesh=[
                        [0, 1, 2, 3],
                        [4, 5, 6, 7]
                        ],
    )

    Let's say we distribute a global_tensor of shape (8,4) over the above DeviceMesh
    with a placements of [Shard(0), Shard(0)].
    The local shape and global offset will be as follows:
    rank0 -- local_shape:[1, 4], global_offset:[0, 0]
    rank1 -- local_shape:[1, 4], global_offset:[1, 0]
    rank2 -- local_shape:[1, 4], global_offset:[2, 0]
    rank5 -- local_shape:[1, 4], global_offset:[5, 0]
    rank3 -- local_shape:[1, 4], global_offset:[3, 0]
    rank4 -- local_shape:[1, 4], global_offset:[4, 0]
    rank6 -- local_shape:[1, 4], global_offset:[6, 0]
    rank7 -- local_shape:[1, 4], global_offset:[7, 0]

    Let's say we distribute a global_tensor of shape (2) over the above DeviceMesh with
    a placements of [Shard(0)]. We will not have non-empty local tensor for all the ranks.
    The local shape and global offset will be as follows:
    rank0 -- local_shape:[1,], global_offset:[0,]
    rank1 -- local_shape:[1,], global_offset:[1,]
    rank2 -- local_shape:[0,], global_offset:[2,]
    rank5 -- local_shape:[0,], global_offset:[2,]
    rank3 -- local_shape:[0,], global_offset:[2,]
    rank4 -- local_shape:[0,], global_offset:[2,]
    rank6 -- local_shape:[0,], global_offset:[2,]
    rank7 -- local_shape:[0,], global_offset:[2,]
    ))r   © r   é   úSharding dim ú greater than tensor ndim T)Úreturn_offsetc              3   ó<   K  — | ]  }t        |t        «      –— Œ y ­w©N)Ú
isinstancer   )Ú.0Úps     ú]/var/www/skyplay_api_hub/venv/lib/python3.12/site-packages/torch/distributed/tensor/_utils.pyú	<genexpr>z8compute_local_shape_and_global_offset.<locals>.<genexpr>{   s   è ø€ ÒPÀœz¨!¬]×;ÑPùs   ‚FzTStrided sharding does not allow Shard() to appear after the strided part has ended. z at idx z in z violates this assumption.)Úget_coordinateÚlistÚlenÚrangeÚndimÚ	enumerateÚsizer   r   ÚdimÚ_local_shard_size_on_dimÚanyÚNotImplementedErrorr   Úsplit_factorÚsumÚzipÚtuple)r   r   r   Úmy_coordinateÚlocal_shapeÚglobal_offsetÚ_Úshard_idx_stride_by_mesh_dimÚnum_shards_by_tensor_dimÚidxÚ	placementÚmesh_dim_sizeÚ	shard_dimÚlocal_offsetÚ
shard_sizeÚshard_offsetÚstrided_shardingÚstrided_part_seenÚstrided_part_endÚshard_idx_strideÚxÚyÚ	shard_idxs                          r   Ú%compute_local_shape_and_global_offsetrA      sP  € ðP ×'Ñ'Ó)€MàÐàä˜<Ó(ˆØ˜œc ,Ó/Ñ/ˆä%*¬3¨|Ó+<Ó%=ö(
Ø !ˆQˆC�$—)‘)‹Oð(
Ð$ð (
ð %& 3¬¨\Ó):Ñ#:Ð ä'¨
Ó3ò 	E‰NˆC�Ø ŸI™I c›NˆMÜ˜)¤UÕ+Ø%ŸM™M�	Ø !˜s¤S¨Ó%6Ñ6�Ø ¤3 {Ó#3Ò3ð Ø# I ;Ð.HÌÈ[ÓIYÐHZÐ[óÐ3ð ,5×+MÑ+MØ 	Ñ*Ø!Ø! #Ñ&Ø"&ð	 ,Nó ,Ñ(�
˜Lð *4�˜IÑ&Ø*6�˜YÑ'ð ! Ñ+¨|¸IÑ/FÒFØ/;¸IÑ/F�M )Ò,à! )Ó,°¸YÑ0GÑGÓ,à(¨Ó3°}ÑDÔ3ð7	Eôh ÑPÀZÔPÓPÐÚØ!& ¬#¨lÓ*;Ñ ;ÐØ %˜w¬¨\Ó):Ñ:ÐÜ"+¨JÓ"7ò ‘��YØ $§	¡	¨#£�Ü˜i¬Õ/Ø )§¡�Ià'¨	Ò2Ü1ð;Ø;D¸+ÀXÈcÈUÐRVØ)˜lÐ*DðFóð ð )¨Ò3Ø6:Ð(¨Ñ3ä! )¬]Ô;Ø7;Ð)¨)Ñ4à4°YÑ?Ø )× 6Ñ 6¸Ñ FñHð 5°YÑ?ÀÒDð
 1°Ó;ÀÑMÓ;à4°YÑ?ð 5°YÑ?ÀÒDð/ô: 4=Ø0ó4÷ñ á/�IÐ/ô ¤sÐ+;¸]Ó'K×L™t˜q !�Q˜“UÓLÕMðˆIó ô 03°;À	Ó/J×K¡t q¨!˜Q ›UÐKˆMÑKä�[Ó!¤5¨Ó#7Ð7Ð7ùòC(
ùór Mùõùó Ls$   ÁJÈ*J&
ÉJ É
J&
É3J.Ê J&
Útensorc           	      ó€  — t        | j                  «       «      }t        | j                  «       «      }t        |«      D ]û  \  }}|j                  |«      }|j	                  «       r§t        t        |«      }|j                  dk  rt        d|› �«      ‚|j                  }	|	| j                  k  sJ d|	› d| j                  › d|› d�«       ‚||	   }
|
|z  ||	<   t        t        |«      «      D ]  }||	k7  sŒ	||   ||	   k\  sŒ||   |z  ||<   Œ! ŒÎt        |t        t        f«      rŒåt        dt!        |«      › d�«      ‚ ||fS )	aV  
    Compute the global size and stride of a DTensor from the given local tensor.
    The local size is multiplited by `world_size` per Sharding dim.
    The local stride is multiplited by `world_size` per Sharding dim, as long as the
    dimension is outside sharding dim.

    For example, if we have a local tensor with size (4, 8, 2) and stride (16, 1, 8).
    If the DTensor placements are [Shard(2)] and world_size is 2;
    then the global size is (4, 8, 4) and stride is (16 * 2, 1, 8).

    Args:
        tensor (:class:`torch.Tensor`):
            Local tensor which DTensor will be constructed from.
        mesh (:class:`DeviceMesh`):
            Object which describes the mesh topology
            of devices for the DTensor.
        placements (Sequence[:class:`Placement`]]):
            The attribute of the DTensor that describes its layout
            on the mesh topology.

    Return:
        tensor_shape: A List of int which specifies the size of DTensor which build
            on top of the local tensor.
        tensor_stride: A List of int which specifies the stride of DTensor.
    r   zOShard placements should have negative dims normalized in the user-facing APIs: r   r   z for placement number ú.zplacement type z not supported!)r   r$   Ústrider#   Úis_shardr   r   r%   ÚAssertionErrorr"   r!   r    r   r   r	   ÚRuntimeErrorÚtype)rB   r   r   Útensor_shapeÚtensor_strider3   r4   r5   Úshard_placementr6   Úlocal_dim_sizeÚis               r   Úcompute_global_tensor_inforO   ¦   sp  € ô8 ˜Ÿ™›Ó&€LÜ˜Ÿ™›Ó)€MÜ# JÓ/ò S‰ˆˆYØŸ	™	 #›ˆØ×ÑÔÜ"¤5¨)Ó4ˆOØ×"Ñ" QÒ&Ü$ð-Ø-<Ð,=ð?óð ð (×+Ñ+ˆIà˜vŸ{™{Ò*ð Ø 	˜{Ð*DÀVÇ[Á[ÀMÐQgÐhkÐglÐlmÐnóÐ*ð *¨)Ñ4ˆNØ&4°}Ñ&DˆL˜Ñ#ô œ3˜}Ó-Ó.ò H�Ø˜	“> m°AÑ&6¸-È	Ñ:RÓ&Rà'4°QÑ'7¸-Ñ'G�M !Ò$ñHô ˜I¬	´7Ð';Õ<Ü ´°i³Ð0AÀÐQÓRÐRð3Sð4 ˜Ð&Ð&ó    Úop_callÚargsc                 ó>  — |D ]Š  }t        |t        j                  t        f«      r|j                  c S t        |t
        t        f«      sŒHt        |«      dkD  sŒWt        |d   t        j                  t        f«      sŒ{|d   j                  c S  t        d| › d�«      ‚)z‰
    Find the device mesh object from args.
    It returns None if no mesh is found.
    NOTE: we can optimize this search if needed
    r   z+Cannot find device mesh from args for op : rD   )	r   ÚdtensorÚDTensorr   Údevice_meshr   r,   r    Ú
ValueError)rQ   rR   Úargs      r   Útry_find_mesh_from_argsrY   á   s‡   € ð ò &ˆÜ�cœGŸO™O¬[Ð9Ô:Ø—?‘?Ò"ä�sœT¤5˜MÕ*Ü�C“˜1“Ü˜3˜q™6¤G§O¡O´[Ð#AÕBà�q‘6×%Ñ%Ò%ð&ô ÐBÀ7À)È1ÐMÓ
NÐNrP   Úglobal_stridec                 óp  ‡ ‡— dgt        ‰ «      z  Št        |«      D ]q  \  }}|j                  «       sŒt        t        |«      j
                  }t        t        ‰ «      «      D ]*  }‰ |   ‰ |   kD  sŒ‰|xx   |j                  |«      z  cc<   Œ, Œs t        ˆ ˆfd„t        t        ‰ «      «      D «       «      S )z¬
    Compute the stride of a local tensor shard, given the global stride of the DTensor.
    NOTE: Currently this function is assuming the DTensor is evenly shardable.
    r   c              3   ó4   •K  — | ]  }‰|   ‰|   z  –— Œ y ­wr   r   )r   rN   rZ   Ústride_divisorss     €€r   r   z'compute_local_stride.<locals>.<genexpr>  s%   øè ø€ ò Ø34ˆ�aÑ˜O¨AÑ.Õ.ñùs   ƒ)	r    r#   rF   r   r   r%   r!   r$   r,   )rZ   r   r   Úmesh_idxr   rN   Újr]   s   `      @r   Úcompute_local_strider`   ö   s´   ù€ ð �cœC Ó.Ñ.€OÜ  Ó,ò >‰ˆ�!Ø�:‰:�<Ü”U˜A“×"Ñ"ˆAô œ3˜}Ó-Ó.ò >�Ø  Ñ# m°AÑ&6Ó6Ø# AÓ&¨$¯)©)°HÓ*=Ñ=Ô&ñ>ð>ô ô Ü8=¼cÀ-Ó>PÓ8Qôó ð rP   c                 ó  — t        | t        j                  «      r| S t        | t        «      r| g}n;t	        | «      dk(  r"t        | d   t
        «      rt        | d   «      }nt        | «      }t        j                  |«      S )z¯
    Unify variable types of size argument to torch.Size
    Acceptable types include:
        int, Sequence[int], Tuple[int], Tuple[Sequence[int]],
        or torch.Size
    r   r   )r   ÚtorchÚSizeÚintr    r   r   )r$   Ú
torch_sizes     r   Únormalize_to_torch_sizerf     se   € ô �$œŸ
™
Ô#Øˆä�$œÔØ�V‰
Ü	ˆT‹�aŠœJ t¨A¡w´Ô9Ü˜$˜q™'“]‰
ä˜$“Zˆ
Ü�:‰:�jÓ!Ð!rP   )#Úcollections.abcr   Útypingr   rb   Útorch.distributed.tensor._apiÚdistributedrB   Ú_apirT   Útorch._prims_commonr   Útorch.distributed.device_meshr   Ú&torch.distributed.tensor._dtensor_specr   Ú(torch.distributed.tensor.placement_typesr   r	   r
   r   r   r,   rd   rA   ÚTensorr   rO   Ú_opsÚ
OpOverloadÚobjectrY   r`   rc   rf   r   rP   r   ú<module>rt      s$  ðÝ $Ý ã ß /Ó /Ý )Ý 4Ý >÷õ ðQ8ØðQ8Ø#-ðQ8Ø;CÀIÑ;NðQ8à
ˆ5��c�‰?˜E # s (™OÐ+Ñ,óQ8ðh8'Ø�L‰Lð8'Ø *ð8'Ø8@ÀÑ8Kð8'à
ˆ4�‰9�d˜3‘iÐÑ ó8'ðvOØ�Z‰Z×"Ñ"ðOØ*2°6Ñ*:ðOàóOð*ØðØ$.ðØ<DÀYÑ<Oðà
ˆ3�ˆ8�_óð," U§Z¡Zô "rP   