§
    Ÿ²Åjî¾  ã            
       óv  — U d dl Z d dlZd dlZd dl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gZ e¦   «         s:d dlZ G d	„ d
¦  «        Zd„ Zeej        d         _        eej        d         _        dS d dlmZ d dlmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)  e j*        e+¦  «        Z,er(	 d dl-m.Z. n # e/$ r e, 0                    d¦  «         Y nw xY w G d„ dej1        ¦  «        Z2 e2¦   «         Z3e2e4d<   dde5fd„Z6 G d„ d¦  «        Zddœde5dee7df         de
ee5df                  defd„ZdS )é    N©Úreduce)Úchain)ÚDictÚListÚOptionalÚTupleÚTYPE_CHECKINGÚUnion)Úis_available)Únot_noneÚinit_device_meshÚ
DeviceMeshc                   ó   — e Zd ZdS )Ú_DeviceMeshStubN)Ú__name__Ú
__module__Ú__qualname__© ó    úNC:\Projects\Historical\venv\Lib\site-packages\torch/distributed/device_mesh.pyr   r      s   € € € € € Øˆr   r   c                  ó   — d S ©Nr   r   r   r   Ú_init_device_mesh_stubr      s   € Øˆr   ztorch.distributed.device_mesh)ÚBackend)Ú_find_pg_by_ranks_and_tagÚ_get_default_groupÚ_get_group_tagÚget_backendÚget_process_group_ranksÚget_rankÚget_world_sizeÚinit_process_groupÚis_initializedÚ	new_groupÚProcessGroupÚsplit_group)Ú	ArrayLikezCDeviceMesh requires numpy >= 1.21 to be installed for type checkingc            	       óx  — e Zd Zdd„Zdd„Zdddeedf         d	eeedf                  ddfd
„Z		 dddde
e         ddfd„Zdd„Zddde
e         fd„Zededefd„¦   «         Zededefd„¦   «         Zdddedefd„Z	 ddedede
ej                 ddfd„Zdeeedf                  fd„Zdddeded         fd„ZdS )Ú_MeshEnvÚreturnNc                 óL   — g | _         i | _        i | _        i | _        i | _        d S r   )Ú
mesh_stackÚchild_to_root_mappingÚmesh_dim_group_optionsÚroot_to_flatten_mappingÚflatten_name_to_root_dims©Úselfs    r   Ú__init__z_MeshEnv.__init__C   s=   € Ø02ˆDŒOØGIˆDÔ&ð ð Ô'ð UWˆDÔ(ð ð Ô*Ð*Ð*r   r   c                 ój   — t          | j        ¦  «        dk    rt          d¦  «        ‚| j        d         S )Nr   z#No device mesh is currently active!éÿÿÿÿ)Úlenr-   ÚRuntimeErrorr2   s    r   Úget_current_meshz_MeshEnv.get_current_meshO   s3   € Ý�4”?Ñ#Ô# qÒ(Ð(Ý"Ð#HÑIÔIÐIØ”? 2Ô&Ð&r   Údevice_meshÚsubmesh_dim_names.Úsubmesh_dimsc                 óp  ‡— ˆfd„|D ¦   «         }‰j         }g }g }d}t          ||¦  «        D ]ê\  }	}
t          |	¦  «        dk    rŽ|                     |	d         |z
  |	d         |z
  ¬¦  «        }|                     |	d         |z
  ¦  «         |t          |	¦  «        dz
  z  }|                     | j        ‰         |
         j        d         ¦  «         Œ¦|                     |	d         |z
  ¦  «         |                     ‰j        |	d                  ¦  «         Œët          t          |j	        ¦  «        ¦  «        }|D ]}| 
                    |¦  «         Œ  |j        g |¢|¢R Ž j        dg|¢R Ž }‰                     ¦   «         }|D ] }t          ‰j        ||d¬¦  «        }||v r|}Œ!||_        ‰| j        |<   |S )Nc                 ó8   •— g | ]}t          ˆfd „|d¦  «        ‘ŒS )c                 ó>   •— | ‰j                              |¦  «        z  S r   )ÚmeshÚsize)ÚxÚyr:   s     €r   ú<lambda>z5_MeshEnv.create_sub_mesh.<locals>.<listcomp>.<lambda>`   s   ø€   [Ô%5×%:Ò%:¸1Ñ%=Ô%=Ñ!=€ r   é   r   )Ú.0Úmesh_dimr:   s     €r   ú
<listcomp>z,_MeshEnv.create_sub_mesh.<locals>.<listcomp>^   sG   ø€ ð ð ð ð õ Ø=Ð=Ð=Ð=ØØñô ðð ð r   r   rE   r6   )Ú	start_dimÚend_dimF©Úmesh_dim_namesÚ_init_backend)r@   Úzipr7   ÚflattenÚappendr0   Ú_dim_group_infosÚlistÚrangeÚndimÚremoveÚpermuteÚreshaper!   r   Údevice_typer.   )r3   r:   r;   r<   Úslice_dim_sizeÚmesh_tensorÚslice_dim_idxÚslice_dim_group_infoÚnum_dims_flattenÚmesh_dim_indicesÚmesh_dim_nameÚmesh_dims_remained_idxÚidxÚpg_ranks_by_dimÚcur_rankÚmesh_ndÚsubmeshÚres_submeshs    `                r   Úcreate_sub_meshz_MeshEnv.create_sub_meshT   sy  ø€ ðð ð ð ð !-ðñ ô ˆNð &Ô*ˆKàˆMØ#%Ð ð  !ÐÝ36°|ÐEVÑ3WÔ3Wð ð Ñ/Ð  -õ Ð'Ñ(Ô(¨1Ò,Ð,à"-×"5Ò"5Ø"2°1Ô"5Ð8HÑ"HØ 0°Ô 4Ð7GÑ Gð #6ñ #ô #�Kð "×(Ò(Ð)9¸!Ô)<Ð?OÑ)OÑPÔPÐPØ$­Ð,<Ñ(=Ô(=ÀÑ(AÑAÐ$Ø(×/Ò/ØÔ4°[ÔAØ)ôä*¨1ô.ñô ð ð ð "×(Ò(Ð)9¸!Ô)<Ð?OÑ)OÑPÔPÐPØ(×/Ò/Ø#Ô4Ð5EÀaÔ5HÔIñô ð ð õ
 &*­%°Ô0@Ñ*AÔ*AÑ%BÔ%BÐ"Ø$ð 3ð 3�Ø&×-Ò-¨cÑ2Ô2Ð2Ð2ð
