Ë
    f^(h}  ã                   óà   — d dl Z d dlmZ d dlmZmZ d dlZd dlmZ d dlm	Z	m
Z
 d dlmZ d dlmZ dgZ	 	 dd dœd	ej                   d
ee
   deeeeeef   f      dee   dej                   f
d„Zy)é    N©Úfnmatch)ÚOptionalÚUnion)Ú_mesh_resourcesÚ
DeviceMesh)Ú_validate_tp_mesh_dim)ÚParallelStyleÚparallelize_module©Úsrc_data_rankÚmoduleÚdevice_meshÚparallelize_planr   Úreturnc                óÈ  ‡— t         j                  j                  d«       |xs t        j                  «       }t        |«       |€t        j                  d«       | S t        |t        «      r||_
        |j                  | |«      S t        |t        «      r¶|j                  «       D ]¡  \  }}|j                  d«      }t        |«      dk(  rt!        d«      ‚|sŒ3|j#                  d«      Št%        ˆfd„| j'                  «       «      }|D ]9  \  }}	|r#dj)                  |«      }
t+        |	||
|i|¬«       Œ+t+        |	|||¬«       Œ; |rŒoŒ£ | S t-        dt/        |«      › d	�«      ‚)
aÐ
  
    Apply Tensor Parallelism in PyTorch by parallelizing modules or sub-modules based on a user-specified plan.

    We parallelize module or sub_modules based on a parallelize_plan. The parallelize_plan contains
    :class:`ParallelStyle`, which indicates how user wants the module or sub_module
    to be parallelized.

    User can also specify different parallel style per module fully qualified name (FQN).

    Note that ``parallelize_module`` only accepts a 1-D :class:`DeviceMesh`, if you have a 2-D or N-D :class:`DeviceMesh`,
    slice the DeviceMesh to a 1-D sub DeviceMesh first then pass to this API(i.e. ``device_mesh["tp"]``)

    Args:
        module (:class:`nn.Module`):
            Module to be parallelized.
        device_mesh (:class:`DeviceMesh`, optional):
            Object which describes the mesh topology of devices for the DTensor.
            If not specified, the call must be under a DeviceMesh context.
        parallelize_plan (Union[:class:`ParallelStyle`, Dict[str, :class:`ParallelStyle`]], optional):
            The plan used to parallelize the module. It can be either a
            :class:`ParallelStyle` object which contains how we prepare
            input/output for Tensor Parallelism or it can be a dict of module
            FQN and its corresponding :class:`ParallelStyle` object. If not
            specified, the call will do nothing at the moment.
    Keyword args:
        src_data_rank (int, optional): the rank of the source data for the logical/global tensor, it is used by
            :meth:`distribute_tensor` to scatter/broadcast the shards/replicas to other ranks. By default,
            we use ``group_rank=0`` on each DeviceMesh dimension as the source data to preserve the single-device
            semantic. If passing ``None`` explicitly, :meth:`parallelize_module` simply uses its local data instead
            of trying to preserve the single-device semantic via scatter/broadcast. Default: 0
    Return:
        A :class:`nn.Module` object parallelized.

    Example::
        >>> # xdoctest: +SKIP("distributed")
        >>> from torch.distributed.tensor.parallel import parallelize_module, ColwiseParallel
        >>> from torch.distributed.device_mesh import init_device_mesh
        >>>
        >>> # Define the module.
        >>> m = Model(...)
        >>> tp_mesh = init_device_mesh("cuda", (8,))
        >>> m = parallelize_module(m, tp_mesh, {"w1": ColwiseParallel(), "w2": RowwiseParallel()})
        >>>

    .. note:: For complex module architecture like Attention, MLP layers, we recommend composing
        different ParallelStyles together (i.e. ``ColwiseParallel`` and ``RowwiseParallel``) and pass
        as a parallelize_plan, to achieves the desired sharding computation.
    z4torch.distributed.tensor.parallel.parallelize_modulez‚No parallelize_plan is provided and auto-parallel is not supported at the moment, so this parallelize_module call will do nothing.ú.r   z9Expect module path to be non-empty, but got empty string!c                 ó"   •— t        | d   ‰«      S )Nr   r   )ÚtÚatoms    €úc/var/www/skyplay_api_hub/venv/lib/python3.12/site-packages/torch/distributed/tensor/parallel/api.pyú<lambda>z$parallelize_module.<locals>.<lambda>d   s   ø€ œg a¨¡d¨DÓ1€ ó    r   zLExpect Union[ParallelStyle, Dict[str, ParallelStyle]] for parallelize_plan, z found!)ÚtorchÚ_CÚ_log_api_usage_oncer   Úget_current_meshr	   ÚwarningsÚwarnÚ
isinstancer
   r   Ú_applyÚdictÚitemsÚsplitÚlenÚ
ValueErrorÚpopÚfilterÚnamed_childrenÚjoinr   Ú	TypeErrorÚtype)r   r   r   r   Úmodule_pathÚparallelize_styleÚpath_splitsÚmatched_childrenÚ_Ú	submoduleÚ	leaf_pathr   s              @r   r   r      s�  ø€ ôn 
‡H�H× Ñ Ð!WÔXàÒC¤×!AÑ!AÓ!C€KÜ˜+Ô&àÐÜ�‰ðNô	
ð ˆô
 Ð"¤MÔ2Ø)6ÐÔ&Ø×&Ñ& v¨{Ó;Ð;Ü	Ð$¤dÔ	+Ø.>×.DÑ.DÓ.Fò !	Ñ*ˆKÐ*Ø%×+Ñ+¨CÓ0ˆKÜ�;Ó 1Ò$Ü ØOóð ò Ø"—‘ qÓ)�Ü#)ã1Ø×)Ñ)Ó+ó$Ð ð %5ò ‘L�A�yÙ"à$'§H¡HØ'ó%˜	ô +Ø%Ø'Ø&Ð(9Ð:Ø*7ö	ô +Ø%Ø'Ø-Ø*7ö	ðó ð!	ðD ˆäð"Ü"&Ð'7Ó"8Ð!9¸ðBó
ð 	
r   )NN)r   r   Útypingr   r   r   Útorch.nnÚnnÚtorch.distributed.device_meshr   r   Ú(torch.distributed.tensor.parallel._utilsr	   Ú'torch.distributed.tensor.parallel.styler
   Ú__all__ÚModuler"   ÚstrÚintr   © r   r   ú<module>r?      s�   ðã Ý ß "ã Ý ß EÝ JÝ Að  Ð
 €ð
 )-ØQUðq
ð
 $%òq
Ø�I‰Iðq
à˜*Ñ%ðq
ð ˜u ]°D¸¸mÐ9KÑ4LÐ%LÑMÑNðq
ð
 ˜C‘=ðq
ð ‡Y�Yôq
r   