§
    O�’j4X ã                   óü  — U d dl Z d dlZd dlZ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 d dlmZmZmZ d dlZd dlmc m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 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/m0Z0m1Z1 d dl2m3Z3  ej4        e5¦  «        Z6da7e8dz  e9d<   da:e8e9d<   de0de;fd„Z<e j=        dSde8fd„¦   «         Z>e j=        dSde8fd„¦   «         Z? ej@        dd¬¦  «         G d„ d¦  «        ¦   «         ZA ej@        dd¬¦  «         G d„ deA¦  «        ¦   «         ZBdeAd eCe,         d!eDeEeCeE         f         ddfd"„ZFd#e'd$eGeEd%f         de'dz  fd&„ZHd#e'd$eGeEd%f         de'dz  fd'„ZI eJ¦   «         ZKeJeGeEeGeEd%f         eLf                  e9d(<   d)e'd$eGeEd%f         d*eGe,d%f         d+eGe,d%f         d,eEd-eLd.eLddfd/„ZMd0eCeA         d)e'd*eGe,d%f         d+eGe,d%f         deCeAeBz           f
d1„ZNi ZOeDeGejP        e'         e#f         d2f         e9d3<   d)e'd4e#dd2fd5„ZQdTd6„ZR G d7„ d2¦  «        ZS	 dUd8e d9e d:e8dz  deCeA         fd;„ZTe	 dUd8e d9e d:e8dz  deCeA         fd<„¦   «         ZUdddd=œd>ejV        d?e d@e dAe8d:e8dz  dBe8dejV        fdC„ZWddDœdEdFdGe dHejX        dIejX        dAe8f
dJ„ZY G dK„ dLe¦  «        ZZ G dM„ dNe¦  «        Z[ G dO„ dPej\        j]        ¦  «        Z^ G dQ„ dRej\        j]        ¦  «        Z_dS )Vé    N)Údefaultdict)ÚSequence)Úcache)ÚAnyÚcastÚ	TypedDict)Ú_are_we_tracing)Ú_MeshLayout©Úone_step_redistribute_cost)Ú_StridedShardNotDecodableErrorÚDTensorSpecÚ
ShardOrderÚShardOrderEntryÚ
TensorMeta)Úassert_no_mixed_partial_types)Ú
DeviceMesh)Ú_is_shard_likeÚ_StridedShardÚPartialÚ	PlacementÚ	ReplicateÚShard)ÚFloatLikeTypeÚIntLikeType)Úget_active_debug_modeÚ#_FORCE_MIN_COST_REDISTRIBUTION_PLANFÚ,_DISABLE_REDISTRIBUTE_TRANSFORM_OPTIMIZATIONÚcostÚreturnc                 ó¸  — t          | t          ¦  «        r| S t          | t          j        ¦  «        r| j        j        }nt          | ¦  «        S |j        }|st          |¦  «        S | j        j        j        }| 	                    |¦  «        r"t          | 
                    |¦  «        ¦  «        S t          | j        j                             |d ¬¦  «        ¦  «        S )N)Úfallback)Ú
isinstanceÚfloatÚtorchÚSymFloatÚnodeÚexprÚfree_symbolsÚ	shape_envÚvar_to_hint_overrideÚissubsetÚxreplaceÚoptimization_hint)r   r(   r)   Úhint_overridess       úTC:\Projects\DSCons\.venv\Lib\site-packages\torch\distributed\tensor\_redistribute.pyÚ_redistribute_cost_sort_keyr1   8   sÃ   € Ý�$�ÑÔð ØˆÝ�$�œÑ'Ô'ð ØŒyŒ~ˆˆå�T‰{Œ{ÐàÔ$€LØð Ý�T‰{Œ{Ðà”YÔ(Ô=€NØ×Ò˜^Ñ,Ô,ð 4Ý�T—]’] >Ñ2Ô2Ñ3Ô3Ð3å�”Ô$×6Ò6°tÀdÐ6ÑKÔKÑLÔLÐLó    TÚenabledc              #   ó8   K  — t           }| a 	 dV — |a dS # |a w xY w)uX	  
    Context manager to control the redistribution planning strategy for DTensor operations.

    This context manager allows you to choose between two algorithms for computing the
    sequence of collective operations needed to redistribute a DTensor from one placement
    to another:

    - **Graph-based**: Uses Dijkstra's algorithm to find the minimum-cost path
      through all possible placement transformations. This approach considers the global
      cost of all collective operations and finds the optimal sequence. Best for complex
      redistribution patterns where reducing communication cost and memory overhead is critical.

    - **Greedy**: Uses a heuristic approach that makes locally optimal choices
      at each step. This is faster to compute but may not produce the globally optimal
      transformation sequence. Best for simple redistribution patterns or when planning
      speed is more important than optimal communication.

    **Default Behavior (without this context manager):**

    When this context manager is NOT used, the algorithm selection follows this priority:

    1. **Non-default shard orders**
       â†’ Always use graph-based algorithm (required for correctness)

    2. **Explicit `use_graph_based_transform` parameter** to `_gen_transform_infos_non_cached`
       â†’ Use the specified algorithm (True = graph-based, False = greedy)

    3. **No explicit parameter** (default case)
       â†’ Use greedy algorithm for faster planning

    **Behavior with this context manager:**

    This context manager overrides the default selection by setting the global flag
    `_FORCE_MIN_COST_REDISTRIBUTION_PLAN`, which takes precedence over the explicit
    `use_graph_based_transform` parameter (but not over non-default shard order requirements).

    **Cache Considerations:**

    The redistribution planner caches transform info for performance via the `@cache`
    decorator on `_gen_transform_infos`. If you need to change the algorithm selection
    for the same input specs, clear the cache using `_gen_transform_infos.cache_clear()`
    to ensure the new setting takes effect and doesn't reuse cached results from a
    previous run.

    Args:
        enabled (bool): If True, forces the use of the graph-based algorithm.
                       If False, forces the use of the greedy algorithm.
                       Default: True
    N)r   )r3   Ú	old_values     r0   Ú use_min_cost_redistribution_planr6   K   s@   è è € õj 4€IØ*1Ð'ð8Øˆˆˆà.7Ð+Ð+Ð+ø¨iÐ+Ð7Ð7Ð7Ð7ó   � •Údisabledc              #   ó8   K  — t           }| a 	 dV — |a dS # |a w xY w)aÓ  
    Context manager to disable the transform optimization pass that merges
    consecutive same-type collectives into single flattened operations.

    When the optimization is disabled, ``_optimize_transform_infos`` becomes a
    no-op and returns the original list of ``_TransformInfo`` objects unchanged.
    This is useful for debugging or isolating issues related to the flattened
    collective merging logic.

    The flag can also be set directly::

        torch.distributed.tensor._redistribute._DISABLE_REDISTRIBUTE_TRANSFORM_OPTIMIZATION = True

    Args:
        disabled (bool): If True (default), disables the optimization.
                         If False, explicitly enables it (the normal default).
    N)r   )r8   r5   s     r0   Ú+disable_redistribute_transform_optimizationr:   ˆ   s@   è è € õ* =€IØ3;Ð0ðAØˆˆˆà7@Ð4Ð4Ð4ø°yÐ4Ð@Ð@Ð@Ð@r7   ©ÚfrozenÚslotsc                   ób   — e Zd ZU eed<   eeef         ed<   ee         ed<   d„ Z	de
dz  fd„ZdS )Ú_TransformInfoÚmesh_dimÚsrc_dst_placementsÚlogical_shapec                 ó€   — | j         dk     rt          ‚| j        d         | j        d         k    rt          d¦  «        ‚d S )Nr   é   zQTransformInfo should only be created if it is an op with some effect, not a no-op)r@   ÚAssertionErrorrA   ©Úselfs    r0   Ú__post_init__z_TransformInfo.__post_init__¬   sN   € ØŒ=˜1ÒÐÝ Ð ØÔ" 1Ô%¨Ô)@ÀÔ)CÒCÐCÝ Øcñô ð ð DÐCr2   r    Nc                 óB  — | j         \  }}|                     ¦   «         r|                     ¦   «         rdS |                     ¦   «         rt          |¦  «        rdS t          |¦  «        r|                     ¦   «         rdS t          |¦  «        rt          |¦  «        rdS dS )zä
        Return a key for grouping transforms by communication type.

        Returns None for local ops (no communication needed), or a string
        that identifies the collective type for potential grouping/merging.
        Ú
all_reduceÚreduce_scatterÚ
all_gatherÚ
all_to_allN)rA   Ú
is_partialÚis_replicater   )rG   ÚsrcÚdsts      r0   Ú_comm_type_keyz_TransformInfo._comm_type_key´   s´   € ð Ô*‰ˆˆSØ�>Š>ÑÔð 
	 × 0Ò 0Ñ 2Ô 2ð 
	Ø�<Ø�^Š^ÑÔð 	¥.°Ñ"5Ô"5ð 	Ø#Ð#Ý˜CÑ Ô ð 	 S×%5Ò%5Ñ%7Ô%7ð 	Ø�<Ý˜CÑ Ô ð 	¥^°CÑ%8Ô%8ð 	Ø�<ð �4r2   )Ú__name__Ú
__module__Ú__qualname__ÚintÚ__annotations__Útupler   r   r   rH   ÚstrrR   © r2   r0   r?   r?   ¥   st   € € € € € € à€M€M�MØ˜i¨Ð2Ô3Ð3Ð3Ñ3à˜KÔ(Ð(Ð(Ñ(ðð ð ð  d¡
ð ð ð ð ð ð r2   r?   c                   óT   — e Zd ZU dZeed<   eedf         ed<   dZedz  ed<   d	d„Z	dS )
Ú_FlattenedTransformInfoa4  
    Represents a flattened transform that combines multiple mesh dimensions
    into a single collective operation using a flattened DeviceMesh.

    Note: inherits the fields from _TransformInfo. Gets an __init__ with parent fields, followed by child fields,
    and runs parent validation (post_init)
    Úmesh.Úoriginal_mesh_dimsNÚ	avg_scaler    c                 ó�   — t                                | ¦  «         | j        �"| j        dk    st          d| j        › �¦  «        ‚d S d S )NrD   z"avg_scale must be > 1 if set, got )r?   rH   r_   rE   rF   s    r0   rH   z%_FlattenedTransformInfo.__post_init__Û   sX   € Ý×$Ò$ TÑ*Ô*Ð*ØŒ>Ð%Ø”> AÒ%Ð%Ý$ØI¸¼ÐIÐIñô ð ð &Ð%Ø%Ð%r2   ©r    N)
rS   rT   rU   Ú__doc__r   rW   rX   rV   r_   rH   rZ   r2   r0   r\   r\   É   sl   € € € € € € ðð ð ÐÐÑà˜c 3˜hœÐ'Ð'Ñ'ð !€Iˆs�T‰zÐ Ð Ñ ðð ð ð ð ð r2   r\   Útransform_infoÚcurrent_placementsÚshard_order_dictc                 ó¾  — | j         \  }}t          | t          ¦  «        r| j        }n| j        f}t          |t
          t          z  ¦  «        r¹|j        }t          ¦   «         }|D ]c}t          ||         ¦  «        dk    rt          d|› d| › d|› d|› �¦  «        ‚|                     ||                              ¦   «         ¦  «         Œdt          |¦  «        |k    s+t          dt          |¦  «        › d|› d| › d|› d|› �
¦  «        ‚t          |t
          t          z  ¦  «        r0|j        }	|	|vrg ||	<   |D ]}
||	                              |
¦  «         Œ|D ]}
|||
<   ŒdS )	zw
    Update current_placements and shard_order_dict in-place to reflect the
    effect of a single transform step.
    r   z?Invalid shard_order update. No entries left to pop for src_dim z. transform_info=z, current_placements=z, shard_order=z^Mismatch between expected and removed mesh dims during shard_order update. Expected to remove z, but removed N)rA   r#   r\   r^   r@   r   r   ÚdimÚsetÚlenÚ