Ð1˜kÔ1ð Ø'ðØ*7ðð ð ä�bð+à)ð+ð +ð +ˆOð #×+Ò+Ñ-Ô-ˆHØ*ð *ð *�Ý$ØÔ+ØØ#4Ø"'ð	ñ ô �ð ˜wÐ&Ð&Ø")�Køà+?ˆKÔ(Ø6AˆDÔ& {Ñ3àÐr   r_   c                 ó<  ‡— t                                |¦  «        Šˆfd„t          |j        ¦  «        D ¦   «         }|s!d                     ˆfd„|D ¦   «         ¦  «        }| j                             ‰i ¦  «         t          g t          t          ‰j        ¦  «        ¦  «        ¢| j        ‰          	                    ¦   «         ¢R Ž }||v rt          |› d‰› d�d|› d�¦  «        ‚‰| j        v r"|| j        ‰         v r| j        ‰         |         S t          j        |j                             ¦   «         ¦  «        }t          t!          ‰j        j        ¦  «        ¦  «        }|D ]}|                     |¦  «         Œ ‰j        j        g |¢|¢R Ž                      d|¦  «        }‰                     ¦   «         }	|D ] }
t-          ‰j        |
|f¬	¦  «        }|	|
v r|}Œ!‰| j        |<   || j                             ‰i ¦  «        |<   t3          |¦  «        | j        ‰         |<   |S )
Nc                 ó^   •— g | ])}t          ‰j        ¦  «                             |¦  «        ‘Œ*S r   )r   rL   Úindex)rF   Úflattened_mesh_dim_nameÚ	root_meshs     €r   rH   z0_MeshEnv.create_flatten_mesh.<locals>.<listcomp>¨   sC   ø€ ð $ð $ð $à+õ ˜Ô1Ñ2Ô2×8Ò8Ð9PÑQÔQð$ð $ð $r   Ú_c                 óD   •— g | ]}t          ‰j        ¦  «        |         ‘ŒS r   )r   rL   )rF   Údimrl   s     €r   rH   z0_MeshEnv.create_flatten_mesh.<locals>.<listcomp>¯   s9   ø€ ð ð ð àõ ! Ô!9Ñ:Ô:¸3Ô?ðð ð r   z# already exists for submesh of the ú. z5The mesh_dim_names of submesh and flattened mesh are z-. Please specify another valid mesh_dim_name.r6   ©rL   )Ú_mesh_resourcesÚget_root_meshr   rL   Újoinr1   Ú
setdefaultr   rR   Úkeysr8   r0   ÚmathÚprodr@   rA   rS   rT   rU   rV   rW   r!   r   rX   r.   Útuple)r3   r:   r_   Úflatten_dims_in_rootÚinvalid_dim_namesÚflattened_mesh_dim_sizeÚremained_dims_in_rootÚflatten_dim_in_rootrb   rc   rd   Úflattened_meshÚres_flattened_meshrl   s                @r   Úcreate_flatten_meshz_MeshEnv.create_flatten_mesh£   sÂ  ø€ õ (×5Ò5°kÑBÔBˆIð$ð $ð $ð $å/7¸Ô8RÑ/SÔ/Sð$ñ $ô $Ð ð
 !ð Ø #§¢ðð ð ð à#7ðñ ô ñ!ô !�ð Ô*×5Ò5°iÀÑDÔDÐDÝ %ð !Ý•h˜yÔ7Ñ8Ô8Ñ9Ô9ð!àÔ/°	Ô:×?Ò?ÑAÔAð!ð !ð !Ðð Ð 1Ð1Ð1Ý"Ø$ÐVÐVÈÐVÐVÐVðCÐL]ð Cð Cð Cñô ð ð ˜TÔ9Ð9Ð9Ø! TÔ%AÀ)Ô%LÐLÐLàÔ3°IÔ>¸}ÔMÐMå&*¤i°Ô0@×0EÒ0EÑ0GÔ0GÑ&HÔ&HÐ#å$(­¨y¬~Ô/BÑ)CÔ)CÑ$DÔ$DÐ!Ø';ð Bð BÐ#Ø%×,Ò,Ð-@ÑAÔAÐAÐAà4˜iœnÔ4ð Ø&ðØ)=ðð ð çŠg�bÐ1Ñ2Ô2ð ð !×)Ò)Ñ+Ô+ˆHØ*ð 8ð 8�å!+ØÔ)ØØ$1Ð#3ð"ñ "ô "�ð
 ˜wÐ&Ð&Ø)7Ð&øØ=FˆDÔ&Ð'9Ñ:ØTfˆDÔ(×3Ò3°I¸rÑBÔBÀ=ÑQÝGLÐMaÑGbÔGbˆDÔ*¨9Ô5°mÑDà%Ð%r   c                 óD   — | j                              |d ¦  «        }|s|n|S r   )r.   Úget)r3   r:   rl   s      r   rs   z_MeshEnv.get_root_meshå   s+   € ð Ô2×6Ò6°{ÀDÑIÔIˆIØ&/Ð>�;�;°YÐ>r   c                 ó¼   — |                       |¦  «        }|j        }|r=|r;t          |¦  «        dk    s
J d¦   «         ‚|d         }|                      ||¦  «        S dS )zÆ
            Returns the index of the mesh dim in the root mesh.
            The device_mesh passed in needs to be sliced out from the root mesh
            or submesh of the root mesh.
            rE   z"The submesh can only be a 1D mesh.r   N)rs   rL   r7   Úget_mesh_dim_by_name)r3   r:   rl   Úchild_mesh_dim_namesÚchild_mesh_dim_names        r   Úget_root_mesh_dimz_MeshEnv.get_root_mesh_dimì   s~   € ð ×*Ò*¨;Ñ7Ô7ˆIØ#.Ô#=Ð Øð QÐ1ð QåÐ,Ñ-Ô-°Ò2Ð2Ð2Ø7ñ 3Ô2Ð2à&:¸1Ô&=Ð#Ø×0Ò0°Ð<OÑPÔPÐPØ�4r   rX   c                 óD   — t          | ¦  «                             ¦   «         S r   )Ú_get_device_handleÚdevice_count©rX   s    r   Únum_devices_per_hostz_MeshEnv.num_devices_per_hostü   s   € å% kÑ2Ô2×?Ò?ÑAÔAÐAr   c                 óT   — t          ¦   «         t                               | ¦  «        z  S r   )r"   r*   r�   rŒ   s    r   Ú	num_hostsz_MeshEnv.num_hosts   s#   € õ "Ñ#Ô#¥x×'DÒ'DÀ[Ñ'QÔ'QÑQÐQr   c                 óö   — |j         �t          |j         ¦  «        dk    rt          d¦  «        ‚||j         vrt          d|› d�d|j         › �¦  «        ‚t          |j                              |¦  «        ¦  «        S )Nr   zNo `mesh_dim_names` found.zMesh dimension 'z' does not exist.z.Available mesh dimensions are: mesh_dim_names=)rL   r7   ÚKeyErrorr   rj   )r3   r:   r_   s      r   r…   z_MeshEnv.get_mesh_dim_by_name  s—   € ð Ô*Ð2Ý�{Ô1Ñ2Ô2°aÒ7Ð7åØ0ñô ð ð  KÔ$>Ð>Ð>ÝØG }ÐGÐGÐGØaÀ[ÔE_ÐaÐañô ð õ ˜KÔ6×<Ò<¸]ÑKÔKÑLÔLÐLr   ro   ÚbackendÚ
