
    ȅiWI              	           % S SK r S SKrS SKJrJr  S SKJr  S SKJrJ	r	  S SK
r
S SKJr  S SKJr  S SKJr  S SKJr  S SKJr  S S	KJr  S
SKJrJrJrJrJrJrJr  S
SK J!r!J"r"J#r#J$r$J%r%J&r&  S
SK'J(r(J)r)  S/r*\+\,   \-S'   S\#S\#S\.4S jr/S\+\#   S\.4S jr0S\+\#   S\+\#   S\+\#   4S jr1S\
Rd                  S\4S jr3S\S\4S jr4S\S\S\$4S jr5S\,S\S\%4S jr6S\,S\S\S\%4S  jr7S\,S\
Rd                  S\%4S! jr8S\,S"\4S# jr9S$ r:S% r;S\,S&\S'\+\   S\+\"   4S( jr<S)\S\#4S* jr=S\,S+\S\+\%   4S, jr>S\S\4S- jr?S\
Rd                  S\+\   4S. jr@S\,S/\S0\S\+\"   4S1 jrAS)\B\,\4   S\4S2 jrCS3\S4\S5\S6\4S7 jrDg)8    N)bisect_rightinsort)Callable)Anycast)_get_device_module)ShardMetadata)ShardedTensor)DTensor)%compute_local_shape_and_global_offset   )BytesStorageMetadataChunkStorageMetadataMetadataIndexSTATE_DICT_TYPESTORAGE_TYPESTensorPropertiesTensorStorageMetadata)LoadItemTypeReadItemSavePlanTensorWriteData	WriteItemWriteItemType)"_check_shard_metadata_pair_overlap+_shards_get_overlap_region_wrt_saved_tensor create_read_items_for_chunk_list__all__plan
other_planreturnc                    U R                   UR                   :w  a  g[        U R                  5      [        UR                  5      :w  a  g[        U R                  UR                  5       GHn  u  p#UR                  UR                  :w  a    gUR
                  nUR
                  nUR                  UR                  :w  d4  UR                  UR                  :w  d  UR
                  UR
                  :w  a    gUR                  nUR                  nU(       a  U(       a  U(       d	  U(       a    gU(       d  M  U(       d  M  UR                  UR                  :w  a    gUR                  nUR                  n	U(       a  U	(       a  U(       d	  U	(       a    gU(       d  GM.  U	(       d  GM8  UR                  U	R                  :w  d  UR                  U	R                  :w  d  GMo    g   g)z
Compare the two Save plans and return True if they are equal.

Args:
    plan (SavePlan): First SavePlan to compare.
    other_plan (SavePlan): Second SavePlan to compare.

Returns:
   True if the two plans are equal, False otherwise.
FT)usablelenitemsziptypeindexfqnoffsettensor_datasizechunkoffsetssizes)
r   r    	plan_itemother_plan_itemplan_metadata_indexother_plan_metadata_indexr+   other_tensor_datar-   other_chunks
             f/home/james-whalen/.local/lib/python3.13/site-packages/torch/distributed/checkpoint/planner_helpers.py_compare_save_plansr7   *   sq    {{j''' 4::#j..// '*$**j6F6F&G"	>>_111'oo$3$9$9!  ##'@'D'DD"))-F-M-MM"((,E,K,KK  +++77 1 1;,,#4#9#99  %%E+11Kk5[ uMM[%8%88{{k&7&77 S 'HV     delta_plansc                 &    [        S U  5       5      $ )z
Check if any delta plan is usable, indicating the plan has changed.

Args:
    delta_plans (List[SavePlan]): A list of delta plans to check.
Returns:
    True if any delta plan is usable, False otherwise.
c              3   J   #    U  H  o=(       a    UR                   v   M     g 7fN)r#   ).0
delta_plans     r6   	<genexpr>(_contains_usable_plan.<locals>.<genexpr>t   s     N+J/j///+s   !#)any)r9   s    r6   _contains_usable_planrB   k   s     N+NNNr8   cached_plansc                     / n[        X5       HA  u  p4U(       a$  UR                  (       d  UR                  U5        M0  UR                  U5        MC     U$ )aG  
Merge a list of delta plans into a single plan.

Args:
    cached_plans (List[SavePlan]): A list of cached plans.
    delta_plans (List[SavePlan]): A list of delta plans to merge. It can contain empty plans

Returns:
    A single merged plan. If a delta plan is not usable, use the cached plan. Otherwise, use the delta plan.
)r&   r#   append)rC   r9   merged_planscached_planr>   s        r6   _merge_delta_local_plansrH   w   sK     L#&|#Aj//,
+	 $B r8   tensorc           	          [        [        R                  " S/[        U R	                  5       5      -  5      U R	                  5       S9$ )Nr   r.   r/   )r   torchSizer$   r,   )rI   s    r6   _create_chunk_from_tensorrN      s5    

A3V[[]!334FKKM r8   shard_mdc                     [        [        R                  " U R                  5      [        R                  " U R                  5      S9$ NrK   )r   rL   rM   shard_offsetsshard_sizes)rO   s    r6   _chunk_for_shardrT      s3    

8112jj--. r8   sharded_tensorc                    U R                  5       R                  n[        UR                  UR                  UR
                  UR                  UR                  S9n[        [        U5      UU R                  5       R                  S9$ )N)dtypelayoutrequires_gradmemory_format
pin_memoryr-   
propertiesr,   )metadatatensor_propertiesr   rW   rX   rY   rZ   r[   r   rT   r,   )rU   rO   shard_propertiesr]   s       r6   _sharded_tensor_metadatara      s|     &..0BB!$$&&&44&44#..J x($$&++ r8   r)   c                 x   [        UR                  UR                  UR                  5      u  p#[        R
                  " U5      [        R
                  " U5      p2[        [        X5      [        R                  [        [        UUS9[        R                  " UR                  5       5      UR                  5       S9S9$ )NrK   r\   r(   r'   r+   )r   shapedevice_mesh
placementsrL   rM   r   r   r   SHARDr   r   r   create_from_tensorto_localr,   )r)   rI   r/   r.   s       r6   _create_write_items_for_dtensorrj      s    :f((&*;*;NE ZZ&

7(;7C)  #& (::6??;LM
 r8   c                     [         R                  " UR                  5      n[        [	        X5      [
        R                  [        X5      S9$ )Nrc   )rL   rM   rR   r   r   r   rg   ra   )r)   rU   rO   r.   s       r6   _create_write_item_for_shardrl      s>     jj//0GC)  ,^F r8   c                 (   [         R                  " S/[        UR                  5       5      -  5      n[	        [        X5      [        R                  [        [        X!R                  5       S9[        R                  " U5      UR                  5       S9S9$ )Nr   rK   r\   rc   )rL   rM   r$   r,   r   r   r   TENSORr   r   r   rh   )r)   rI   r.   s      r6   _create_write_item_for_tensorro      sm    jj!s6;;=112GC)!!#&wkkmL'::6B
 r8   bytesc                 D    [        [        U 5      [        R                  S9$ )N)r(   r'   )r   r   r   BYTE_IO)r)   rp   s     r6   _create_write_item_for_bytesiors      s     C "" r8   c           
          [        [        R                  U [        R                  " U45      U[        R                  " U45      [        R                  " U45      S9$ N)r'   
dest_indexdest_offsetsstorage_indexstorage_offsetslengths)r   r   rr   rL   rM   rv   dest_offsetrx   storage_offsetlengths        r6   _create_read_item_for_byteior      sK     !!ZZ/#

N#45

F9% r8   c           
          [        [        R                  U [        R                  " U5      U[        R                  " U5      [        R                  " U5      S9$ ru   )r   r   rn   rL   rM   rv   rw   rx   ry   rz   s        r6   _create_read_item_for_tensorr      sD       ZZ-#

?3

7# r8   checkpoint_mdlocal_chunksc                 R  ^ ^!^" / nUR                   nU(       a  U(       d  U$ [        US   R                  5      nSnUS:  aH  Sn[        U5       H7  m [	        U 4S j[
        R                  " X$5       5       5      nX:  d  M3  UnT nM9     US:X  a  S/[        U5      -  m"S/[        U5      -  m!O~U V	s/ s H1  n	U	R                  U   U	R                  U   U	R                  U   -   4PM3     sn	m"U V	s/ s H1  n	U	R                  U   U	R                  U   U	R                  U   -   4PM3     sn	m![        [        [        U5      5      U"4S jS9n
[        [        [        U5      5      U!4S jS9n/ nSn[        U
5      nU GH  nX/   nT!U   u  nn[        UUS45      nU(       a  US	U2	 X:  a2  X   nUU   nT"U   u  nnUU:  a  O[        UUU45        US-  nX:  a  M2  U H  u  nnUU   n[        UU5      (       d  M  / n/ n/ n[        UUS
9 H;  u  nnnnUR                  U5        UR                  U5        UR                  U5        M=     UR                  [        [        U UR                  U5      U[        U UR                  U5      UUS95        M     GM     U$ s  sn	f s  sn	f )a'  
Create a list of ``ReadItem`` based on the checkpoint and local chunks.

This applies the resharding algorithm and computes the reads needed
to satisfy ``local_chunks`` with a checkpoint described by ``checkpoint_md``.

Args:
    fqn (str) : The state_dict FQN to pass to ``ReadItem``.
    checkpoint_md (TensorStorageMetadata): metadata for a given tensor
        from a checkpoint.
    local_chunks (List[ChunkStorageMetadata]): Local chunks that needs to be
        loaded.

Returns:
    A list of ``ReadItem`` that will satisfy all input chunks.
r   r   c              3   b   >#    U  H$  nUR                   T   UR                  T   -   v   M&     g 7fr<   rK   )r=   r-   dims     r6   r?   3create_read_items_for_chunk_list.<locals>.<genexpr>   s/      HE c"U[[%55Hs   ,/)r   r   c                    > TU    S   $ Nr    )idxsaved_boundss    r6   <lambda>2create_read_items_for_chunk_list.<locals>.<lambda>9      S)!,r8   )keyc                    > TU    S   $ r   r   )r   local_boundss    r6   r   r   =  r   r8   N)saved_shardcurrent_shardr   )chunksr$   r.   rangemax	itertoolschainr/   sortedr   r   r   r   rE   r   r   )#r)   r   r   
read_itemssaved_chunksnum_dims	sweep_dimmax_sizedim_sizecsaved_sorted_indiceslocal_sorted_indicesactive_saved	saved_ptr	num_saved	local_idxlocal_chunklocal_start	local_endcutoffstorage_idxstorage_chunksaved_start	saved_end_ry   rw   rz   _dimoffset_for_saved_tensoroffset_for_current_tensorr~   r   r   r   s#                                   @@@r6   r   r      s   * "$J ''L|<?**+H I!|?C &__\H H "#	 # 1}x#l"33x#l"33 "
! YYy!199Y#7!''):L#LM!
 "
! YYy!199Y#7!''):L#LM!

 "c, , "c, ,
 +-LI()I)	"-!-i!8Yl[",=>WfW%#.9K(5M%1+%>"Ki'<)[!9:NI # +NA{(5M5k=QQ OLG =)')  &&'>?##$=>v& ,,S+2E2EyQ!-"/]22K# %4#
) +' *d Q

s   38J28J$
state_dictc                   ^^ / nU R                  5        H  u  mm[        T[        5      (       a  UR                  [	        TT5      5        M8  [        T[
        5      (       a6  UR                  UU4S jTR                  5       R                   5       5        M  [        T[        R                  5      (       a  UR                  [        TT5      5        M  UR                  [        TT5      5        M     [        U5      $ )Nc              3   >   >#    U  H  n[        TTU5      v   M     g 7fr<   )rl   )r=   rO   r)   objs     r6   r?   5_create_default_metadata_only_plan.<locals>.<genexpr>  s$       >H -S#x@@ >s   )r%   
isinstancer   rE   rj   r
   extendr^   shards_metadatarL   Tensorro   rs   r   )r   requestsr)   r   s     @@r6   "_create_default_metadata_only_planr   y  s    H$$&Sc7##OO;CEF]++OO  # > >  U\\**OO9#sCDOO:3DE ' Hr8   objectc                 R   [        US5      (       a  UR                  X5      $ [        U[        5      (       a5  UR	                  5        Vs/ s H  n[        XUR                  5      PM     sn$ [        U[        R                  5      (       a  [        X5      /$ [        X5      /$ s  snf )N__create_write_items__)hasattrr   r   r
   local_shardsrl   r^   rL   r   ro   rs   )r)   r   shards      r6   _create_write_itemsr     s    v/00,,S99	FM	*	*  ,,.
. )ennE.
 	
 
FELL	)	)-c:;;.s;<<
s   
 B$c                     [        U R                  U R                  U R                  5      u  p[        R
                  " U5      [        R
                  " U5      p![        UUS9$ rQ   )r   rd   re   rf   rL   rM   r   )rI   r/   r.   s      r6   _create_chunk_from_dtensorr     sS    :f((&*;*;NE ZZ&

7(;7 r8   c                 n   [        U S5      (       a  U R                  5       nU$ [        U [        5      (       a5  U R	                  5        Vs/ s H  n[        UR                  5      PM     nnU$ [        U [        R                  5      (       a  [        U 5      /nU$ [        S[        U 5       35      es  snf )N__create_chunk_list__zMUnsupported Type, expecting one of [Tensor, DTensor, ShardedTensor] ,but got )r   r   r   r
   r   rT   r^   rL   r   rN   
ValueErrorr'   )rI   r   r   s      r6   _create_chunk_listr     s    v.//335  
FM	*	*:@:M:M:O
:OU^^,:O 	 
  
FELL	)	)1&9:  V~'
 	

s   B2mdr   c                     [        U[        5      (       d   [        U5      n[        XU5      $ [        [        U 5      S[        U 5      SSS9/$ ! [         a$  n[        SU  S3S[	        U5       3-   5      UeS nAff = f)Nz Invalid checkpoint metadata for z, z(expected BytesStorageMetadata but found r   r{   )r   r   r   r   r'   r   r   r   )r)   r   r   r   exs        r6   _create_read_itemsr     s    b.//	-c2L 0FF )(-+C0 
 	
  	23%r:<T"XJGH 	s   A 
A<A77A<c                 v    S[         4S jnS[        4S jnS[        R                  4S jn[	        U UUU5        g)zH
Initializes meta tensor if the meta tensor is DTensor or torch.Tensor.
valuec                    [        U SS 5      nU[        R                  " S5      :X  a  [        R                  R                  5       R                  n[        [        R                  [        U5      R                  5       5      n[        R                  " U R                  5       US9n[        R                  " UU R                  U R                  U R!                  5       U R#                  5       S9nU$ U $ )Ndevicemetar   )re   rf   rd   stride)getattrrL   r   distdistributed_c10d_get_pg_default_devicer'   r   r   current_device
empty_likeri   r   
from_localre   rf   r,   r   )r   r   device_typenew_local_tensordtensors        r6   dtensor_func&_init_state_dict.<locals>.dtensor_func  s    $/U\\&))//FFHMMK0=LLNF  %//0@P (( !-- ++jjl||~G NLr8   c                     [        U SS 5      nU[        R                  " S5      :X  a  [        S[	        U 5       S35      eU $ )Nr   r   zFound unsupported type z for meta device loading.)r   rL   r   RuntimeErrorr'   )r   r   s     r6   sharded_tensor_func-_init_state_dict.<locals>.sharded_tensor_func  sF    $/U\\&)))$u+6OP  Lr8   c                 2   [        U SS 5      nU[        R                  " S5      :X  ao  [        R                  R                  5       R                  n[        [        R                  [        U5      R                  5       5      n[        R                  " XS9nU$ U $ )Nr   r   r   )r   rL   r   r   r   r   r'   r   r   r   r   )r   r   r   rI   s       r6   tensor_func%_init_state_dict.<locals>.tensor_func  sy    $/U\\&))//FFHMMK0=LLNF %%e;FMLr8   N)r   r   rL   r   _iterate_state_dict)r   r   r   r   s       r6   _init_state_dictr     s@    
G *3 
5<< 
 	r8   iter_objectr   r   r   c           	      p   [        U [        5      (       a  U" U 5      $ [        U [        5      (       a  U" U 5      $ [        U [        R                  5      (       a  U" U 5      $ [        U [
        [        [        [        [        R                  45      (       d  U c  U $ [        U [        5      (       a)  U R                  5        H  u  pE[        XQX#5      X'   M     U $ [        U [        [        45      (       a>  U  Vs/ s H  n[        XaX#5      PM     nn[        U [        5      (       a  [        U5      nU$ gs  snf )a  
Iterate through the state dict, applying the given functions to each tensor type
and update the state dict in place.

Args:
    iter_object (Any): the target state_dict.
    sharded_tensor_func (Callable): the function to apply to ShardedTensor
    dtensor_func (Callable): the function to apply to DTensor
    tensor_func (Callable): the function to apply to Tensor

# TODO: let state_dict_util._iterate_state_dict() to support in place option
so we don't need to have two versions of _iterate_state_dict.
N)r   r   r
   rL   r   intfloatstrrp   ioBytesIOdictr%   r   listtuple)r   r   r   r   r   r   vrets           r6   r   r     s   ( +w''K((	K	/	/";//	K	.	.;'';eS% DEE	K	&	&%++-JC2%8 K . 	K$	/	/ !
   1DR  	 
 k5))*C
 
0
s   8D3)Er   r   bisectr   r   collections.abcr   typingr   r   rL   torch.distributeddistributedr   torch._utilsr   !torch.distributed._shard.metadatar	   'torch.distributed._shard.sharded_tensorr
   torch.distributed.tensorr   torch.distributed.tensor._utilsr   r^   r   r   r   r   r   r   r   plannerr   r   r   r   r   r   
reshardingr   r   r   r   r   __annotations__boolr7   rB   rH   r   rN   rT   ra   rj   rl   ro   rs   r   r   r   r   r   r   r   r   r   r   r   r   r8   r6   <module>r     s   	  ' $     + ; A , Q    99c 9>h >H > >B	OtH~ 	O$ 	Ox.h 
(^2ell 7K } 1E !-:( g ) (	+7D
s 
ELL 
Y 
 C 

x	x(x +,x 
(^	xv? x "=S =# =$y/ =w 3G u|| 5I0J &
C 
] 
 
h 
.4c3h 4C 4n,,, ", 	,r8   