ValueErrorÚaddÚpopÚappend)rc   rd   re   Úsrc_placementÚdst_placementÚ	mesh_dimsÚsrc_dimÚremoved_dimÚ_Údst_dimr@   s              r0   Ú"_update_shard_order_and_placementsru   ä   sþ  € ð $2Ô#DÑ €M�=å�.Õ"9Ñ:Ô:ð /Ø"Ô5ˆ	ˆ	à#Ô,Ð.ˆ	å�-¥­Ñ!6Ñ7Ô7ð ØÔ#ˆÝ‘e”eˆØð 	=ð 	=ˆAÝÐ# GÔ,Ñ-Ô-°Ò2Ð2Ý ð6Øð6ð 6Ø1?ð6ð 6à*<ð6ð 6ð $4ð6ð 6ñô ð ð �OŠOÐ,¨WÔ5×9Ò9Ñ;Ô;Ñ<Ô<Ð<Ð<å�9‰~Œ~ Ò,Ð,Ýð2å�y‘>”>ð2ð 2à1<ð2ð 2ð #1ð2ð 2ð '9ð	2ð 2ð
  0ð2ð 2ñô ð õ �-¥­Ñ!6Ñ7Ô7ð 7ØÔ#ˆØÐ*Ð*Ð*Ø(*Ð˜WÑ%Ø!ð 	7ð 	7ˆHØ˜WÔ%×,Ò,¨XÑ6Ô6Ð6Ð6àð 5ð 5ˆØ'4Ð˜8Ñ$Ð$ð5ð 5r2   r]   rp   .c                 ó@  ‡— |                       ¦   «         }| j        Š‰€dS t          ˆfd„|D ¦   «         ¦  «        }|                      |¦  «        }t	          |                     ¦   «         g¦  «        }|j                             ¦   «         D ]}|j        |k    r|c S ŒdS )zé
    Query for an explicitly created flattened mesh using layout comparison.

    Searches root_mesh._flatten_mapping for a mesh whose layout matches
    the expected flattened layout for the given dims. Pure Python layout math.
    Nc              3   ó(   •K  — | ]}‰|         V — Œd S ©NrZ   )Ú.0ÚiÚmesh_dim_namess     €r0   ú	<genexpr>z5_get_flattened_mesh_by_layout_impl.<locals>.<genexpr>%  s(   øè è € Ð;Ð;¨A�n QÔ'Ð;Ð;Ð;Ð;Ð;Ð;r2   )	Ú_get_root_meshr{   rX   Ú_get_slice_mesh_layoutr
   ÚcollapseÚ_flatten_mappingÚvaluesÚ_layout)r]   rp   Ú	root_meshÚ	dim_namesÚsliced_layoutÚexpected_layoutÚflattened_meshr{   s          @r0   Ú"_get_flattened_mesh_by_layout_implrˆ     sÄ   ø€ ð ×#Ò#Ñ%Ô%€IØÔ(€NàÐØˆtõ Ð;Ð;Ð;Ð;°Ð;Ñ;Ô;Ñ;Ô;€Ið ×/Ò/°	Ñ:Ô:€MÝ! =×#9Ò#9Ñ#;Ô#;Ð"<Ñ=Ô=€Oð $Ô4×;Ò;Ñ=Ô=ð "ð "ˆØÔ! _Ò4Ð4Ø!Ð!Ð!Ð!ð 5ð ˆ4r2   c                 óþ   — t          ¦   «         r`t          j        j        j        rJt          | |¦  «        €dS ddlm} t          j        j         	                    | t          |¦  «        ¦  «        S t          | |¦  «        S )aB  
    Query for an explicitly created flattened mesh using layout comparison.

    When tracing with compile_on_one_rank, delegates to a custom op so the
    flattened mesh appears as a call_function node derived from mesh (a graph
    input) rather than as a get_attr constant holding an unpicklable
    ProcessGroup.
    Nr   )Údevice_mesh)r	   r%   ÚdistributedÚconfigÚcompile_on_one_rankrˆ   Útorch.distributed._opsrŠ   ÚopsÚ_get_flattened_submeshÚlist)r]   rp   rs   s      r0   Ú_get_flattened_mesh_by_layoutr’   4  s~   € õ ÑÔð S�UÔ.Ô5ÔIð Sõ .¨d°IÑ>Ô>ÐFØ�4Ø;Ð;Ð;Ð;Ð;Ð;åŒyÔ$×;Ò;¸DÅ$ÀyÁ/Ä/ÑRÔRÐRå-¨d°IÑ>Ô>Ð>r2   Ú_warned_flatten_issuesrŠ   Úsrc_placementsÚdst_placementsÚnum_opsÚ	comm_typeÚreasonc                 óÚ  ‡— t          | ¦  «        ||f}|t          v rdS t                               |¦  «         | j        Š‰�.ˆfd„|D ¦   «         }d                     d„ |D ¦   «         ¦  «        }	n%dd                     d„ |D ¦   «         ¦  «        › d| › �}	d}
|d	k    rd
|	› d�}n(|dk    rd}n|dk    rd|› d�}nt          d|› �¦  «        ‚t                               |
|||||¦  «         dS )a-  
    Warn once per (mesh, dims, reason) about inability to flatten operations.

    Args:
        device_mesh: The device mesh being used
        mesh_dims: Tuple of mesh dimensions that could not be flattened
        src_placements: Source placements for the redistribution
        dst_placements: Target placements for the redistribution
        num_ops: Number of sequential operations that will be performed
        comm_type: Type of collective operation (e.g., "reduce_scatter")
        reason: Either "no_flattened_mesh" or "uneven_tensor_shape"
    Nc                 ó    •— g | ]
}‰|         ‘ŒS rZ   rZ   )ry   Údr{   s     €r0   ú
<listcomp>z;_warn_flatten_optimization_not_possible.<locals>.<listcomp>k  s   ø€ Ð:Ð:Ð:¨1�^ AÔ&Ð:Ð:Ð:r2   z, c              3   ó"   K  — | ]
}d |› d �V — ŒdS )ú"NrZ   )ry   Únames     r0   r|   z:_warn_flatten_optimization_not_possible.<locals>.<genexpr>l  s*   è è € Ð?Ð?¨T˜[ ˜[˜[˜[Ð?Ð?Ð?Ð?Ð?Ð?r2   zdims c              3   ó4   K  — | ]}t          |¦  «        V — Œd S rx   )rY   )ry   r›   s     r0   r|   z:_warn_flatten_optimization_not_possible.<locals>.<genexpr>n  s(   è è € Ð$?Ð$?°¥S¨¡V¤VÐ$?Ð$?Ð$?Ð$?Ð$?Ð$?r2   z of a%  While redistributing from %s to %s, %d sequential %s operations will be performed. This is suboptimal: multiple collective operations have higher latency (separate kernel launches and synchronization points) and may give inconsistent results between ranks due to different reduction orders. %sÚno_flattened_meshz&To optimize, flatten mesh dimensions [z0] so DTensor can use a single operation instead.Úuneven_tensor_shape)zÀ Unfortunately, because the tensor dimension is not evenly divisible by the product of the mesh dim sizes that would need to be flattened for the optimization to work, it can not be optimized.Únon_ascending_mesh_dimsz0it is not possible to merge non-ascending order z operations.zUnexpected reason: )Úhashr“   rk   r{   ÚjoinrE   ÚloggerÚwarning)rŠ   rp   r”   r•   r–   r—   r˜   Ú	cache_keyr„   Údims_strÚcommon_warningÚ
reason_msgr{   s               @r0   Ú'_warn_flatten_optimization_not_possibler¬   O  s`  ø€ õ* �kÑ"Ô" I¨vÐ6€IØÕ*Ð*Ð*ØˆÝ×Ò˜yÑ)Ô)Ð)à Ô/€NØÐ!Ø:Ð:Ð:Ð:°	Ð:Ñ:Ô:ˆ	Ø—9’9Ð?Ð?°YÐ?Ñ?Ô?Ñ?Ô?ˆˆàR˜4Ÿ9š9Ð$?Ð$?°YÐ$?Ñ$?Ô$?Ñ?Ô?ÐRÐRÀ[ÐRÐRˆð	`ð ð Ð$Ò$Ð$Øx¸hÐxÐxÐxˆ
ˆ
Ø	Ð(Ò	(Ð	(ð
ˆ
ˆ
ð 
Ð,Ò	,Ð	,àV¸yÐVÐVÐVð 	ˆ
õ Ð;°6Ð;Ð;Ñ<Ô<Ð<å
‡N‚NØ˜¨¸ÀÈJñô ð ð ð r2   Útransform_infosc           	      ó:  ‡‡‡— t          | ¦  «        dk     r| S t          r| S t          h d£¦  «        Šdt          dz  dt          fˆfd„}dt
          t          t          f         dt
          t          t          f         dt          fd	„Šd
t          t                   dt
          t          dz  t          dz  f         fˆˆfd„}g }d}|t          | ¦  «        k     �r¨| |         }| 
                    ¦   «         }	 ||	¦  «        s|                     |¦  «         |dz  }ŒV|j        }
|g}|dz   }|t          | ¦  «        k     r§ || |          
                    ¦   «         ¦  «        r„ ‰| |         j        |
¦  «        rm|                     | |         ¦  «         |dz  }|t          | ¦  «        k     r: || |          
                    ¦   «         ¦  «        r ‰| |         j        |
¦  «        °m ||¦  «        \  }}|�|                     |¦  «         na|                     |¦  «         |dv rHt          t          d„ |D ¦   «         ¦  «        ¦  «        }t          ‰|||t          |¦  «        |	|¦  «         |}|t          | ¦  «        k     �°¨t                                d| |¦  «         |S )a¼  
    Optimize transform infos by merging consecutive same-type collectives into
    a single flattened operation when a matching flattened DeviceMesh exists.

    Merging requirements:
    - Operations must be consecutive in the transform list (no reordering).
      Notably, redistributing from P, P, P -> R, S, R is not optimized here and cannot be optimized due to
      optimization needing to fuse non-contiguous reductions, leaving this pattern vulnerable to numerics issues and
      suboptimal perf
    - Operations must have the same comm type (e.g., all allgather or all reduce_scatter)
    - Operations must have identical src_dst_placements (e.g., can't merge
      Partial->Shard(0) with Partial->Shard(1))
    - A flattened mesh covering the relevant dimensions must exist
    - For reduce_scatter, tensor dim must be evenly divisible by flattened mesh size

    For nested sharding, the merged operation uses the logical_shape from the
    outermost mesh dimension (smallest mesh_dim index) which represents the
    global tensor shape needed for correct padding/unpadding.

    TODO:
    - all_to_all operations are excluded from merging, but it may be possible to merge them in some cases.

    é   >   rL   rJ   rK   ÚkeyNr    c                 ó   •— | ‰v S )z:Check if a comm type key represents a mergeable operation.rZ   )r°   ÚMERGEABLE_COMM_TYPESs    €r0   Úis_mergeablez/_optimize_transform_infos.<locals>.is_mergeable±  s   ø€ àÐ*Ð*Ð*r2   Úp1Úp2c                 ó
  — | |k    rdS | \  }}|\  }}||k    rdS |                      ¦   «         r|                      ¦   «         sdS t          t          |¦  «        }t          t          |¦  «        }ddh}|j        |v o|j        |v S )zß
        Check if two src_dst_placements can be merged.

        Allows merging of Partial("sum") and Partial("avg") since they can be
        combined: perform sum reduction, then scale by avg mesh dims afterward.
        TFÚsumÚavg)rN   r   r   Ú	reduce_op)	r´   rµ   Úsrc1Údst1Úsrc2Údst2Úpartial1Úpartial2Úmergeable_reduce_opss	            r0   Úare_placements_mergeablez;_optimize_transform_infos.<locals>.are_placements_mergeableµ  sª   € ð �Š8ˆ8Ø�4à‰
ˆˆdØ‰
ˆˆdð �4Š<ˆ<Ø�5ð —’Ñ!Ô!ð 	 d§o¢oÑ&7Ô&7ð 	Ø�5õ � Ñ&Ô&ˆÝ� Ñ&Ô&ˆØ % u˜~ÐàÔÐ"6Ð6ð ;ØÔ"Ð&:Ð:ð	
r2   Úinfosc                 ó"  •‡‡— t          | ¦  «        dk     rdS | d         j        Š| d                              ¦   «         }t          ˆˆfd„| D ¦   «         ¦  «        st	          d¦  «        ‚t          d„ | D ¦   «         ¦  «        }t          t          |¦  «        ¦  «        }|dk    r	||k    rdS n|d	k    r||d
d
d…         k    rdS t          ‰|¦  «        }|€dS ‰\  }}|d	k    r/t          t          |¦  «        j
        Št          | ˆfd„¬¦  «        }nŽ|dk    rgt          t          |¦  «        j
        Št          | ˆfd„¬¦  «        }|j        ‰         }t          j        ˆfd„| D ¦   «         ¦  «        }	||	z  dk    rdS n!|dk    r	| d         }nt          d|› �¦  «        ‚d
}
|}|                     ¦   «         r7t          j        ˆfd„| D ¦   «         ¦  «        }|dk    r|}
t#          d¦  «        }||f}t%          d||j        |||
¬¦  «        d
fS )aû  
        Try to create a flattened transform from 2+ same-type transforms.

        Returns (result, failure_reason) where:
        - result is the FlattenedTransformInfo if successful, None otherwise
        - failure_reason is None if successful, or one of:
          - "too_few_transforms": Less than 2 transforms provided
          - "no_flattened_mesh": No flattened mesh exists for the required dimensions
          - "uneven_tensor_shape": For reduce_scatter, tensor dim not evenly divisible
        r¯   )NÚtoo_few_transformsr   c              3   ó:   •K  — | ]} ‰|j         ‰¦  «        V — Œd S rx   )rA   )ry   ÚinforÁ   Úfirst_placementss     €€r0   r|   zJ_optimize_transform_infos.<locals>.try_create_flattened.<locals>.<genexpr>é  sH   øè è € ð 
ð 
àð %Ð$ TÔ%<Ð>NÑOÔOð
ð 
ð 
ð 
ð 
ð 
r2   z5All transforms must have mergeable src_dst_placementsc              3   ó$   K  — | ]}|j         V — Œd S rx   ©r@   )ry   rÆ   s     r0   r|   zJ_optimize_transform_infos.<locals>.try_create_flattened.<locals>.<genexpr>ð  s$   è è € Ð:Ð:¨D˜$œ-Ð:Ð:Ð:Ð:Ð:Ð:r2   rK   )Nr£   rL   Néÿÿÿÿ)Nr¡   c                 ó   •— | j         ‰         S rx   ©rB   ©ÚxÚaffected_dims    €r0   ú<lambda>zI_optimize_transform_infos.<locals>.try_create_flattened.<locals>.<lambda>  ó   ø€ °a´oÀlÔ6S€ r2   )r°   c                 ó   •— | j         ‰         S rx   rÌ   rÍ   s    €r0   rÐ   zI_optimize_transform_infos.<locals>.try_create_flattened.<locals>.<lambda>  rÑ   r2   c              3   óL   •K  — | ]}‰                      |j        ¦  «        V — Œd S rx   )Úsizer@   ©ry   rÆ   rŠ   s     €r0   r|   zJ_optimize_transform_infos.<locals>.try_create_flattened.<locals>.<genexpr>  sD   øè è € ð 2ð 2Ø48�× Ò  ¤Ñ/Ô/ð2ð 2ð 2ð 2ð 2ð 2r2   )Nr¢   rJ   z0Unsupported comm type for try_create_flattened: c              3   óž   •K  — | ]G}t          t          |j        d          ¦  «        j        dk    ¯+‰                     |j        ¦  «        V — ŒHdS )r   r¸   N)r   r   rA   r¹   rÔ   r@   rÕ   s     €r0   r|   zJ_optimize_transform_infos.<locals>.try_create_flattened.<locals>.<genexpr>)  s_   øè è € ð ð àÝ� Ô!8¸Ô!;Ñ<Ô<ÔFÈ%ÒOÐOð × Ò  ¤Ñ/Ô/àOÐOÐOÐOðð r2   rD   r·   )r@   rA   rB   r]   r^   r_   )ri   rA   rR   ÚallrE   rX   Úsortedr’   r   r   rg   ÚmaxrB   ÚmathÚprodÚNotImplementedErrorrN   r   r\   )rÂ   r—   rp   Úsorted_mesh_dimsr‡   rP   rQ   Úoutermost_infoÚtensor_dim_sizeÚeffective_shard_mesh_sizer_   Ú
merged_srcÚscaleÚmerged_placementsrÏ   rÇ   rÁ   rŠ   s                 @@€€r0   Útry_create_flattenedz7_optimize_transform_infos.<locals>.try_create_flattenedÕ  sÿ  øøø€ õ ˆu‰:Œ:˜Š>ˆ>Ø-Ð-ð ! œ8Ô6ÐØ˜!”H×+Ò+Ñ-Ô-ˆ	Ýð 
ð 
ð 
ð 
ð 
àð
ñ 
ô 
ñ 
ô 
ð 	õ !ØGñô ð õ Ð:Ð:°EÐ:Ñ:Ô:Ñ:Ô:ˆ	Ý ¥¨	Ñ!2Ô!2Ñ3Ô3Ðð Ð(Ò(Ð(ð Ð,Ò,Ð,Ø6Ð6ð -à˜,Ò&Ð&ð Ð,¨T¨T¨r¨TÔ2Ò2Ð2Ø6Ð6å6°{ÐDTÑUÔUˆØÐ!Ø,Ð,ð $‰ˆˆSØ˜Ò$Ð$å¥ sÑ+Ô+Ô/ˆLÝ  Ð,SÐ,SÐ,SÐ,SÐTÑTÔTˆNˆNØÐ*Ò*Ð*Ý¥ sÑ+Ô+Ô/ˆLÝ  Ð,SÐ,SÐ,SÐ,SÐTÑTÔTˆNØ,Ô:¸<ÔHˆOÝ(,¬	ð 2ð 2ð 2ð 2Ø<Að2ñ 2ô 2ñ )ô )Ð%ð Ð!:Ñ:¸aÒ?Ð?Ø2Ð2ð @à˜,Ò&Ð&à" 1œXˆNˆNå%ØNÀ9ÐNÐNñô ð ð
 ˆ	Øˆ
Ø�>Š>ÑÔð 	,Ý”Ið ð ð ð à!ðñ ô ñ ô ˆEð
 �qŠyˆyØ!�	Ý$ U™^œ^�
à'¨Ð-Ðõ $ØØ#4Ø,Ô:Ø#Ø#3Ø#ðñ ô ð ð

ð 
	
r2   r   rD   )r¡   r¢   r£   c              3   ó$   K  — | ]}|j         V — Œd S rx   rÉ   )ry   Úgs     r0   r|   z,_optimize_transform_infos.<locals>.<genexpr>k  s$   è è € Ð(CÐ(C¸¨¬Ð(CÐ(CÐ(CÐ(CÐ(CÐ(Cr2   z5_optimize_transform_infos original: %s, optimized: %s)ri   r   Ú	frozensetrY   ÚboolrX   r   r‘   r?   r\   rR   rm   rA   ÚextendrØ   r¬   r¦   Údebug)r­   rŠ   r”   r•   r³   rä   Úresultrz   rÆ   Úcurrent_keyrd   ÚgroupÚjÚ	flattenedÚfailure_reasonrp   r²   rÁ   s    `              @@r0   Ú_optimize_transform_infosrñ   ‹  sZ  øøø€ õ: ˆ?ÑÔ˜aÒÐØÐå3ð ØÐõ %Ð%SÐ%SÐ%SÑTÔTÐð+�# ™*ð +­ð +ð +ð +ð +ð +ð +ð
Ý•)�YÐ&Ô'ð
Ý-2µ9½iÐ3GÔ-Hð
å	ð
ð 
ð 
ð 
ð@i
Ý•NÔ#ði
å	Õ&¨Ñ-­s°T©zÐ9Ô	:ði
ð i
ð i
ð i
ð i
ð i
ð i
ðX >@€FØ	€Aà
�c�/Ñ"Ô"Ò
"Ñ
"Ø˜qÔ!ˆØ×)Ò)Ñ+Ô+ˆð ˆ|˜KÑ(Ô(ð 	Ø�MŠM˜$ÑÔÐØ�‰FˆAØð
 "Ô4ÐØ'+ fˆØ�‰Eˆà•�OÑ$Ô$Ò$Ð$Ø�˜_¨QÔ/×>Ò>Ñ@Ô@ÑAÔAð %à(Ð(Ø Ô"Ô5Ð7Iñô ð %ð �LŠL˜¨Ô+Ñ,Ô,Ð,Ø�‰FˆAð •�OÑ$Ô$Ò$Ð$Ø�˜_¨QÔ/×>Ò>Ñ@Ô@ÑAÔAð %à(Ð(Ø Ô"Ô5Ð7Iñô ð %ð %9Ð$8¸Ñ$?Ô$?Ñ!ˆ	�>ØÐ Ø�MŠM˜)Ñ$Ô$Ð$Ð$ð �MŠM˜%Ñ Ô Ð àð "ð ð õ
 "¥&Ð(CÐ(C¸UÐ(CÑ(CÔ(CÑ"CÔ"CÑDÔD�	Ý7ØØØ"Ø"Ý˜‘J”JØØ"ñô ð ð ˆðe �c�/Ñ"Ô"Ò
"Ñ
"õf ‡L‚LØ?ÀÐRXñô ð ð €Mr2   ÚDTensorRedistributePlannerÚ_planner_cacheÚdtensor_metac                 óÊ   — t          ¦   «         rt          | |¦  «        S t          j        | ¦  «        |f}|t          vrt          | |¦  «        }|t          |<   t          |         S )aù  
    Factory function to get or create a DTensorRedistributePlanner instance.
    This function provides transparent caching of planner instances based on
    device mesh and dtensor meta. Multiple calls with the same parameters
    will return the same cached instance for better performance.
    Args:
        device_mesh: The device mesh for the planner
        dtensor_meta: TensorMeta of the DTensor to redistribute
    Returns:
        A DTensorRedistributePlanner instance (potentially cached)
    )r	   rò   ÚweakrefÚrefró   )rŠ   rô   r¨   Úplanners       r0   Úget_redistribute_plannerrù   …  sf   € õ ÑÔð EÝ)¨+°|ÑDÔDÐDå”˜[Ñ)Ô)¨<Ð8€IØ�Ð&Ð&Ý,¨[¸,ÑGÔGˆØ$+��yÑ!å˜)Ô$Ð$r2   c                  ó8   — t                                ¦   «          dS )z8Clear the cache of DTensorRedistributePlanner instances.N)ró   ÚclearrZ   r2   r0   Ú clear_redistribute_planner_cacherü   Ÿ  s   € å×ÒÑÔÐÐÐr2   c                   ó.  — e Zd ZdZ ej        dd¬¦  «         G d„ d¦  «        ¦   «         Zd„ Zede	e