pg_optionsc                 ó   — ||f| j         |<   d S r   )r/   )r3   ro   r’   r“   s       r   Ú_set_mesh_dim_group_optionsz$_MeshEnv._set_mesh_dim_group_options  s   € ð 18¸Ð/DˆDÔ'¨Ñ,Ð,Ð,r   c                 ó(  ‡	— ||                       |¦  «        k    rt          d¦  «        ‚| j                             |i ¦  «         | j        |         }g |j        ¢|¢Š	t          ˆ	fd„|D ¦   «         ¦  «        st          d|› d‰	› d�¦  «        ‚d}g }|D ]}}||v r&||         }|d         }|                     |¦  «         n0|j                             |¦  «        }|                     |f¦  «         ||k    rt          d|› d�d|› d	�d
¦  «        ‚|}Œ~|S )z¸
            Validate whether the mesh_dim_names is valid for slicing the given device_mesh.
            If valid, return dim indexes of the slice mesh in the device mesh.
            z'Cannot create a submesh from a submesh.c              3   ó    •K  — | ]}|‰v V — Œ	d S r   r   )rF   r_   Úvalid_mesh_dim_namess     €r   ú	<genexpr>z0_MeshEnv._get_slice_mesh_dims.<locals>.<genexpr>2  s=   øè è € ð ð à!ð Ð!5Ð5ðð ð ð ð ð r   zInvalid mesh_dim_names z% specified. Valid mesh_dim_names are ú.r6   z specified. z!Found mesh dim indices to slice: rp   z.Mesh dim indices should be in ascending order.)	rs   r8   r1   ru   rL   Úallr‘   rP   rj   )
r3   r:   rL   r1   Úcurr_idxÚslice_mesh_dimsr_   Úmesh_indicesÚnext_idxr˜   s
            @r   Ú_get_slice_mesh_dimsz_MeshEnv._get_slice_mesh_dims  s³  ø€ ð ˜d×0Ò0°Ñ=Ô=Ò=Ð=Ý"Ð#LÑMÔMÐMð Ô*×5Ò5°kÀ2ÑFÔFÐFØ(,Ô(FÀ{Ô(SÐ%ð$ØÔ+ð$à*ð$Ð õ
 ð ð ð ð à%3ðñ ô ñ ô ð õ ðH¨nð Hð HØ0DðHð Hð Hñô ð ð ˆHØ ˆOØ!/ð $ð $�Ø Ð$=Ð=Ð=Ø#<¸]Ô#K�Lð  ,¨BÔ/�HØ#×*Ò*¨<Ñ8Ô8Ð8Ð8à*Ô9×?Ò?ÀÑNÔN�HØ#×*Ò*¨H¨;Ñ7Ô7Ð7Ø˜xÒ'Ð'Ý"ØN°.ÐNÐNÐNØO¸OÐOÐOÐOØHñô ð ð
 $��à"Ð"r   c                 ó„  — |                       ||¦  «        }|j                             d|¦  «                             d|j                             |¦  «        ¦  «        }|                     ¦   «         }g }|D ]I}t          |j        ||fd¬¦  «        }||v r|j        |         gng |_        | 	                    |¦  «         ŒJ|S )z`
            Return all the submeshes of a given mesh dimension of the device mesh.
            r6   FrK   )
r…   r@   ÚswapdimsrW   rA   r!   r   rX   rQ   rP   )	r3   r:   r_   rG   rb   rc   Úres_submeshesÚmesh_1dre   s	            r   Ú_get_all_submeshesz_MeshEnv._get_all_submeshesS  sî   € ð ×0Ò0°¸mÑLÔLˆHØ)Ô.×7Ò7¸¸HÑEÔE×MÒMØ�KÔ$×)Ò)¨(Ñ3Ô3ñô ˆOð #×+Ò+Ñ-Ô-ˆHØˆMØ*ð .ð .�Ý$ØÔ+ØØ$1Ð#3Ø"'ð	ñ ô �ð   7Ð*Ð*ð !Ô1°(Ô;Ð<Ð<àð Ô(ð
 ×$Ò$ WÑ-Ô-Ð-Ð-à Ð r   ©r+   N©r+   r   r   )r:   r   r+   r   )r   r   r   r4   r9   r	   Ústrr   Úintrg   r   r�   rs   rˆ   Ústaticmethodr�   r�   r…   ÚC10dBackendÚOptionsr•   r    r¥   r   r   r   r*   r*   B   s^  € € € € € ð
	ð 
	ð 
	ð 
	ð	'ð 	'ð 	'ð 	'ð
M	à%ðM	ð  % S¨# XœðM	ð ˜u S¨# XœÔ/ð	M	ð
 ðM	ð M	ð M	ð M	ð` MQð@	&ð @	&Ø+ð@	&Ø<DÀS¼Mð@	&àð@	&ð @	&ð @	&ð @	&ðD	?ð 	?ð 	?ð 	?ð	°ð 	À(È3Ä-ð 	ð 	ð 	ð 	ð  
ð	B¨cð 	B°cð 	Bð 	Bð 	Bñ 
Œð	Bð 
ð	R 3ð 	R¨3ð 	Rð 	Rð 	Rñ 
Œð	Rð
	MØ+ð	MØ<?ð	Màð	Mð 	Mð 	Mð 	Mð* 9=ð		Eð 	Eàð	Eð ð	Eð ! Ô!4Ô5ð		Eð
 ð	Eð 	Eð 	Eð 	Eð2	#à�%˜˜S˜”/Ô"ð2	#ð 2	#ð 2	#ð 2	#ðh	!Ø+ð	!Ø<?ð	!à�,Ôð	!ð 	!ð 	!ð 	!ð 	!ð 	!r   r*   rr   ÚcudarX   c                 ó.   — t          t          | d¦  «        S )a:  
        Get the module corresponding to the device_type which is cuda or cuda-like device.
        For example, when the device_type is cuda, the module `torch.cuda` is returned.
        Return None when there is no corresponding module for device_type, otherwise
        return the corresponding module.
        N)ÚgetattrÚtorchrŒ   s    r   rŠ   rŠ   r  s   € õ •u˜k¨4Ñ0Ô0Ð0r   c                   óÜ  — e Zd ZU dZeed<   ej        ed<   ee	edf                  ed<   dddœdede