ee
         f         defd	„¦   «         Zedede	e
ee
         f         fd
„¦   «         Ze	 	 d&dedee         deedf         dedz  dedefd„¦   «         Zdededdfd„Z	 	 d'd„Zdeedf         dede	def         fd„Zdededed         fd„Zddde
d ee
df         dee         fd!„Zd"ed#ed ee
df         dee         fd$„Z d"ed#edee         fd%„Z!dS )(rò   a  
    This class is used to plan the collective calls to transform the local shard
    of the DTensor from its current spec to the target spec.
    Suppose there are N tensor dimensions and M mesh dimensions, the total
    possible state size will be (N+2)*M*M!.
    Note: Use get_redistribute_planner() factory function instead of direct
    instantiation for automatic caching.
    Tr;   c                   ó¦   — e Zd ZU eedf         ed<   eed<    ej        dddd¬¦  «        Z	e
dz  ed<   d„ Zd	„ Zd
„ Zde
fd„Zde
fd„Zdedefd„ZdS )ú$DTensorRedistributePlanner.DistState.Ú
placementsÚtensor_dim_to_mesh_dimNF)ÚdefaultÚinitÚreprÚcompareÚ_hashc                 ó@   — t          j        | j        | j        ¦  «        S rx   )r   Úformat_shard_order_strr   r  rF   s    r0   Ú__str__z,DTensorRedistributePlanner.DistState.__str__¶  s"   € ÝÔ5Ø”ØÔ+ñô ð r2   c                 ó*   — |                       ¦   «         S rx   )r	  rF   s    r0   Ú__repr__z-DTensorRedistributePlanner.DistState.__repr__¼  s   € Ø—<’<‘>”>Ð!r2   c                 ób   — t                                | d|                      ¦   «         ¦  «         d S )Nr  )ÚobjectÚ__setattr__Ú_compute_hashrF   s    r0   rH   z2DTensorRedistributePlanner.DistState.__post_init__¿  s9   € å×ÒØØØ×"Ò"Ñ$Ô$ñô ð ð ð r2   r    c                 óF   — | j         �| j         n|                      ¦   «         S rx   )r  r  rF   s    r0   Ú__hash__z-DTensorRedistributePlanner.DistState.__hash__Ç  s!   € Ø!%¤Ð!7�4”:�:¸T×=OÒ=OÑ=QÔ=QÐQr2   c                 ó8   — t          | j        | j        f¦  «        S rx   )r¤   r   r  rF   s    r0   r  z2DTensorRedistributePlanner.DistState._compute_hashÊ  s$   € Ýà”OØÔ/ðñô ð r2   Úotherc                 óš   — t          |t          j        ¦  «        sdS | j        |j        k    rdS | j        | j        f|j        |j        fk    S ©NF)r#   rò   Ú	DistStater  r   r  )rG   r  s     r0   Ú__eq__z+DTensorRedistributePlanner.DistState.__eq__Ò  s^   € Ý˜eÕ%?Ô%IÑJÔJð Ø�uØŒz˜Uœ[Ò(Ð(Ø�uà”ØÔ+ðð Ô ØÔ,ðòð r2   )rS   rT   rU   rX   r   rW   r   ÚdataclassesÚfieldr  rV   r	  r  rH   r  r  r  rè   r  rZ   r2   r0   r  rÿ   ®  sø   € € € € € € à˜) S˜.Ô)Ð)Ð)Ñ)Ø *Ð*Ð*Ñ*Ø-˜KÔ-Ø˜u¨5¸%ð
ñ 
ô 
ˆˆs�T‰zð 	
ð 	
ñ 	
ð	ð 	ð 	ð	"ð 	"ð 	"ð	ð 	ð 	ð	R˜cð 	Rð 	Rð 	Rð 	Rð	 3ð 	ð 	ð 	ð 	ð	 ð 	¨4ð 	ð 	ð 	ð 	ð 	ð 	r2   r  c                 óx   ‡ — t          |t          t          z  ¦  «        rt          ˆ fd„|D ¦   «         ¦  «        S |S )z<Convert a nested list structure to a nested tuple structure.c              3   óB   •K  — | ]}‰                      |¦  «        V — Œd S rx   )Ú	_to_tuple)ry   ÚitemrG   s     €r0   r|   z7DTensorRedistributePlanner._to_tuple.<locals>.<genexpr>â  s/   øè è € Ð<Ð<°$˜Ÿš¨Ñ-Ô-Ð<Ð<Ð<Ð<Ð<Ð<r2   )r#   r‘   rX   )rG   rÎ   s   ` r0   r  z$DTensorRedistributePlanner._to_tupleß  sA   ø€ å�a�¥™Ñ&Ô&ð 	=ÝÐ<Ð<Ð<Ð<¸!Ð<Ñ<Ô<Ñ<Ô<Ð<Øˆr2   rÎ   r    c                 ór   — t          d„ t          |                      ¦   «         ¦  «        D ¦   «         ¦  «        S )zConvert dict to ShardOrderc              3   ó\   K  — | ]'\  }}|¯t          |t          |¦  «        ¬ ¦  «        V — Œ(dS ))Ú
tensor_dimrp   N)r   rX   )ry   r°   Úvalues      r0   r|   zADTensorRedistributePlanner._dict_to_ShardOrder.<locals>.<genexpr>è  sS   è è € ð 
ð 
á��UØð
Ý sµe¸E±l´lÐCÑCÔCð
ð 
ð 
ð 
ð 
ð 
r2   )rX   rØ   Úitems)rÎ   s    r0   Ú_dict_to_ShardOrderz.DTensorRedistributePlanner._dict_to_ShardOrderå  sB   € õ ð 
ð 
å$ Q§W¢W¡Y¤YÑ/Ô/ð
ñ 
ô 
ñ 
ô 
ð 	
r2   c                 óp   — t          t          ¦  «        }| D ]}t          |j        ¦  «        ||j        <   Œ|S )z1Convert ShardOrder to dict with tensor dim as key)r   r‘   rp   r   )rÎ   Útensor_mesh_dim_dictÚentrys      r0   Ú_ShardOrder_to_dictz.DTensorRedistributePlanner._ShardOrder_to_dictî  sD   € õ  +­4Ñ0Ô0ÐØð 	Kð 	KˆEÝ59¸%¼/Ñ5JÔ5JÐ  Ô!1Ñ2Ð2Ø#Ð#r2   NFr]   r­   rn   .Úsrc_shard_orderÚ use_strided_shard_as_shard_orderc                 óÆ  — t          |¦  «        | j        k    r't          dt          |¦  «        › d| j        › �¦  «        ‚|rt          j        || d¬¦  «        \  }}|€t          j        |¦  «        }t          |¦  «        }t                               |¦  «        }t           	                    t          |¦  «        |¦  «        }|g}g }	|D ]’}
t          |
t          ¦  «        }t          |
||¦  «         t           	                    t          |¦  «        t                               |¦  «        ¦  «        }|                     |¦  «         |	                     |¦  «         Œ“t!          |d         ¦  «        g}t#          |	¦  «        D ]K\  }}|rdnd}|                     |¦  «         |                     t!          ||d	z            ¦  «        ¦  «         ŒLd
                     |¦  «        S )aÌ  
        Generate a string representation of the sequence of state transitions
        (placements and shard orders) as described by the given transform_info.

        Args:
            mesh: The DeviceMesh used for the redistribution.
            transform_infos: A sequence of _TransformInfo objects describing each
                transformation step.
            src_placement: The initial tuple of Placement objects.
            src_shard_order: (Optional) The initial ShardOrder representing
                the mapping of tensor dimensions to mesh dimensions. If None,
                the default shard order is computed from src_placement and mesh.
            use_strided_shard_as_shard_order: If True, normalize _StridedShard
                placements into regular Shard placements with an explicit
                shard_order before stringifying.

        Returns:
            A string showing the sequence of DistState transitions, separated by '->'.
        zdimensions mismatch z vs T©r)  Nr   z-->z->rD   Ú )ri   ÚndimrE   r   Ú&_normalize_placements_into_shard_orderÚcompute_default_shard_orderr‘   rò   r'  r  rX   r#   r\   ru   r#  rm   rY   Ú	enumerater¥   )r]   r­   rn   r(  r)  Úcur_placementre   Ú	cur_stateÚ
state_listÚis_flattened_listrc   Úis_flattenedÚ	new_stateÚtrace_partsrz   Ú	separators                   r0   Ústringify_transform_infosz4DTensorRedistributePlanner.stringify_transform_infosö  s  € õ6 ˆ}ÑÔ ¤Ò*Ð*Ý ØJ¥s¨=Ñ'9Ô'9ÐJÐJ¸t¼yÐJÐJñô ð ð ,ð 	åÔBØ! 4È$ðñ ô ñ +ˆM˜?ð
 Ð"Ý)ÔEÀmÑTÔTˆOÝ˜]Ñ+Ô+ˆÝ5×IÒIØñ
ô 
Ðõ /×8Ò8Ý�-Ñ Ô  /ñ
ô 
ˆ	ð ð
ˆ
ð )+Ðà-ð 	3ð 	3ˆNÝ% nÕ6MÑNÔNˆLå.Ø Ð/?ñô ð õ 3×<Ò<Ý�mÑ$Ô$Ý*×>Ò>Ð?OÑPÔPñô ˆIð ×Ò˜iÑ(Ô(Ð(Ø×$Ò$ \Ñ2Ô2Ð2Ð2õ ˜: aœ=Ñ)Ô)Ð*ˆÝ(Ð):Ñ;Ô;ð 	7ð 	7‰OˆAˆ|Ø!-Ð7˜˜°4ˆIØ×Ò˜yÑ)Ô)Ð)Ø×Ò�s :¨a°!©eÔ#4Ñ5Ô5Ñ6Ô6Ð6Ð6Ø�wŠw�{Ñ#Ô#Ð#r2   rŠ   rô   c                 ó  — || _         |                     ¦   «         st          ‚|€t          ‚|| _        t	          |j        ¦  «        | _        t          ¦   «         | _        t          ¦   «         | _	        |  
                    ¦   «          dS )zÅ
        Initialize DTensorRedistributePlanner.

        Args:
            device_mesh: The device mesh for this planner
            dtensor_meta: TensorMeta of the DTensor to redistribute
        N)rŠ   Ú_is_current_rank_part_of_meshrE   rô   ri   ÚshapeÚtensor_dimensionrh   Ú"strided_shard_placements_in_targetÚpartial_reduce_ops_in_targetÚsetup_cost_callbacks)rG   rŠ   rô   s      r0   Ú__init__z#DTensorRedistributePlanner.__init__@  s}   € ð 'ˆÔØ×8Ò8Ñ:Ô:ð 	!Ý Ð ØÐÝ Ð Ø(ˆÔÝ # LÔ$6Ñ 7Ô 7ˆÔÝFIÁeÄeˆÔ/Ý69±e´eˆÔ)Ø×!Ò!Ñ#Ô#Ð#Ð#Ð#r2   c                 óT   ‡ ‡— dt           j        dt          fˆ fd„Šˆfd„}|‰ _        dS )zÍ
        Set up the cost function for different collective operations.
        Uses communication time estimation based on actual tensor sizes and
        mesh topology for accurate cost modeling.
        Ústater    c                 óT   •— t          ‰j        | j        ‰j        | j        d¬¦  «        S )NF)r]   r   Útensor_metaÚshard_orderr)  )r   rŠ   r   rô   r  )rC  rG   s    €r0   Ústate_to_speczFDTensorRedistributePlanner.setup_cost_callbacks.<locals>.state_to_spec`  s7   ø€ õ ØÔ%Ø Ô+Ø Ô-Ø!Ô8Ø16ðñ ô ð r2   c                 óH   •— t           ‰| ¦  «         ‰|¦  «        ¦  «        S rx   r   )Ú	src_stateÚ	dst_staterG  s     €r0   Úcost_functionzFDTensorRedistributePlanner.setup_cost_callbacks.<locals>.cost_functionk  s.   ø€ Ý-Ø�˜iÑ(Ô(¨-¨-¸	Ñ*BÔ*Bñô ð r2   N)rò   r  r   rK  )rG   rK  rG  s   ` @r0   r@  z/DTensorRedistributePlanner.setup_cost_callbacksW  s^   øø€ ð		Ý-Ô7ð		åð		ð 		ð 		ð 		ð 		ð 		ð	ð 	ð 	ð 	ð 	ð
 +ˆÔÐÐr2   r   Útensor_mesh_dim_tuplerÿ   c                 óÌ  — i }t                                |¦  «        }|                      |                      |¦  «        |¦  «        }|D �]7}|j        }||         d         }t          ||         t          ¦  «        sŒ4t          | j        ¦  «        D ]î}	||	k    rŒ	||          	                    ¦   «         }
||	          
                    |
¦  «         t          |¦  «        }t          |	¦  «        ||
<   |                      |                      |¦  «        t                                |¦  «        ¦  «        }|                      ||¦  «        ||<   ||          
                    |
¦  «         ||	          	                    ¦   «          Œï�Œ9|D ]â}|j        }||         d         }t          ||         t          ¦  «        sŒ3||          	                    ¦   «         }
t          |¦  «        }t          ¦   «         ||
<   |                      |                      |¦  «        t                                |¦  «        ¦  «        }||          
                    |
¦  «         |                      ||¦  «        ||<   Œãt          |¦  «        D ]}\  }}t          |t           ¦  «        sŒt          |¦  «        }t          ¦   «         ||<   |                      |                      |¦  «        |¦  «        }|                      ||¦  «        ||<   Œ~t          |¦  «        D ]â\  }}t          |t          ¦  «        sŒt          | j        ¦  «        D ]²}	t          |¦  «        }t          |	¦  «        ||<   ||	          
                    |¦  «         |                      |                      |¦  «        t                                |¦  «        ¦  «        }|                      ||¦  «        ||<   ||	          	                    ¦   «          Œ³Œãt          |¦  «        D ]â\  }}t          |t           ¦  «        sŒt          | j        ¦  «        D ]²}	t          |¦  «        }t          |	¦  «        ||<   ||	          
                    |¦  «         |                      |                      |¦  «        t                                |¦  «        ¦  «        }|                      ||¦  «        ||<   ||	          	                    ¦   «          Œ³Œãt          |¦  «        D ]°\  }}t          |t          ¦  «        sŒ| j        D ]�}t          |¦  «        }t!          |¦  «        ||<   d„ |D ¦   «         }t%          |¦  «        dk    r	|ddhk    rŒK|                      |                      |¦  «        |¦  «        }|                      ||¦  «        ||<   ŒŽŒ±|D ]â}|j        }||         d         }t          ||         t&          ¦  «        sŒ3||          	                    ¦   «         }