ej        d	f         dee	edf                  d
eddf
d„Zd„ Zd„ Zd$d„Zd%d„Zdefd„Zd„ Zdedefd„Zde
ee	edf         f         dd fd„Zd&dee
eef                  defd„Zdee         fd„Ze	 d&ddœde
eee         f         dedee
ej        d	f                  dee	edf                  dd f
d„¦   «         Zd&dee         defd„Zedefd„¦   «         Zede	edf         fd„¦   «         Z defd„Z!d&dee
eef                  defd „Z"deee                  fd!„Z#d&d"ee         dd fd#„Z$dS )'r   aÈ  
        DeviceMesh represents a mesh of devices, where layout of devices could be
        represented as a n-d dimension array, and each value of the n-d dimensional
        array is the global id of the default process group ranks.

        DeviceMesh could be used to describe the layout of devices across the cluster,
        and serves as a proxy for communication among the device lists within the cluster.

        DeviceMesh can be used as a context manager.

        .. note::
            DeviceMesh follows SPMD programming model, which means the same PyTorch Python program
            is running on all processes/ranks in the cluster. Therefore, users need to make sure the
            `mesh` array (which describes the layout of devices) should be identical across all ranks.
            Inconsistent `mesh` will lead to silent hang.

        Args:
            device_type (str): The device type of the mesh. Currently supports: "cpu", "cuda/cuda-like".
            mesh (ndarray): A multi-dimensional array or an integer tensor describing the layout
                of devices, where the IDs are global IDs of the default process group.

        Returns:
            DeviceMesh: A :class:`DeviceMesh` object representing the device layout.

        The following program runs on each process/rank in an SPMD manner. In this example, we have 2
        hosts with 4 GPUs each.
        A reduction over the first dimension of mesh will reduce across
        columns (0, 4), .. and (3, 7), a reduction over the second dimension
        of mesh reduces across rows (0, 1, 2, 3) and (4, 5, 6, 7).

        Example::
            >>> # xdoctest: +SKIP("no rank")
            >>> from torch.distributed.device_mesh import DeviceMesh
            >>>
            >>> # Initialize device mesh as (2, 4) to represent the topology
            >>> # of cross-host(dim 0), and within-host (dim 1).
            >>> mesh = DeviceMesh(device_type="cuda", mesh=[[0, 1, 2, 3],[4, 5, 6, 7]])
        rX   r@   .rL   NTrK   r(   rM   r+   c                óô  — || _         t          |t          j        ¦  «        r"|j        j        dk    rt          d|› �¦  «        ‚t          |t          j        ¦  «        r2|                     ¦   «                              t          j	        ¬¦  «        n t          j
        |dt          j	        ¬¦  «        | _        |rt          |¦  «        nd | _        t          | j                             ¦   «                              ¦   «         ¦  «        | _        d | _        |dk    rà|r(|                      ¦   «          |                      ¦   «          t)          ¦   «         r*t+          ¦   «         dk    rt-          j        ¦   «         | _        | j        t1          ¦   «         k                         ¦   «         }|                     d¦  «        dv sJ ‚|                     d¦  «        dk    r|d                              ¦   «         nd | _        d S d S )	NÚcpuz!`mesh` must be a CPU tensor, got ©Údtype©Údevicerµ   ÚxlaÚthreadedr   )r   rE   )rX   Ú
isinstancer°   ÚTensorr·   ÚtypeÚ
ValueErrorÚdetachÚtor©   Útensorr@   ry   rL   rO   ÚtolistÚ_flatten_mesh_listÚ
_thread_idÚ_get_or_create_default_groupÚ_init_process_groupsr$   r   Ú	threadingÚ	get_identr!   ÚnonzerorA   Ú_coordinate_on_dim)r3   rX   r@   rL   rM   Úrank_coordss         r   r4   zDeviceMesh.__init__§  sÕ  € ð  +ˆDÔÝ˜$¥¤Ñ-Ô-ð M°$´+Ô2BÀeÒ2KÐ2KÝ Ð!KÀTÐ!KÐ!KÑLÔLÐLõ ˜d¥E¤LÑ1Ô1ðG�—’‘”× Ò ¥u¤yÐ Ñ1Ô1Ð1å”\ $¨u½E¼IÐFÑFÔFð ŒIð
 <JÐ"S¥%¨Ñ"7Ô"7Ð"7ÈtˆDÔõ ',¨D¬I×,=Ò,=Ñ,?Ô,?×,FÒ,FÑ,HÔ,HÑ&IÔ&IˆDÔ#Ø"ˆDŒOð ˜eÒ#Ð#ð !ð 0Ø×5Ò5Ñ7Ô7Ð7Ø×-Ò-Ñ/Ô/Ð/å!Ñ#Ô#ð <­©¬¸Ò(CÐ(CÝ&/Ô&9Ñ&;Ô&;�D”Oð  $œy­H©J¬JÒ6×?Ò?ÑAÔA�Ø"×'Ò'¨Ñ*Ô*¨fÐ4Ð4Ð4Ð4à/:×/?Ò/?ÀÑ/BÔ/BÀQÒ/FÐ/F�K ”N×)Ò)Ñ+Ô+Ð+ÈDð Ô'Ð'Ð'ð $Ð#r   c           	      ó  — t          ¦   «         }|st          ¦   «          t          ¦   «         }| j                             ¦   «         |k    r-t          d|› d| j                             ¦   «         › d�¦  «        ‚t          | j        ¦  «        }|sg|re|                     ¦   «         }||k    r'||z  dk    rt          d|› d|› d| j        › d�¦  «        ‚| 	                    t          ¦   «         |z  ¦  «         t          ¦   «         S )	Nz2Mesh should not be bigger than default world size z, but found z ranks!r   z8DeviceMesh only support homogeneous hardware, but found z ranks and ú z	 devices!)r$   r#   r"   r@   Únumelr8   rŠ   rX   r‹   Ú
set_devicer!   r   )r3   Údefault_initializedÚ
world_sizeÚdevice_handler�   s        r   rÄ   z'DeviceMesh._get_or_create_default_groupÑ  sJ  € Ý"0Ñ"2Ô"2ÐØ&ð %Ý"Ñ$Ô$Ð$å'Ñ)Ô)ˆJØŒy�ŠÑ Ô  :Ò-Ð-Ý"Ø{ÈÐ{Ð{ÐaeÔaj×apÒapÑarÔarÐ{Ð{Ð{ñô ð õ /¨tÔ/?Ñ@Ô@ˆMà&ð L¨=ð Lð (5×'AÒ'AÑ'CÔ'CÐ$àÐ!5Ò5Ð5Ø"Ð%9Ñ9¸QÒ>Ð>å&ðeØ%ðeð eØ2Fðeð eØIMÔIYðeð eð eñô ð ð ×(Ò(­©¬Ð6JÑ)JÑKÔKÐKå%Ñ'Ô'Ð'r   c           	      ó  — g }t          ¦   «         }| j        j        dk    rÂ| j                             ¦   «         t	          ¦   «         k    r™t          t          t	          ¦   «         ¦  «        ¦  «        }t          j         	                    ¦   «         r%t          |¦  «        dk    rt          d|d¬¦  «        n|}|                     t          |¦  «        ||j        f¦  «         �n›t          | j        j        ¦  «        D �]€}| j                             d|¦  «                             d| j                             |¦  «        ¦  «        }|t$          j        v rt$          j        |         \  }}nd\  }}| j        rd| j        |         › �nd	|› �}	d }t+          |d
d ¦  «        x}
	 �%t-          |||                     ¦   «         |	¬¦  «        }|D ]³}|                     ¦   «         }|
€t          ||||	¬¦  «        }|                      ¦   «         |v rrt3          |¦  «        |k    r(t5          d|                      ¦   «         › d|› d�¦  «        ‚|                     t          t7          |¦  «        ¦  «        ||j        f¦  «         Œ´�Œ‚|| _        d S )NrE   Úgloozcpu:gloo,cuda:ncclÚmesh_default)r’   ÚranksÚ
group_descr6   )NNÚmesh_Ú	mesh_dim_Úbound_device_id)Ú	parent_pgr“   Úsplit_ranksrÖ   )rÕ   r’   r“   rÖ   zFEach device mesh dimension should get only one process group, but got z in ú!)r   r@   rT   rÍ   r"   rR   rS   r°   r­   r   r   r%   rP   r   Ú
group_namer¢   rW   rA   rr   r/   rL   r¯   r'   rÁ   r!   r7   r8   r   rQ   )r3   Údim_group_infosÚdefault_grouprÕ   Ú	dim_groupro   rb   r’   r“   rÖ   rÙ   Údim_meshÚsubgroup_rankss                r   rÅ   zDeviceMesh._init_process_groupsî  s  € ð ACˆOÝ.Ñ0Ô0ˆMàŒyŒ~ Ò"Ð" t¤y§¢Ñ'8Ô'8½NÑ<LÔ<LÒ'LÐ'Lõ �U¥>Ñ#3Ô#3Ñ4Ô4Ñ5Ô5�õ ”z×.Ò.Ñ0Ô0ð'õ $ MÑ2Ô2°fÒ<Ð<õ Ø 4Ø#Ø#1ðñ ô ð ð 'ð ð  ×&Ò&å& yÑ1Ô1ØØ!Ô,ðñô ð ñ õ ! ¤¤Ñ0Ô0ð Pñ P�Cð '+¤i×&8Ò&8¸¸SÑ&AÔ&A×&IÒ&IØ˜DœIŸNšN¨3Ñ/Ô/ñ'ô '�Oð �oÔDÐDÐDõ ,ÔBÀ3ÔGñØ#Ø&˜Jð /9Ñ+˜ ð  Ô.ð/Ð: Ô 3°CÔ 8Ð:Ð:Ð:à.¨Ð.Ð.ð ð !%�Iå+2Ø)Ð+<¸dñ,ô ,ð ˜ð "ð	"õ
 %0Ø&3Ø'1Ø(7×(>Ò(>Ñ(@Ô(@Ø'1ð	%ñ %ô %˜	ð %4ð ð ˜Ø)1¯ªÑ):Ô):˜ð
 +Ð2Ý(1Ø&4Ø(/Ø+5Ø+5ð	)ñ )ô )˜Ið  Ÿ=š=™?œ?¨nÐ<Ð<Ý" ?Ñ3Ô3°cÒ9Ð9Ý&2ð%<Ðmq×mzÒmzÑm|Ôm|ð %<ð %<Ø*8ð%<ð %<ð %<ñ'"ô '"ð !"ð ,×2Ò2å$2µ8¸IÑ3FÔ3FÑ$GÔ$GØ$2Ø$-Ô$8ð!"ñô ð øñ+ð8 %4ˆDÔ!Ð!Ð!r   c                 óD   — t           j                             | ¦  «         | S r   )rr   r-   rP   r2   s    r   Ú	__enter__zDeviceMesh.__enter__b  s   € åÔ&×-Ò-¨dÑ3Ô3Ð3ØˆKr   c                 óB   — t           j                             ¦   «          d S r   )rr   r-   Úpop)r3   Úexc_typeÚ	exc_valueÚexc_tracebacks       r   Ú__exit__zDeviceMesh.__exit__h  s   € åÔ&×*Ò*Ñ,Ô,Ð,Ð,Ð,r   c                 ó¸   — | j         s%d| j        › d| j                             ¦   «         › d�n,d| j        › d| j                             ¦   «         › d| j         › d�}|S )NzDeviceMesh('z', ú)z, mesh_dim_names=)rL   rX   r@   rÁ   )r3   Údevice_mesh_reprs     r   Ú__repr__zDeviceMesh.__repr__l  sz   € ð Ô*ðuÐI˜tÔ/ÐIÐI°D´I×4DÒ4DÑ4FÔ4FÐIÐIÐIÐIàt DÔ$4ÐtÐt¸¼×9IÒ9IÑ9KÔ9KÐtÐtÐ^bÔ^qÐtÐtÐtð ð
 $Ð#r   c                 ó¸   — t          | dd ¦  «        | _        | j        s7t          | j        | j        j        | j        | j        | j        f¦  «        | _        | j        S )NÚ_hash)	r¯   rð   ÚhashrÂ   r@   ÚshaperX   rL   rÃ   r2   s    r   Ú__hash__zDeviceMesh.__hash__t  s]   € å   w°Ñ5Ô5ˆDŒJØ”:ð 	Ý!àÔ/Øœ	œØÔ(ØÔ+Øœðñô �”
ð ”:Ðr   Úotherc                 ó(  — t          |t          ¦  «        sdS t          | ¦  «        t          |¦  «        k    rdS | j        |j        k    oI| j        j        |j        j        k    o/| j        |j        k    o| j        |j        k    o| j        |j        k    S )NFT)	rº   r   ÚidrÂ   r@   rò   rX   rL   rÃ   )r3   rô   s     r   Ú__eq__zDeviceMesh.__eq__ƒ  sœ   € Ý˜e¥ZÑ0Ô0ð Ø�uÝ�$‰xŒx�2˜e™9œ9Ò$Ð$Ø�tð Ô+¨uÔ/GÒGð <Øœ	œ¨5¬:Ô+;Ò;ð<àÔ(¨EÔ,=Ò=ð<ð Ô+¨uÔ/CÒCð<ð œ¨5Ô+;Ò;ðr   c                 ód  — | j         st          d¦  «        ‚t          |t          ¦  «        r|fn|}|| j         k    r| S t                               | |¦  «        }t          j        j         	                    ¦   «         5  t           
                    | ||¦  «        }ddd¦  «         n# 1 swxY w Y   |S )aU
  
            Slice the current DeviceMesh based on the mesh_dim_names given to create a submesh.
            The submesh created consists of the dimensions and the communicators indicated by
            ``mesh_dim_names``

            Args:
                mesh_dim_names (Union[str, Tuple[str]]): the name or the tuple of names of the
                mesh dimension of the DeviceMesh to create the submesh for.
            Returns:
                A :class:`DeviceMesh` object

            The following program runs on each process/rank in an SPMD manner in a world size of 8.
            In the first example:
                Calling mesh_2d["tp"] on rank 0, 1, 2, 3 returns a 1D submesh of DeviceMesh:([0, 1, 2, 3]).
                Calling mesh_2d["tp"] on rank 4, 5, 6, 7 returns a 1D submesh of  DeviceMesh:([4, 5, 6, 7]).
                Calling mesh_2d["dp"] on rank 0, 4 returns a 1D submesh of  DeviceMesh:([0, 4]).
                Calling mesh_2d["dp"] on rank 1, 5 returns a 1D submesh of  DeviceMesh:([1, 5]).
                Calling mesh_2d["dp"] on rank 2, 6 returns a 1D submesh of  DeviceMesh:([2, 6]).
                Calling mesh_2d["dp"] on rank 3, 7 returns a 1D submesh of  DeviceMesh:([3, 7]).

            In the second example:
                Calling mesh_3d["dp", "cp"] on rank 0, 1, 4, 5 returns a 2D submesh of DeviceMesh:([[0, 1], [4, 5]]).
                Calling mesh_3d["dp", "cp"] on rank 2, 3, 6, 7 returns a 2D submesh of DeviceMesh:([[2, 3], [6, 7]]).
                Calling mesh_3d["cp", "dp"] on rank 0, 1, 4, 5 returns a 2D submesh of DeviceMesh:([[0, 4], [1, 5]]).
                Calling mesh_3d["cp", "dp"] on rank 2, 3, 6, 7 returns a 2D submesh of DeviceMesh:([[2, 6], [3, 7]]).

            Example::
                >>> # xdoctest: +SKIP("no rank")
                >>> from torch.distributed.device_mesh import DeviceMesh
                >>>
                >>> # Initialize a 2D device mesh as (2, 4) to represent the topology
                >>> # of cross-host(dim 0), and within-host (dim 1).
                >>> mesh_2d = init_device_mesh(device_type="cuda", (2,4), mesh_dim_names=("dp", "tp"))
                >>> tp_mesh = mesh_2d["tp"]
                >>> dp_mesh = mesh_2d["dp"]
                >>>
                >>> # Initialize a 3D mesh.
                >>> mesh_3d = init_device_mesh(device_type="cuda", (2,2,2), mesh_dim_names=("dp", "pp", "cp"))
                >>> # The order of the mesh_dim_names provided deteremines the order of dimensions in the submesh.
                >>> dp_cp_mesh = mesh_3d["dp", "cp"]
                >>> cp_dp_mesh = mesh_3d["cp", "dp"]
            z1Cannot slice a DeviceMesh without mesh_dim_names!N)rL   r8   rº   r¨   rr   r    r°   Ú_subclassesÚfake_tensorÚunset_fake_temporarilyrg   )r3   rL   r�   re   s       r   Ú__getitem__zDeviceMesh.__getitem__‘  s  € ðZ Ô&ð XÝ"Ð#VÑWÔWÐWõ &0°ÅÑ%DÔ%DÐX�Ð!Ð!È.ð ð  Ô!4Ò4Ð4Ø�å"1×"FÒ"FØ˜.ñ#ô #�õ Ô&Ô2×IÒIÑKÔKð ð Ý-×=Ò=Ø˜n¨oñô �Gðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð �s   Á<B%Â%B)Â,B)rG   c                 óÔ  — t          | d¦  «        st          d¦  «        ‚| j        j        dk    r!|€t          d| j        j        › d�dd¦  «        ‚| j        j        dk    r+|€)t	          t          | j        d	         dd