t          |¦  «        }t          ¦   «         ||
<   |                      |                      |¦  «        t                                |¦  «        ¦  «        }||          
                    |
¦  «         |                      ||¦  «        ||<   Œã| j        s|S t          |¦  «        D ]Ï\  }}t          |t          ¦  «        sŒ| j        D ]¬}|j        }	t          |¦  «        }|||<   ||	          
                    |¦  «         |                      |                      |¦  «        t                                |¦  «        ¦  «        }|                      ||¦  «        ||<   ||	          	                    ¦   «          Œ­ŒÐ|S )NrÊ   c                 óF   — h | ]}t          |t          ¦  «        ¯|j        ’ŒS rZ   )r#   r   r¹   ©ry   Úps     r0   ú	<setcomp>z<DTensorRedistributePlanner.get_next_state.<locals>.<setcomp>@  s9   € ð &ð &ð &Ø$%½:ÀaÍÑ;QÔ;Qð&Ø”Kð&ð &ð &r2   rD   r·   r¸   )rò   r'  r  r  r   r#   r   Úranger=  rl   rm   r‘   r#  rK  r   r0  r   r?  ri   r   r>  rg   )rG   r   rL  Úall_next_stater%  Úcur_dist_stater&  Úsrc_tensor_dimÚsrc_mesh_dimÚdst_tensor_dimÚmove_mesh_dimÚnew_placementsÚ
dist_stateÚ	placementr@   r¹   Úpartial_reduce_opsÚstrided_shard_objs                     r0   Úget_next_statez)DTensorRedistributePlanner.get_next_stater  s  € ðH MOˆå9×MÒMØ!ñ 
ô  
Ðð ŸšØ�NŠN˜:Ñ&Ô&Ø!ñ
ô 
ˆð +ð 	;ñ 	;ˆEØ"Ô-ˆNØ/°Ô?ÀÔCˆLÝ˜j¨Ô6½Ñ>Ô>ð àÝ"'¨Ô(=Ñ">Ô">ð ;ð ;�Ø! ^Ò3Ð3Øð !5°^Ô D× HÒ HÑ JÔ J�Ø$ ^Ô4×;Ò;¸MÑJÔJÐJÝ!% jÑ!1Ô!1�Ý05°nÑ0EÔ0E�˜}Ñ-Ø!Ÿ^š^Ø—N’N >Ñ2Ô2Ý.×BÒBØ,ñô ñô �
ð .2×-?Ò-?Ø"Øñ.ô .�˜zÑ*ð
 % ^Ô4×;Ò;¸MÑJÔJÐJØ$ ^Ô4×8Ò8Ñ:Ô:Ð:Ð:ñ+;ð6 +ð 	ð 	ˆEØ"Ô-ˆNØ/°Ô?ÀÔCˆLÝ˜j¨Ô6½Ñ>Ô>ð àØ0°Ô@×DÒDÑFÔFˆMÝ! *Ñ-Ô-ˆNÝ,5©K¬KˆN˜=Ñ)ØŸšØ—’˜~Ñ.Ô.Ý*×>Ò>Ð?SÑTÔTñô ˆJð ! Ô0×7Ò7¸ÑFÔFÐFØ)-×);Ò);ØØñ*ô *ˆN˜:Ñ&Ð&õ (1°Ñ'<Ô'<ð 	ð 	Ñ#ˆL˜)Ý˜i­Ñ1Ô1ð ØÝ! *Ñ-Ô-ˆNÝ+4©;¬;ˆN˜<Ñ(ØŸšØ—’˜~Ñ.Ô.Ð0Eñô ˆJð *.×);Ò);ØØñ*ô *ˆN˜:Ñ&Ð&õ $-¨ZÑ#8Ô#8ð 	;ð 	;ÑˆH�iÝ˜i­Ñ3Ô3ð ØÝ"'¨Ô(=Ñ">Ô">ð ;ð ;�å!% jÑ!1Ô!1�Ý+0°Ñ+@Ô+@�˜xÑ(Ø$ ^Ô4×;Ò;¸HÑEÔEÐEØ!Ÿ^š^Ø—N’N >Ñ2Ô2Ý.×BÒBØ,ñô ñô �
ð .2×-?Ò-?Ø"Øñ.ô .�˜zÑ*ð % ^Ô4×8Ò8Ñ:Ô:Ð:Ð:ð;õ& $-¨ZÑ#8Ô#8ð 	;ð 	;ÑˆH�iÝ˜i­Ñ1Ô1ð ØÝ"'¨Ô(=Ñ">Ô">ð ;ð ;�å!% jÑ!1Ô!1�Ý+0°Ñ+@Ô+@�˜xÑ(Ø$ ^Ô4×;Ò;¸HÑEÔEÐEØ!Ÿ^š^Ø—N’N >Ñ2Ô2Ý.×BÒBØ,ñô ñô �
ð .2×-?Ò-?Ø"Øñ.ô .�˜zÑ*ð % ^Ô4×8Ò8Ñ:Ô:Ð:Ð:ð;õ* $-¨ZÑ#8Ô#8ð 	ð 	ÑˆH�iÝ˜i­Ñ3Ô3ð ØØ!Ô>ð ð �	Ý!% jÑ!1Ô!1�Ý+2°9Ñ+=Ô+=�˜xÑ(ð&ð &Ø)7ð&ñ &ô &Ð"õ Ð)Ñ*Ô*¨QÒ.Ð.Ð3EÈ%ÐQVÈÒ3WÐ3WØà!Ÿ^š^Ø—N’N >Ñ2Ô2Ð4Iñô �
ð .2×-?Ò-?Ø"Øñ.ô .�˜zÑ*Ð*ðð4 +ð 	ð 	ˆEØ"Ô-ˆNØ/°Ô?ÀÔCˆLÝ˜j¨Ô6½ÑFÔFð ØØ0°Ô@×DÒDÑFÔFˆMÝ! *Ñ-Ô-ˆNÝ,5©K¬KˆN˜=Ñ)ØŸšØ—’˜~Ñ.Ô.Ý*×>Ò>Ð?SÑTÔTñô ˆJð ! Ô0×7Ò7¸ÑFÔFÐFØ)-×);Ò);ØØñ*ô *ˆN˜:Ñ&Ð&ð Ô6ð 	"Ø!Ð!õ $-¨ZÑ#8Ô#8ð 	;ð 	;ÑˆH�iÝ˜i­Ñ3Ô3ð ØØ%)Ô%Lð ;ð ;Ð!Ø!2Ô!6�å!% jÑ!1Ô!1�Ø+<�˜xÑ(Ø$ ^Ô4×;Ò;¸HÑEÔEÐEØ!Ÿ^š^Ø—N’N >Ñ2Ô2Ý.×BÒBØ,ñô ñô �
ð .2×-?Ò-?Ø"Øñ.ô .�˜zÑ*ð % ^Ô4×8Ò8Ñ:Ô:Ð:Ð:ð!;ð$ Ðr2   rI  rJ  c           	      óú  — ddl }d}d|d||gfg}t          ¦   «         }|rÈ|                     |¦  «        \  }}}}	}
|	|k    r|
S |	|v rŒ*|                     |	¦  «         |                      |	j        |	j        ¦  «        }|                     ¦   «         D ]T\  }}||vrKt          t          |¦  «        |z   }|
|gz   }|dz  }| 
                    |t          |¦  «        ||||f¦  «         ŒU|°Èt          d|› d|› �¦  «        ‚)aB  
        Find the min cost path from src_state to dst_state using Dijkstra's
        algorithm.

        Args:
            src_state: The source state
            dst_state: The destination state

        Returns:
            A list of states representing the min cost path from src_state to
            dst_state
        r   Ng        rD   zNo path found from src_state z to dst_state )Úheapqrh   Úheappoprk   r^  r   r  r"  r   r   Úheappushr1   rE   )rG   rI  rJ  r`  ÚcounterÚpqÚvisitedrs   r   Úcurrent_stateÚpathÚnext_statesÚ
next_stateÚtransition_costÚnew_costÚnew_paths                   r0   Úfind_min_cost_pathz-DTensorRedistributePlanner.find_min_cost_pathŒ  sh  € ð 	ˆˆˆð ˆð �7˜C ¨Y¨KÐ8Ð9ð 	õ ‘%”%ˆØð 	Ø.3¯mªm¸BÑ.?Ô.?Ñ+ˆAˆq�$˜ tØ 	Ò)Ð)Ø�Ø Ð'Ð'ØØ�KŠK˜Ñ&Ô&Ð&à×-Ò-ØÔ(¨-Ô*Nñô ˆKð 0;×/@Ò/@Ñ/BÔ/Bð ð Ñ+�
˜OØ WÐ,Ð,Ý#¥C¨™œ°Ñ@�HØ# z lÑ2�HØ˜q‘L�GØ—N’NØå7¸ÑAÔAØ#Ø$Ø&Ø$ðñ	ô 	ð 	øð! ð 	õ4 ØP¨IÐPÐPÀYÐPÐPñ
ô 
ð 	
r2   r@   Úfull_tensor_shapec           	      óˆ  — t          |¦  «        }|j        D �])}|j        }|j        }t	          |¦  «        dk    rt
          ‚|D ]û}||k    rŒ	|j        |         }	t          |	t          ¦  «        rR|	 	                    ||         | j
                             |¬¦  «        | j
                             |¦  «        ¦  «        \  }
}nyt          |	t          ¦  «        rR|	 	                    ||         | j
                             |¬¦  «        | j
                             |¦  «        ¦  «        \  }
}nt          d|	› �¦  «        ‚|
||<   Œü�Œ+|S )Nr   rÉ   zUnsupported placement type: )r‘   r  r   rp   ri   rE   r   r#   r   Úlocal_shard_size_and_offsetrŠ   rÔ   Ú_sym_get_coordinater   rj   )rG   rI  r@   rn  Únew_logical_shaper&  r   rp   Úmdimr[  Únew_sizers   s               r0   Úget_logical_shapez,DTensorRedistributePlanner.get_logical_shapeÊ  sm  € õ 04Ð4EÑ/FÔ/FÐØÔ5ð 	9ñ 	9ˆEØÔ)ˆJØœˆIÝ�9‰~Œ~ Ò"Ð"Ý$Ð$Ø!ð 9ð 9�Ø˜8Ò#Ð#ØØ%Ô0°Ô6�	Ý˜i­Ñ/Ô/ð QØ"+×"GÒ"GØ)¨*Ô5ØÔ(×-Ò-°tÐ-Ñ<Ô<ØÔ(×<Ò<¸TÑBÔBñ#ô #‘K�H˜a˜aõ
   	­=Ñ9Ô9ð QØ"+×"GÒ"GØ)¨*Ô5ØÔ(×-Ò-°tÐ-Ñ<Ô<ØÔ(×<Ò<¸TÑBÔBñ#ô #‘K�H˜a˜aõ %Ð%OÀIÐ%OÐ%OÑPÔPÐPØ08Ð! *Ñ-Ð-ñ%9ð& !Ð r2   Úsrc_specÚdst_specc           	      ó–  — dt           dt          t          t          df         t          f         fd„} ||¦  «        \  }} ||¦  «        \  }}|D ]1}	t	          |	t
          ¦  «        r| j                             |	¦  «         Œ2t          j	        ||¦  «        D ]6}	t	          |	t          ¦  «        r| j                             |	j        ¦  «         Œ7|                      ||¦  «        }
|                      ||¦  «        }g }|                      |
|¦  «        }t          j        |¦  «        D ]¢\  }}|j        |j        k    r�d}t#          t%          |j        |j        ¦  «        ¦  «        D ]c\  }\  }}||k    rU|dk    rt'          d¦  «        ‚|}|                      |||¦  «        }|                     t-          |||f|¬¦  «        ¦  «         ŒdŒ£|S )NÚspecr    .c                 ó®   — | j         r(t          j        | j        | j        d¬¦  «        \  }}||fS | j        €t          d| › �¦  «        ‚| j        | j        fS )NTr+  zMissing shard_order field in )r)  r   r.  r   r]   rF  rj   )ry  rY  rF  s      r0   Ú_try_normalize_specz\DTensorRedistributePlanner.generate_graph_based_transform_infos.<locals>._try_normalize_specô  sw   € ð Ô4ð 9åÔFØœØœ	Ø9=ðñ ô ñ ,� ð & {Ð2Ð2àÔ#Ð+Ý$Ð%KÀTÐ%KÐ%KÑLÔLÐLØ”¨Ô(8Ð8Ð8r2   rÊ   z@Multiple mesh_dims are different between cur_state and nxt_state©r@   rA   rB   )r   rX   r   r   r#   r   r>  rk   Ú	itertoolsÚchainr   r?  r¹   r  rm  Úpairwiser   r0  ÚziprE   ru  rm   r?   )rG   rv  rw  rn  r{  r”   r(  r•   Údst_shard_orderr[  rI  rJ  r­   Ú
state_pathr2  Ú	nxt_stateÚupdate_mesh_dimr@   r1  Únxt_placementrB   s                        r0   Ú$generate_graph_based_transform_infosz?DTensorRedistributePlanner.generate_graph_based_transform_infosë  s2  € ð	9Ýð	9å•5� C˜Ô(­*Ð4Ô5ð	9ð 	9ð 	9ð 	9ð" +>Ð*=¸hÑ*GÔ*GÑ'ˆ˜Ø*=Ð*=¸hÑ*GÔ*GÑ'ˆ˜ð
 (ð 	Gð 	GˆIÝ˜)¥]Ñ3Ô3ð GØÔ7×;Ò;¸IÑFÔFÐFøõ
 #œ¨¸ÑHÔHð 	Kð 	KˆIÝ˜)¥WÑ-Ô-ð KØÔ1×5Ò5°iÔ6IÑJÔJÐJøà—N’N >°?ÑCÔCˆ	Ø—N’N >°?ÑCÔCˆ	Ø02ˆØ×,Ò,¨Y¸	ÑBÔBˆ
Ý$-Ô$6°zÑ$BÔ$Bð 	ð 	Ñ ˆI�yàÔ# yÔ';Ò;Ð;Ø"$�Ý@IÝ˜	Ô,¨iÔ.BÑCÔCñAô Að ð Ñ<�HÑ<˜}¨mð %¨Ò5Ð5Ø*¨bÒ0Ð0Ý"0Ø bñ#ô #ð ð +3˜Ø(,×(>Ò(>Ø% xÐ1Bñ)ô )˜ð (×.Ò.Ý*Ø)8Ø4AÀ=Ð3QØ.;ðñ ô ñô ð øøð Ðr2   c           	      óV  — t          |j        ¦  «        }|g}g }| j        j        dk    r[|j        d         |j        d         k    r=|                     t          d|j        d         |j        d         f|¬¦  «        ¦  «         |S t          |j        ¦  «        D ]Ñ\  }}||         }t          |t          ¦  «        rš|| j        j        dz
  k     r†| j         
                    |¬¦  «        }	|                     ||j                 |	| j                             |¦  «        ¦  «        \  }
}t          |¦  «        }|
||j        <   |                     |¦  «         Œ¼|                     |¦  «         ŒÒt          |j        ¦  «        }t          |j        ¦  «        }|j        dk    �r,t          t!          t#          |¦  «        ¦  «        ¦  «        D �]}||         }||         }t          |t          ¦  «        r¡|j        }g g }}t          t%          ||¦  «        ¦  «        D ]d\  }\  }}||k    r nU|                     |¦  «        r|                     |¦  «         |                     |¦  «        r|                     |¦  «         Œe||k    rt)          ¦   «         }||k    r2|                     t          |||f||         ¬¦  «        ¦  «         |||<   �Œt          t%          ||¦  «        ¦  «        D ]@\  }\  }}||k    r2|                     t          |||f||         ¬¦  «        ¦  «         |||<   ŒA|S )a¸  
        Generate the transform infos from the source placements to the target placements.

        To transform from source to target placement it might have multiple steps, i.e. it
        might decompose Si -> Sj into Si -> R -> Sj.
        This would detect if there're mis-aligned/nested shardings between src/dst placements.
        E.g. Suppose the redistribution to perform is (Shard(0), Shard(0)) -> (Replicate(), Shard(0)),
        in this case Shard(0) -> Shard(0) for mesh dimension 1 actually needs resharding, because in
        the former is a nested-sharding of a tensor already sharded dimension 0, whereas
        the latter is the first sharding on tensor dimension 0.
        rD   r   r|  rÉ   )r‘   r<  rŠ   r-  r   rm   r?   r0  r#   r   rÔ   Ú_local_shard_size_and_offsetrg   rq  Ú
num_shardsÚreversedrR  ri   r€  Úis_shardr   )rG   rv  rw  Úinitial_logical_shapeÚmesh_dims_to_logical_shaper­   rz   rP   Úcurrent_logical_shapeÚmesh_dim_sizeÚlocal_shard_sizers   rr  rd   Útarget_placementsr@   ÚcurrentÚtargetÚ	shard_dimÚcurrent_mesh_shardingÚtarget_mesh_shardingÚsrP  s                          r0   Úgenerate_greedy_transform_infosz:DTensorRedistributePlanner.generate_greedy_transform_infos4  sÄ  € õ$ !% X¤^Ñ 4Ô 4ÐØ&;Ð%<Ð"Ø02ˆØÔÔ  AÒ%Ð%ð Ô" 1Ô%¨Ô)<¸QÔ)?Ò?Ð?Ø×&Ò&Ý"Ø!"à$Ô/°Ô2Ø$Ô/°Ô2ð,ð '<ðñ ô ñ	ô 	ð 	ð #Ð"õ
   Ô 3Ñ4Ô4ð 	Ið 	I‰FˆAˆsØ$>¸qÔ$AÐ!Ý˜#�uÑ%Ô%ð IØ�tÔ'Ô,¨qÑ0Ò0Ð0à$(Ô$4×$9Ò$9À1Ð$9Ñ$EÔ$E�MØ*-×*JÒ*JØ-¨c¬gÔ6Ø%ØÔ(×<Ò<¸QÑ?Ô?ñ+ô +Ñ'Ð$ aõ
 )-Ð-BÑ(CÔ(CÐ%Ø1AÐ% c¤gÑ.Ø.×5Ò5Ð6GÑHÔHÐHøà*×1Ò1Ð2GÑHÔHÐHÐHõ
 " (Ô"5Ñ6Ô6ÐÝ  Ô!4Ñ5Ô5ÐàÔ Ò"Ñ"õ %¥U­3Ð/AÑ+BÔ+BÑ%CÔ%CÑDÔDð (:ñ (:�Ø,¨XÔ6�Ø*¨8Ô4�õ ˜f¥eÑ,Ô,ð -ð !'¤
�IØBDÀbÐ+?Ð)Ý%.ÝÐ.Ð0AÑBÔBñ&ô &ð ;ð ;™	˜™6˜A˜qð  š=˜=Ø!˜EØŸ:š: iÑ0Ô0ð <Ø1×8Ò8¸Ñ;Ô;Ð;ØŸ:š: iÑ0Ô0ð ;Ø0×7Ò7¸Ñ:Ô:Ð:øà,Ð0DÒDÐDõ
 "+¡¤˜à˜fÒ$Ð$Ø#×*Ò*Ý&Ø%-Ø07¸Ð/@Ø*DÀXÔ*Nðñ ô ñô ð ð 4:Ð& xÑ0ùõ
 ,5ÝÐ"Ð$5Ñ6Ô6ñ,
ô ,
ð 	6ð 	6Ñ'ˆHÑ'�w ð ˜&Ò Ð Ø×&Ò&Ý"Ø!)Ø,3°VÐ+<Ø&@ÀÔ&Jðñ ô ñô ð ð 06Ð" 8Ñ,øØÐr2   r  ra   )"rS   rT   rU   rb   r  Ú	dataclassr  r  ÚstaticmethodÚdictrV   r‘   r   r#  r'  r   r   r?   rX   r   rè   rY   r9  r   rA  r@  r$   r^  rm  r   ru  r   r†  r˜  rZ   r2   r0   rò   rò   ¤  s  € € € € € ðð ð €[Ô $¨dÐ3Ñ3Ô3ð.ð .ð .ð .ð .ñ .ô .ñ 4Ô3ð.ð`ð ð ð ð
˜t C¨¨c¬ NÔ3ð 
¸
ð 
ð 
ð 
ñ „\ð
ð ð$˜zð $¨d°3¸¸S¼	°>Ô.Bð $ð $ð $ñ „\ð$ð ð
 .2Ø16ðG$ð G$ØðG$à! .Ô1ðG$ð ˜Y¨˜^Ô,ðG$ð $ dÑ*ð	G$ð
 +/ðG$ð 
ðG$ð G$ð G$ñ „\ðG$ðR$àð$ð !ð$ð 
ð	$ð $ð $ð $ð.+à	ð+ð +ð +ð +ð6Và˜) S˜.Ô)ðVð  *ðVð 
Ð4°eÐ;Ô	<ð	Vð Vð Vð Vðt<
Ø"ð<
Ø/8ð<
à	Ð4Ô	5ð<
ð <
ð <
ð <
ð|!à9ð!ð ð!ð !  c œ?ð	!ð
 
ˆkÔ	ð!ð !ð !ð !ðBGàðGð ðGð !  c œ?ð	Gð
 
ˆnÔ	ðGð Gð Gð GðR~àð~ð ð~ð 
ˆnÔ	ð	~ð ~ð ~ð ~ð ~ð ~r2   rv  rw  Úuse_graph_based_transformc                 óê  — | j         }| j        }|j        }t          d„ ||fD ¦   «         ¦  «         }t          d„ g | j        ¢|j        ¢R D ¦   «         ¦  «        }|s|rd}nt
          �t
          }n|€d}| j        €t          ‚t          || j        ¦  «        }|rD	 | 	                    | || j
        ¦  «        }	n<# t          $ r |                     | |¦  «        }	Y nw xY w|                     | |¦  «        }	|	S )Nc              3   ó>   K  — | ]}t          j        |¦  «        V — Œd S rx   )r   Úis_default_device_order)ry   Úorders     r0   r|   z2_gen_transform_infos_non_cached.<locals>.<genexpr>¿  sA   è è € ð $ð $àõ 	Ô+¨EÑ2Ô2ð$ð $ð $ð $ð $ð $r2   c              3   ó@   K  — | ]}t          |t          ¦  «        V — Œd S rx   )r#   r   rO  s     r0   r|   z2_gen_transform_infos_non_cached.<locals>.<genexpr>Ã  s@   è è € ð ð àõ 	�1•mÑ$Ô$ðð ð ð ð ð r2   TF)rŠ   rF  r×   Úanyr   r   rE  rE   rù   r†  r<  r   r˜  )
rv  rw  rœ  rŠ   r(  r�  Úhas_non_default_orderÚhas_strided_shardÚdrpr­   s
             r0   Ú_gen_transform_infos_non_cachedr¦  µ  sz  € ð
 Ô&€KØÔ*€OØÔ*€Oõ !$ð $ð $à% Ð7ð$ñ $ô $ñ !ô !ð Ðõ ð ð à=�8Ô&Ð=¨Ô)<Ð=Ð=ðñ ô ñ ô Ðð ð *Ð 1ð *Ø$(Ð!Ð!Ý	,Ð	8Ý$GÐ!Ð!Ø	"Ð	*Ø$)Ð!ØÔÐ#ÝÐÝ
"ØØÔñô €Cð !ð Rð	VØ!×FÒFØ˜( H¤Nñô ˆOˆOøõ .ð 	Vð 	Vð 	VØ!×AÒAÀ(ÈHÑUÔUˆOˆOˆOð	Vøøøð ×=Ò=¸hÈÑQÔQˆØÐs   ÂB7 Â7 CÃCc                 ó$   — t          | ||¦  «        S rx   )r¦  )rv  rw  rœ  s      r0   Ú_gen_transform_infosr¨  î  s   € õ +Ø�(Ð5ñô ð r2   )Úasync_oprœ  Úis_explicitÚlocal_tensorÚcurrent_specÚtarget_specr©  rª  c                ó2  — |j         |j         k    rt          d¦  «        ‚|j        €t          d¦  «        ‚t	          |j        ¦  «         t	          |j        ¦  «         | }|j         }|                     ¦   «         s| S t          ¦   «         rt          |||¦  «        }nt          |||¦  «        }t          |||j        |j        ¦  «        }	t          ¦   «         }
|
�O|
                     | |j        |j        t                               ||	|j        |j        |j        ¦  «        |¬¦  «        nt!          j        ¦   «         }|5  |	D �]¼}t%          |t&          ¦  «        r|j         }n|}|j        }|j        \  }}t%          |t,          ¦  «        st%          |t,          ¦  «        r||u s