…         Ž ¦  «        S t                               | ¦  «        }t          j	         
                    |d¦  «        }|rG||                     ¦   «         v r1||         j        d	         dd
…         }t	          t          |Ž ¦  «        S t          |t          ¦  «        rt                               | |¦  «        n|}t	          t          | j        |         dd
…         Ž ¦  «        S )aÂ  
            Returns the single ProcessGroup specified by mesh_dim, or, if mesh_dim is not specified and the
            DeviceMesh is 1-dimensional, returns the only ProcessGroup in the mesh.

            Args:
                mesh_dim (str/int, optional): it can be the name of the mesh dimension or the index
                of the mesh dimension. Default is None.

            Returns:
                A :class:`ProcessGroup` object.
            rQ   z*DeviceMesh process groups not initialized!rE   NúFound the DeviceMesh have ú dimensionsúJOptional kwarg `mesh_dim` needs to be specified when device_mesh.ndim > 1.zmIf you want to get the list of all the ProcessGroups in the DeviceMesh,please use `get_all_groups()` instead.r   é   )Úhasattrr8   r@   rT   r   r   rQ   rr   rs   r0   rƒ   rv   rº   r¨   r…   )r3   rG   rl   r0   rÞ   s        r   Ú	get_groupzDeviceMesh.get_groupÚ  sŽ  € õ ˜4Ð!3Ñ4Ô4ð QÝ"Ð#OÑPÔPÐPàŒyŒ~ Ò!Ð! hÐ&6Ý"ØL°´´ÐLÐLÐLØ`ð=ñô ð ð ŒyŒ~ Ò"Ð" xÐ'7ÝÝ-¨tÔ/DÀQÔ/GÈÈÈÔ/KÐLñô ð õ (×5Ò5°dÑ;Ô;ˆIÝ&5Ô&M×&QÒ&QØ˜4ñ'ô 'Ð#ð 'ð ¨8Ð7N×7SÒ7SÑ7UÔ7UÐ+UÐ+UØ"9¸(Ô"CÔ"TÐUVÔ"WÐXZÐYZÐXZÔ"[�ÝÕ 9¸?Ð KÑLÔLÐLõ " (­CÑ0Ô0ð"•O×8Ò8¸¸xÑHÔHÐHà!ð õ
  Ý-¨tÔ/DÀXÔ/NÈrÐPQÈrÔ/RÐSñô ð r   c                 óN   ‡ — ˆ fd„t          ‰ j        j        ¦  «        D ¦   «         S )z 
            Returns a list of ProcessGroups for all mesh dimensions.

            Returns:
                A list of :class:`ProcessGroup` object.
            c                 ó:   •— g | ]}‰                      |¦  «        ‘ŒS r   )r  )rF   Úir3   s     €r   rH   z-DeviceMesh.get_all_groups.<locals>.<listcomp>  s%   ø€ ÐEÐEÐE¨!�D—N’N 1Ñ%Ô%ÐEÐEÐEr   )rS   r@   rT   r2   s   `r   Úget_all_groupszDeviceMesh.get_all_groups  s,   ø€ ð FÐEÐEÐE­u°T´Y´^Ñ/DÔ/DÐEÑEÔEÐEr   rq   Úgroupc                ó"  — t          | t          ¦  «        rØt          | ¦  «        }t          |t          j        ¦  «        r|                     ¦   «         |k    s"|�Bt          |t          j        ¦  «        s(||k    r"t          dt          |¦  «        › d|› �¦  «        ‚t          j        |dt          j	        ¬¦  «        }t          |||d¬¦  «        }t          | ¦  «        || j        fg|_        |S t          | ¦  «        }t          |¦  «        dk    rt          d	¦  «        ‚|€t          d
¦  «        ‚t          |t          j        ¦  «        r3|                     ¦   «                              t          j	        d¬¦  «        n t          j        |dt          j	        ¬¦  «        }|j        t          |¦  «        k    r5t          d|                     ¦   «         › dt          |¦  «        › d�¦  «        ‚t          |||d¬¦  «        }d„ |D ¦   «         |_        |S )aM  
            Constructs a :class:`DeviceMesh` with ``device_type`` from an
            existing :class:`ProcessGroup`.

            The constructed device mesh has number of dimensions equal to the
            number of groups passed. If more than one group is passed, then the
            ``mesh`` argument is required.
            NzInvalid mesh z for ProcessGroup with ranks r³   r¶   FrK   r   z.Expects at least one ProcessGroup to be passedz0Must pass mesh if passing multiple ProcessGroups)rµ   r·   zEExpects mesh with ndim equal to number of ProcessGroups but got mesh z and z ProcessGroupsc                 óV   — g | ]&}t          |¦  «        t          |¦  «        |j        f‘Œ'S r   )r   r    rÝ   )rF   r  s     r   rH   z)DeviceMesh.from_group.<locals>.<listcomp>J  sH   € ð ,ð ,ð ,ð õ	 # 5Ñ)Ô)Ý+¨EÑ2Ô2ØÔ$ðð,ð ,ð ,r   )rº   r&   r    r°   r»   rÁ   r½   r¨   rÀ   r©   r   r   rÝ   rQ   rR   r7   r¾   r¿   rT   )r  rX   r@   rL   Úgroup_ranksr:   Úgroupss          r   Ú