J d¦   «         ‚|                     |¬¦  «        }||k    r| }ŒŠ|dk    r| }Œ“|                     ¦   «         rú|                     ¦   «         rTt5          t6          |¦  «        }|                     | ||¦  «        }t%          |t&          ¦  «        r|j        �
||j        z  }�n{|                     ¦   «         r4t5          t>          |¦  «        }|                      | |||j!        ¦  «        }�n3t%          |t,          ¦  «        r|                      | |||j!        ¦  «        }�nÿtE          d|› d	|› d
�¦  «        ‚|                     ¦   «         �r‘t5          t>          |¦  «        }|                     ¦   «         rUt5          t6          |¦  «        }| #                    | |||¦  «        }t%          |t&          ¦  «        r|j        �
||j        z  }�nV|                     ¦   «         r-| $                    | ||| %                    |¦  «        ¦  «        }�n|                     ¦   «         rJt5          t>          |¦  «        }|j&        |j&        k    r#| '                    | |||j!        |j&        ¦  «        }�n·t%          |t,          ¦  «        rJ|                      | |||j!        ¦  «        }| $                    |||| %                    |¦  «        ¦  «        }�nXt          d|› d|› �¦  «        ‚|                     ¦   «         r‡|                     ¦   «         r.t5          t6          |¦  «        }| (                    | ||¦  «        }�nítS          |¦  «        rtE          d|› d	|› d
�¦  «        ‚||k    rtU          d|› d|› d�¦  «        ‚| }�n¨t%          |t,          ¦  «        �r’|                     ¦   «         rYt5          t6          |¦  «        }|                     | ||¦  «        }| +                    |||| %                    |¦  «        ¦  «        }�n%|                     ¦   «         r,| +                    | ||| %                    |¦  «        ¦  «        }nå|                     ¦   «         r^t5          t>          |¦  «        }|                      | |||j!        ¦  «        }| +                    |||| %                    |¦  «        ¦  «        }nst%          |t,          ¦  «        rI|                      | |||j!        ¦  «        }| +                    |||| %                    |¦  «        ¦  «        }nt          d|› d|› �¦  «        ‚|s.t%          |tX          j-        ¦  «        r| .                    ¦   «         }|} �Œ¾	 ddd¦  «         n# 1 swxY w Y   |S )zÿ
    This redistribute the local tensor (torch.Tensor) from the current DTensorSpec to
    the target DTensorSpec, which involves the necessary collective calls to transform
    the local shard of the DTensor from its current spec to the target spec.
    z)Cross device mesh comm not supported yet!NzUuse_strided_shard_as_shard_order should be initialized in DTensorSpec.__post_init__())rª  z:_StridedShard redistribute assumes no flattened transformsrÉ   rD   zredistribute from z to z not supported yetzUnexpected placement z& for redistribute to target placement z&Redistribution from one partial type (z) to another (z) is unsupported.)/r]   rÜ   r)  rj   r   r   r;  r	   r¦  r¨  rñ   r   Úrecord_redistribute_callsrò   r9  rF  Ú
contextlibÚnullcontextr#   r\   r@   rA   r   rÔ   rO   rN   r   r   Ú_reduce_valuer_   r‹  r   Ú_to_replicate_tensorrB   ÚRuntimeErrorÚ_reduce_shard_valueÚ_replicate_to_shardrq  rg   Ú_to_new_shard_dimÚ_partition_valuer   rE   Ú_replicate_to_strided_shardÚfuncolÚAsyncCollectiveTensorÚwait)r«  r¬  r­  r©  rœ  rª  Únew_local_tensorrŠ   r­   Úoptimized_transform_infosÚ
debug_modeÚredistribute_contextrc   Úmesh_to_userz   r’  r“  Ú
num_chunksÚpartial_specÚcurrent_placementÚtarget_placementÚ
shard_specÚ
replicateds                          r0   Úredistribute_local_tensorrÈ  ù  s§  € ð  Ô˜KÔ,Ò,Ð,å!Ð"MÑNÔNÐNàÔ4Ð<ÝØcñ
ô 
ð 	
õ " ,Ô"9Ñ:Ô:Ð:Ý! +Ô"8Ñ9Ô9Ð9à#ÐØÔ#€Kà×4Ò4Ñ6Ô6ð ð ÐåÑÔð 
Ý9Ø˜+Ð'@ñ
ô 
ˆˆõ /Ø˜+Ð'@ñ
ô 
ˆõ
 !:ØØØÔØÔñ	!ô !Ðõ 'Ñ(Ô(€Jð  Ð!ð 	×,Ò,ØØÔ#ØÔ"Ý&×@Ò@ØØ)ØÔ'ØÔ(ØÔ=ñô ð $ð 	-ñ 	
ô 	
ð 	
õ Ô#Ñ%Ô%ð ð$ 
ð b,ð b,Ø7ð a	,ñ a	,ˆNå˜.Õ*AÑBÔBð *Ø,Ô1��à)�ØÔ'ˆAØ,Ô?‰OˆG�Võ
 ˜'¥=Ñ1Ô1ð µZÀÍÑ5VÔ5Vð Ø" kÐ1Ð1Ð1ØPñ 2Ô1Ð1ð %×)Ò)°1Ð)Ñ5Ô5ˆJà˜&Ò Ð à#/Ð Øà˜QŠˆð $0Ð Øà×"Ò"Ñ$Ô$ð }à×%Ò%Ñ'Ô'ð Ý#'­°Ñ#9Ô#9�LØ'3×'AÒ'AØ$ k°1ñ(ô (Ð$õ
 # >Õ3JÑKÔKðWà*Ô4Ð@à+;¸nÔ>VÑ+VÐ(ùØ×%Ò%Ñ'Ô'ð Ý(,­U°GÑ(<Ô(<Ð%Ø'8×'MÒ'MØ$ k°1°nÔ6Rñ(ô (Ð$Ñ$õ   ­Ñ7Ô7ð Ø'.×'CÒ'CØ$ k°1°nÔ6Rñ(ô (Ð$Ñ$õ 'ØT¨WÐTÐT¸&ÐTÐTÐTñô ð ð —’Ñ"Ô"ñ bå#'­¨vÑ#6Ô#6Ð Ø×%Ò%Ñ'Ô'ð (Ý#'­°Ñ#9Ô#9�LØ'3×'GÒ'GØ$ k°1Ð6Fñ(ô (Ð$õ
 # >Õ3JÑKÔKðWà*Ô4Ð@à+;¸nÔ>VÑ+VÐ(ùØ×)Ò)Ñ+Ô+ð à'7×'KÒ'KØ$ k°1°k×6UÒ6UÐVWÑ6XÔ6Xñ(ô (Ð$Ñ$ð ×%Ò%Ñ'Ô'ð Ý!%¥e¨WÑ!5Ô!5�JØ!”~Ð)9Ô)=Ò=Ð=Ø+5×+GÒ+GØ(Ø'ØØ*Ô8Ø,Ô0ñ,ô ,Ð(ùõ   ­Ñ7Ô7ð à!(×!=Ò!=Ø$ k°1°nÔ6Rñ"ô "�Jð (8×'KÒ'KØ"Ø#ØØ#×7Ò7¸Ñ:Ô:ñ	(ô (Ð$Ñ$õ %Øg°ÐgÐgÐ_eÐgÐgñô ð ð ×"Ò"Ñ$Ô$ð 6Ø×'Ò'Ñ)Ô)ð 4Ý#'­°Ñ#8Ô#8�LØ'3×'DÒ'DØ$ k°1ñ(ô (Ð$Ñ$õ $ GÑ,Ô,ð 
4Ý&ØT¨WÐTÐT¸&ÐTÐTÐTñô ð ð  &Ò(Ð(Ý,ØuÀWÐuÐuÐ\bÐuÐuÐuñô ð ð (4Ð$Ñ$Ý˜F¥MÑ2Ô2ñ %à×%Ò%Ñ'Ô'ð #å#'­°Ñ#9Ô#9�LØ!-×!;Ò!;Ø$ k°1ñ"ô "�Jð (.×'IÒ'IØ" K°°K×4SÒ4SÐTUÑ4VÔ4Vñ(ô (Ð$Ñ$ð ×)Ò)Ñ+Ô+ð à'-×'IÒ'IØ$ k°1°k×6UÒ6UÐVWÑ6XÔ6Xñ(ô (Ð$Ð$ð ×%Ò%Ñ'Ô'ð å(,­U°GÑ(<Ô(<Ð%Ø!2×!GÒ!GØ$ k°1°nÔ6Rñ"ô "�Jð (.×'IÒ'IØ" K°°K×4SÒ4SÐTUÑ4VÔ4Vñ(ô (Ð$Ð$õ   ­Ñ7Ô7ð ð ")×!=Ò!=Ø$ k°1°nÔ6Rñ"ô "�Jð (.×'IÒ'IØ" K°°K×4SÒ4SÐTUÑ4VÔ4Vñ(ô (Ð$Ð$õ %Øg°ÐgÐgÐ_eÐgÐgñô ð ð ð ;¥
Ø ¥&Ô">ñ!ô !ð ;ð $4×#8Ò#8Ñ#:Ô#:Ð Ø+ˆL‰LðCa	,ðb,ð b,ð b,ñ b,ô b,ð b,ð b,ð b,ð b,ð b,ð b,øøøð b,ð b,ð b,ð b,ðF Ðs   Ä>W\Ü\Ü\©r©  Úgrad_outputúdtensor.DTensorÚprevious_specÚ	out_dtypeÚop_dtypec          	      ó  — || j         j        k    r›| j                              |¬¦  «        }t          | j        j        | j        j        t          | j        |  	                    ¦   «         |¬¦  «        | j        j
        ¬¦  «        }t          |j        |j        |j        |j
        ¬¦  «        }n| j         }| j        }g }t          |j        |j        ¦  «        D ]s\  }}	t          |¦  «        s|                     ¦   «         r6|	                     ¦   «         r"|                     t#          ¦   «         ¦  «         Œ^|                     |	¦  «         Œtt          |j        t%          |¦  «        |j        |j
        ¬¦  «        }t'          ||||¬¦  «        }
|
j        |k    r|
                     |¦  «        }
t          |j        t%          |¦  «        t          | j        |  	                    ¦   «         |
j        ¬¦  «        |j
        ¬¦  «        }|
|fS )a§  
    Common function for redistributing a distributed tensor during backward
    and twice-backward backpropagation steps.

    Args:
        grad_output: The output gradient tensor.
        previous_spec: DTensorSpec prior to redistribution.
        out_dtype: dtype to cast the returned gradient to. Pinned by autograd
                to match the dtype of the input of the node above this one.
        op_dtype: dtype to run the backward collective at.
        async_op: whether to perform the DTensor redistribute operation
                asynchronously or not. Default: False

    Returns:
        A :class:`torch.Tensor` object.
        A :class:`DTensorSpec` object.
    ©Údtype©r<  ÚstriderÑ  ©r]   r   rE  r)  )r   rE  r)  rÉ  ©rE  r)  )Ú_local_tensorrÑ  Útor   Ú_specrŠ   r   r   r<  rÓ  r)  rE  r€  r   rO   rN   rm   r   rX   rÈ  )rÊ  rÌ  rÍ  rÎ  r©  r«  r¬  Únormalized_placementsr’  r“  Úoutputry  s               r0   Ú_redistribute_backwardrÛ  ë  s8  € ð2 �;Ô,Ô2Ò2Ð2Ø"Ô0×3Ò3¸(Ð3ÑCÔCˆÝ"ØÔ"Ô.Ø"Ô(Ô3Ý"Ø!Ô'Ø"×)Ò)Ñ+Ô+Øðñ ô ð
 .9Ô->Ô-_ð	
ñ 	
ô 	
ˆõ $ØÔ*Ø$Ô/Ø$Ô0Ø-:Ô-[ð	
ñ 
ô 
ˆˆð #Ô0ˆØ"Ô(ˆð .0ÐÝ˜|Ô6¸Ô8PÑQÔQð 1ð 1‰ˆ�Ý˜7Ñ#Ô#ð 	1 w×';Ò';Ñ'=Ô'=ð 	1À6×CTÒCTÑCVÔCVð 	1Ø!×(Ò(­©¬Ñ5Ô5Ð5Ð5à!×(Ò(¨Ñ0Ô0Ð0Ð0åØÔ!ÝÐ.Ñ/Ô/Ø!Ô-Ø)6Ô)Wð	ñ ô €Mõ 'ØØØØð	ñ ô €Fð „|�yÒ Ð Ø—’˜9Ñ%Ô%ˆåØÔ!ÝÐ#Ñ$Ô$ÝØÔ#Ø×%Ò%Ñ'Ô'Ø”,ð
ñ 
ô 
ð
 *7Ô)Wð	ñ 	ô 	€Dð �4ˆ<Ðr2   c                   ó8   — e Zd ZU ej        ed<   ej        ed<   dS )Ú_BackwardDtypeConfigrÎ  rÍ  N)rS   rT   rU   r%   rÑ  rW   rZ   r2   r0   rÝ  rÝ  I  s.   € € € € € € ØŒkÐÐÑØŒ{ÐÐÑÐÐr2   rÝ  c                   óB   — e Zd ZU ej        ed<   ej        ed<   eed<   dS )Ú_DtypeConfigrÎ  rÍ  Úbackward_optionsN)rS   rT   rU   r%   rÑ  rW   rÝ  rZ   r2   r0   rß  rß  N  s:   € € € € € € ØŒkÐÐÑØŒ{ÐÐÑØ*Ð*Ð*Ñ*Ð*Ð*r2   rß  c                   ób   — e Zd Zedddedeedf         dedef
d„¦   «         Z	edd
„¦   «         Z
dS )ÚRedistributeÚinputrË  rŠ   r   .r©  Údtype_configc           	      ó  — || _         |d         }|d         | _        |d         | _        |d         }|d         }||j        j        k    rj|j                             |¬¦  «        }	t          ||j        j        t          |j
        |                     ¦   «         |¬¦  «        |j        j        ¬¦  «        }
n|j        }	|j        }
|
| _        |
j        |k    r,t          |||
j        ¬¦  «        }t          |	|
||d¬	¦  «        }n|	}|
}|j        |k    rY|                     |¦  «        }t          ||j        t          |j
        |                     ¦   «         |¬¦  «        |j        ¬
¦  «        }t!          j        |||j        ¬¦  «        S )Nrà  rÎ  rÍ  rÐ  rÒ  rÔ  )rE  T)r©  rª  rÕ  ©Úrequires_grad)r©  Úbwd_op_dtypeÚbwd_out_dtyperÖ  rÑ  r×  r   rØ  r   r   r<  rÓ  r)  r¬  rE  rÈ  ÚdtensorÚDTensorrç  )Úctxrã  rŠ   r   r©  rä  ÚbwdrÎ  rÍ  r«  r¬  r­  rÚ  s                r0   ÚforwardzRedistribute.forwardU  sÄ  € ð  ˆŒØÐ-Ô.ˆØ˜zœ?ˆÔØ Ô,ˆÔà 
Ô+ˆØ  Ô-ˆ	à�uÔ*Ô0Ò0Ð0Ø Ô.×1Ò1¸Ð1ÑAÔAˆLÝ&Ø Ø œ;Ô1Ý&Øœ+Ø Ÿ<š<™>œ>Ø"ðñ ô ð
 27´Ô1]ð	ñ 	ô 	ˆLˆLð !Ô.ˆLØ œ;ˆLà'ˆÔàÔ" jÒ0Ð0Ý%Ø˜Z°\Ô5Mðñ ô ˆKõ /ØØØØ!Ø ðñ ô ˆFˆFð "ˆFØ&ˆKàŒ<˜9Ò$Ð$Ø—Y’Y˜yÑ)Ô)ˆFÝ%ØØÔ&Ý&Øœ+Ø Ÿ<š<™>œ>Ø#ðñ ô ð
 2=Ô1]ð	ñ 	ô 	ˆKõ ŒàØàÔ-ð
ñ 
ô 
ð 	
r2   rÊ  c                 ót   — t                                || j        | j        | j        | j        ¦  «        }|d d d d fS rx   )ÚNestedRedistributeÚapplyr¬  r©  rè  ré  )rì  rÊ  Úoutput_dtensors      r0   ÚbackwardzRedistribute.backward   sL   € å+×1Ò1ØØÔØŒLØÔØÔñ
ô 
ˆð ØØØØð
ð 	
r2   N)rÊ  rË  )rS   rT   rU   rš  r   rX   r   rè   rß  rî  ró  rZ   r2   r0   râ  râ  T  s—   € € € € € ØðH
ð !ðH
ð  ð	H
ð
 ˜) S˜.Ô)ðH
ð ðH
ð #ðH
ð H
ð H
ñ „\ðH
ðT ð
ð 
ð 
ñ „\ð
ð 
ð 
r2   râ  c                   ój   — e Zd ZdZedddededej        dej        f
d„¦   «         Z	edd
„¦   «         Z
dS )rð  a¯  
    This class is used to make the redistribution of a DTensor twice-differentiable.
    This is called during the `Redistribute.forward`.
    Therefore, `NestedRedistribute.forward` is called during the first backward pass,
    and `NestedRedistribute.backward` is called during the second backward pass.

    Note: `NestedRedistribute.backward` is not differentiable, and therefore triple
    backward is not yet supported.
    rÊ  rË  rÌ  r©  rÎ  rÍ  c                 ó´   — || _         |j        j        | _        || _        t          |||||¬¦  «        \  }}|| _        t          j        |||j	        ¬¦  «        S )N)rÍ  rÎ  r©  ræ  )
r©  rÖ  rÑ  Úoriginal_dtyperÎ  rÛ  r¬  rê  rë  rç  )rì  rÊ  rÌ  r©  rÎ  rÍ  rÚ  ry  s           r0   rî  zNestedRedistribute.forward½  sx   € ð  ˆŒØ(Ô6Ô<ˆÔØˆŒå-ØØØØØð
ñ 
ô 
‰ˆ�ð  ˆÔõ ŒàØà%Ô3ð
ñ 
ô 
ð 	
r2   Úgrad2_outputc                 óz   — | j         }t                               ||| j        | j        | j        ¦  «        }|d d d d d fS rx   )r¬  rð  rñ  r©  rÎ  rö  )rì  r÷  rÌ  rò  s       r0   ró  zNestedRedistribute.backwardà  sU   € àÔ(ˆõ ,×1Ò1ØØØŒLØŒLØÔñ
ô 
ˆð ØØØØØð
ð 	
r2   N)r÷  rË  )rS   rT   rU   rb   rš  r   rè   r%   rÑ  rî  ró  rZ   r2   r0   rð  rð  ²  s•   € € € € € ðð ð ð 
ð 'ð 
ð #ð	 
ð
 ð 
ð ”+ð 
ð ”;ð 
ð  
ð  
ñ „\ð 
ðD ð
ð 
ð 
ñ „\ð
ð 
ð 
r2   rð  )Tra   rx   )`r°  r  r}  ÚloggingrÚ   rö   Úcollectionsr   Úcollections.abcr   Ú	functoolsr   Útypingr   r   r   r%   Ú)torch.distributed._functional_collectivesr‹   Ú_functional_collectivesrº  Útorch.distributed.tensor._apiÚtensorÚ_apirê  r	   Útorch.distributed._mesh_layoutr
   Ú*torch.distributed.tensor._collective_utilsr   Ú&torch.distributed.tensor._dtensor_specr   r   r   r   r   Útorch.distributed.tensor._utilsr   Ú$torch.distributed.tensor.device_meshr   Ú(torch.distributed.tensor.placement_typesr   r   r   r   r   r   Útorch.typesr   r   Útorch.utils._debug_moder   Ú	getLoggerrS   r¦   r   rè   rW   r   r$   r1   Úcontextmanagerr6   r:   r™  r?   r\   r‘   r›  rV   ru   rX   rˆ   r’   rh   r“   rY   r¬   rñ   ró   ÚReferenceTyperù   rü   rò   r¦  r¨  ÚTensorrÈ  rÑ  rÛ  rÝ  rß  ÚautogradÚFunctionrâ  rð  rZ   r2   r0   ú<module>r     s?  ðð Ð Ð Ð Ð Ø Ð Ð Ð Ø Ð Ð Ð Ø €€€Ø €€€Ø €€€Ø #Ð #Ð #Ð #Ð #Ð #Ø $Ð $Ð $Ð $Ð $Ð $Ø Ð Ð Ð Ð Ð Ø 'Ð 'Ð 'Ð 'Ð 'Ð 'Ð 'Ð 'Ð 'Ð 'à €€€Ø :Ð :Ð :Ð :Ð :Ð :Ð :Ð :Ð :Ø /Ð /Ð /Ð /Ð /Ð /Ð /Ð /Ð /Ð /Ð /Ð /Ø EÐ EÐ EÐ EÐ EÐ EØ 6Ð 6Ð 6Ð 6Ð 6Ð 6Ø QÐ QÐ QÐ QÐ QÐ Qðð ð ð ð ð ð ð ð ð ð ð ð ð ð JÐ IÐ IÐ IÐ IÐ IØ ;Ð ;Ð ;Ð ;Ð ;Ð ;ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð 3Ð 2Ð 2Ð 2Ð 2Ð 2Ð 2Ð 2Ø 9Ð 9Ð 9Ð 9Ð 9Ð 9ð 
ˆÔ	˜8Ñ	$Ô	$€ð 48Ð # T¨D¡[Ð 7Ð 7Ñ 7ð 6;Ð ,¨dÐ :Ð :Ñ :ðM mð M¸ð Mð Mð Mð Mð& Ôð98ð 98¨dð 98ð 98ð 98ñ Ôð98ðx ÔðAð A¸$ð Að Að Añ ÔðAð8 €Ô˜d¨$Ð/Ñ/Ô/ð ð  ð  ð  ð  ñ  ô  ñ 0Ô/ð ðF €Ô˜d¨$Ð/Ñ/Ô/ðð ð ð ð ˜nñ ô ñ 0Ô/ðð4.5Ø"ð.5à˜Yœð.5ð ˜3  S¤	˜>Ô*ð.5ð 
ð	.5ð .5ð .5ð .5ðbØ
ðØ!& s¨C x¤ðà�$Ñðð ð ð ð>?Ø
ð?Ø!& s¨C x¤ð?à�$Ñð?ð ?ð ?ð ?ð0 ADÀÁÄÐ ˜˜E # u¨S°#¨X¤¸Ð";Ô<Ô=Ð EÐ EÑ Eð9Øð9à�S˜#�XŒð9ð ˜) S˜.Ô)ð9ð ˜) S˜.Ô)ð	9ð
 ð9ð ð9ð ð9ð 
ð9ð 9ð 9ð 9ðxpØ˜.Ô)ðpàðpð ˜) S˜.Ô)ðpð ˜) S˜.Ô)ð	pð
 
ˆ.Ð2Ñ
2Ô3ðpð pð pð pðn ð �Ø	ˆ'Ô
 
Ô
+¨ZÐ
7Ô8Ø ð"ôð ð ñ ð%Øð%àð%ð "ð%ð %ð %ð %ð4ð ð ð ð
Nð Nð Nð Nð Nñ Nô Nð Nðh .2ð6ð 6Øð6àð6ð  $ d™{ð6ð 
ˆ.Ôð	6ð 6ð 6ð 6ðr ð .2ðð Øðàðð  $ d™{ðð 
ˆ.Ôð	ð ð ñ „ðð Ø-1àðoð oð oØ”,ðoàðoð ðoð
 ðoð  $ d™{ðoð ðoð „\ðoð oð oð oðp ð[ð [ð [Ø"ð[àð[ð Œ{ð	[ð
 Œkð[ð ð[ð [ð [ð [ð|ð ð ð ð ˜9ñ ô ð ð
+ð +ð +ð +ð +�9ñ +ô +ð +ð[
ð [
ð [
ð [
ð [
�5”>Ô*ñ [
ô [
ð [
ð|C
ð C
ð C
ð C
ð C
˜œÔ0ñ C
ô C
ð C
ð C
ð C
r2   