from_groupzDeviceMesh.from_group  s;  € õ  ˜%¥Ñ.Ô.ð #Ý5°eÑ<Ô<�å˜t¥U¤\Ñ2Ô2ð	Ø7;·{²{±}´}ÈÒ7SÐ7SàÐ$Ý& t­U¬\Ñ:Ô:ð %à Ò+Ð+å$Ø]­¨D©	¬	Ð]Ð]ÐP[Ð]Ð]ñô ð õ ”| K¸ÅUÄYÐOÑOÔO�Ý(ØØØ#1Ø"'ð	ñ ô �õ $ EÑ*Ô*¨K¸Ô9IÐJð0�Ô,ð #Ð"Ý˜%‘[”[ˆFÝ�6‰{Œ{˜aÒÐÝ Ð!QÑRÔRÐRØˆ|Ý Ð!SÑTÔTÐTõ ˜d¥E¤LÑ1Ô1ðG�—’‘”× Ò ¥u¤y¸Ð Ñ?Ô?Ð?å”\ $¨u½E¼IÐFÑFÔFð ð
 Œy�C ™KœKÒ'Ð'Ý ðLØ ŸKšK™MœMðLð LÝ03°F±´ðLð Lð Lñô ð õ %Ø˜T°.ÐPUðñ ô ˆKð,ð ,ð $ð,ñ ,ô ,ˆKÔ(ð Ðr   c                 ól   — |€| j                              ¦   «         n| j                              |¦  «        S r   )r@   rÍ   rA   )r3   rG   s     r   rA   zDeviceMesh.sizeT  s,   € Ø(0Ð(8�4”9—?’?Ñ$Ô$Ð$¸d¼i¿nºnÈXÑ>VÔ>VÐVr   c                 ó   — | j         j        S r   )r@   rT   r2   s    r   rT   zDeviceMesh.ndimW  s   € à”9”>Ð!r   c                 ó4   — t          | j        j        ¦  «        S r   )ry   r@   rò   r2   s    r   rò   zDeviceMesh.shape[  s   € å˜œœÑ)Ô)Ð)r   c                 ó   — t          ¦   «         S )z:
            Returns the current global rank.
            )r!   r2   s    r   r!   zDeviceMesh.get_rank_  s   € õ ‘:”:Ðr   c                 ó  — | j         dk    r |€t          d| j        j         › d�d¦  «        ‚|€d}t          |                      |¦  «        ¦  «        }t          |t          ¦  «        s
J d¦   «         ‚t          t          |¦  «        ¦  «        S )a{  
            Returns the local rank of the given mesh_dim of the DeviceMesh.

            Args:
                mesh_dim (str/int, optional): it can be the name of the mesh dimension or the index
                of the mesh dimension. Default is None.

            Returns:
                An integer denotes the local rank.

            The following program runs on each process/rank in an SPMD manner. In this example, we have 2
            hosts with 4 GPUs each.
            Calling mesh_2d.get_local_rank(mesh_dim=0) on rank 0, 1, 2, 3 would return 0.
            Calling mesh_2d.get_local_rank(mesh_dim=0) on rank 4, 5, 6, 7 would return 1.
            Calling mesh_2d.get_local_rank(mesh_dim=1) on rank 0, 4 would return 0.
            Calling mesh_2d.get_local_rank(mesh_dim=1) on rank 1, 5 would return 1.
            Calling mesh_2d.get_local_rank(mesh_dim=1) on rank 2, 6 would return 2.
            Calling mesh_2d.get_local_rank(mesh_dim=1) on rank 3, 7 would return 3.

            Example::
                >>> # xdoctest: +SKIP("no rank")
                >>> from torch.distributed.device_mesh import DeviceMesh
                >>>
                >>> # Initialize device mesh as (2, 4) to represent the topology
                >>> # of cross-host(dim 0), and within-host (dim 1).
                >>> mesh = DeviceMesh(device_type="cuda", mesh=[[0, 1, 2, 3],[4, 5, 6, 7]])
            rE   Nrþ   rÿ   r   r   z1We expect ProcessGroup before calling `get_rank`!)rT   r8   r@   r   r  rº   r&   r!   )r3   rG   Úmesh_dim_groups      r   Úget_local_rankzDeviceMesh.get_local_ranke  s«   € ð8 Œy˜1Š}ˆ} Ð!1Ý"ØL°´´ÐLÐLÐLØ`ñô ð ð Ð!Ø�å% d§n¢n°XÑ&>Ô&>Ñ?Ô?ˆNÝØ¥ñô ð Cð CàBñCô Cð õ �H ^Ñ4Ô4Ñ5Ô5Ð5r   c                 ó"   — | j         r| j         ndS )z©
            Return the relative indices of this rank relative to all
            dimensions of the mesh. If this rank is not part of the mesh, return None.
            N)rÉ   r2   s    r   Úget_coordinatezDeviceMesh.get_coordinate�  s   € ð
 /3Ô.EÐO�4Ô*Ð*È4ÐOr   r_   c                 ód   — | j         st          d¦  «        ‚t                               | |¦  «        S )a\  
            Returns a 1D DeviceMesh by flattening the current DeviceMesh.

            If no mesh_dim_name is provided, the default is a string concatentaing the mesh_dim_names of the
            given submesh with each mesh_dim_name separated by "_". For example, if we have a 3D mesh
            DeviceMesh([[[0, 1], [2, 3]], [[4, 5], [6, 7]]], mesh_dim_names=("dp", "cp", "tp")), calling
            mesh_3d["dp", "cp"]._flatten() will create a 1D submesh DeviceMesh([0, 1, 2, 3], mesh_dim_names=("dp_cp",))
            on rank 0, 1, 2, 3 and a 1D submesh DeviceMesh([4, 5, 6, 7], mesh_dim_names=("dp_cp",)) on rank 4, 5, 6, 7.

            After the flattened dimension is created, to access the flattened dimesnion in mesh_3d, one can use the
            existing slicing method to obtain the flattened mesh through calling mesh_3d["dp_cp"].
            z3Cannot flatten a DeviceMesh without mesh_dim_names!)rL   r8   rr   r�   )r3   r_   s     r   Ú_flattenzDeviceMesh._flatten–  s<   € ð Ô&ð Ý"ØIñô ð õ #×6Ò6°t¸]ÑKÔKÐKr   r§   r¦   r   )%r   r   r   Ú__doc__r¨   Ú__annotations__r°   r»   r   r	   r   Úboolr4   rÄ   rÅ   rä   rê   rî   ró   Úobjectr÷   rü   r©   r&   r  r   r  rª   r  rA   ÚpropertyrT   rò   r!   r  r  r  r   r   r   r   r   {  sÌ  € € € € € € ð%	ð %	ðN ÐÐÑØŒlÐÐÑØ   s¨C x¤Ô1Ð1Ð1Ñ1ð 9=Ø"&ð(	ð (	ð (	àð(	ð ˜œ kÐ1Ô2ð(	ð
 % U¨3°¨8¤_Ô5ð(	ð  ð(	ð ð(	ð (	ð (	ð (	ðT	(ð 	(ð 	(ð:r	4ð r	4ð r	4ðh	ð 	ð 	ð 	ð	-ð 	-ð 	-ð 	-ð	$˜cð 	$ð 	$ð 	$ð 	$ð	ð 	ð 	ð	 ð 	¨4ð 	ð 	ð 	ð 	ðG	Ø"'¨¨U°3¸°8¬_Ð(<Ô"=ðG	àðG	ð G	ð G	ð G	ðR,	ð ,	 h¨u°S¸#°X¬Ô&?ð ,	È<ð ,	ð ,	ð ,	ð ,	ð\	F D¨Ô$6ð 	Fð 	Fð 	Fð 	Fð 
ð @Dð@	ð
 9=ð@	ð @	ð @	Ø˜ t¨LÔ'9Ð9Ô:ð@	àð@	ð ˜5 ¤¨{Ð!:Ô;Ô<ð@	ð
 % U¨3°¨8¤_Ô5ð@	ð ð@	ð @	ð @	ñ 
Œð@	ðD	Wð 	W ¨#¤ð 	W¸#ð 	Wð 	Wð 	Wð 	Wð 
ð	"˜#ð 	"ð 	"ð 	"ñ 
Œð	"ð 
ð	*˜5  c œ?ð 	*ð 	*ð 	*ñ 
Œð	*ð	˜cð 	ð 	ð 	ð 	ð(	6ð (	6¨8°E¸#¸s¸(´OÔ+Dð (	6ÐPSð (	6ð (	6ð (	6ð (	6ðT	P H¨T°#¬YÔ$7ð 	Pð 	Pð 	Pð 	Pð	Lð 	L¨(°3¬-ð 	LÀ<ð 	Lð 	Lð 	Lð 	Lð 	Lð 	Lr   rq   Ú
mesh_shape.rL   r+   c          	      ó†  — |�‘t          t          |¦  «        ¦  «        t          |¦  «        k    rt          dd|› �¦  «        ‚t          |¦  «        t          |¦  «        k    r1t          ddt          |¦  «        › dt          |¦  «        › d�¦  «        ‚| r(|                      ¦   «         st          d| › d	�d
¦  «        ‚t	          j        d¦  «        5  t	          j        t          j        |¦  «        t          j	        ¬¦  «         
                    |¦  «        }ddd¦  «         n# 1 swxY w Y   t          | ||¬¦  «        }|S )a¤  
        Initializes a `DeviceMesh` based on `device_type`, `mesh_shape`, and `mesh_dim_names` parameters.

        This creates a DeviceMesh with an n-dimensional array layout, where `n` is the length of `mesh_shape`.
        If `mesh_dim_names` is provided, each dimension is labeled as `mesh_dim_names[i]`.

        .. note::
            `init_device_mesh` follows SPMD programming model, meaning the same PyTorch Python program
            runs on all processes/ranks in the cluster. Ensure `mesh_shape` (the dimensions of the nD array
            describing device layout) is identical across all ranks. Inconsistent `mesh_shape` may lead to hanging.

        .. note::
            If no process group is found, init_device_mesh will initialize distributed process group/groups
            required for distributed communications behind the scene.

        Args:
            device_type (str): The device type of the mesh. Currently supports: "cpu", "cuda/cuda-like".
                Passing in a device type with a GPU index, such as "cuda:0", is not allowed.
            mesh_shape (Tuple[int]): A tuple defining the dimensions of the multi-dimensional array
                describing the layout of devices.
            mesh_dim_names (Tuple[str], optional): A tuple of mesh dimension names to assign to each dimension
                of the multi-dimensional array describing the layout of devices. Its length must match the length
                of `mesh_shape`. Each string in `mesh_dim_names` must be unique.

        Returns:
            DeviceMesh: A :class:`DeviceMesh` object representing the device layout.

        Example::
            >>> # xdoctest: +SKIP("no rank")
            >>> from torch.distributed.device_mesh import init_device_mesh
            >>>
            >>> mesh_1d = init_device_mesh("cuda", mesh_shape=(8,))
            >>> mesh_2d = init_device_mesh("cuda", mesh_shape=(2, 8), mesh_dim_names=("dp", "tp"))

        Nz"Each mesh_dim_name must be unique.z/Found repeated mesh_dim_name in mesh_dim_names z6mesh_shape and mesh_dim_names should have same length!zFound len(mesh_dim_names): z and len(mesh_shape):rš   z0Device type with index is not supported but got rp   zUIf you maintained a 'torch.device' object, it's recommended to pass in 'device.type'.r³   r´   )rX   r@   rL   )r7   Úsetr8   Úisalphar°   r·   Úarangerw   rx   r©   Úviewr   )rX   r  rL   r@   r:   s        r   r   r   ª  s±  € ðR Ð%Ý•3�~Ñ&Ô&Ñ'Ô'­3¨~Ñ+>Ô+>Ò>Ð>Ý"Ø8ØVÀnÐVÐVñô ð õ
 �:‰Œ¥# nÑ"5Ô"5Ò5Ð5Ý"ØLØnµ#°nÑ2EÔ2EÐnÐnÕ\_Ð`jÑ\kÔ\kÐnÐnÐnñô ð ð ð 	˜{×2Ò2Ñ4Ô4ð 	ÝØRÀ;ÐRÐRÐRØgñô ð õ Œ\˜%Ñ Ô ð 	Yð 	YÝ”<¥¤	¨*Ñ 5Ô 5½U¼YÐGÑGÔG×LÒLÈZÑXÔXˆDð	Yð 	Yð 	Yñ 	Yô 	Yð 	Yð 	Yð 	Yð 	Yð 	Yð 	Yøøøð 	Yð 	Yð 	Yð 	Yå Ø#ØØ)ð
ñ 
ô 
ˆð Ðs   ÃAD$Ä$D(Ä+D()r­   )8Úloggingrw   rÆ   Ú	functoolsr   Ú	itertoolsr   Útypingr   r   r   r	   r
   r   r°   Útorch.distributedr   Útorch.utils._typing_utilsr   Ú__all__Úsysr   r   Úmodulesr   r   Útorch._C._distributed_c10dr   r«   Ú"torch.distributed.distributed_c10dr   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   Ú	getLoggerr   ÚloggerÚnumpy.typingr(   ÚImportErrorÚwarningÚlocalr*   rr   r  r¨   rŠ   r©   r   r   r   ú<module>r5     sd  ðð €€€€Ø €€€Ø Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø DÐ DÐ DÐ DÐ DÐ DÐ DÐ DÐ DÐ DÐ DÐ DÐ DÐ DÐ DÐ Dà €€€Ø *Ð *Ð *Ð *Ð *Ð *Ø .Ð .Ð .Ð .Ð .Ð .ð ˜|Ð
,€ð €|�~„~ð _Ø€J€J€Jðð ð ð ð ñ ô ð ðð ð ð ?N€C„KÐ/Ô0Ô;ð 0ð „KØ'ôäÐÐð BÐAÐAÐAÐAÐAðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ˆWÔ˜xÑ(Ô(€Fð ð ð	Ø.Ð.Ð.Ð.Ð.Ð.Ð.øØð 	ð 	ð 	Ø�NŠNØUñô ð ð ð ð	øøøð
l!ð l!ð l!ð l!ð l!�9”?ñ l!ô l!ð l!ð\	 !) ¡
¤
€O�XÐ*Ð*Ñ*ð1ð 1¨ð 1ð 1ð 1ð 1ðmLð mLð mLð mLð mLñ mLô mLð mLðf 59ð	Gð Gð GØðGà˜#˜s˜(”OðGð !  s¨C x¤Ô1ð	Gð
 
ðGð Gð Gð Gð Gð Gs   Â7B> Â>CÃC