
    sgN              	          U 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	m
Z
mZmZmZmZmZ d dlZd dlmZ d dlmZ d dl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"m#Z#m$Z$ d dl%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z, d dl-m.Z.m/Z/m0Z0m1Z1 d dl2m3Z3 d dl4m5Z5 ddl6m7Z7  ejp                  e9      Z:ejv                  e<d<   g dZ= G d de*      Z> G d de'      Z? G d de?      Z@	 d-deeAe	f   dedeBde&fdZCdee&   dee&   fdZDdeeAe	f   d eBde)fd!ZE	 d-dee)   d"eBdeee)   ef   fd#ZFde!defd$ZGd%ed&edeBfd'ZHd(ej                  d)edeBfd*ZJd+ee)   dedeBfd,ZKy).    N)ChainMap)reduce)AnycastDictListOptionalTupleUnion)narrow_tensor_by_index)dedup_save_plans)FLATTEN_MAPPINGflatten_state_dict)_flatten_sharded_tensors)set_element)BytesStorageMetadataChunkStorageMetadataMetadataMetadataIndexSTATE_DICT_TYPESTORAGE_TYPESStorageMetaTensorStorageMetadata)LoadPlanLoadPlannerReadItemSavePlanSavePlanner	WriteItemWriteItemType)"_create_default_metadata_only_plan_create_read_items_create_write_items_init_state_dict)find_state_dict_object)DTensor   )_versionlogger)DefaultSavePlannerDefaultLoadPlannercreate_default_local_load_plancreate_default_global_load_plancreate_default_local_save_plancreate_default_global_save_planc                      e Zd ZU eed<   	 	 	 	 ddededee   deddf
dZ	 	 dd	ed
ee	   deddfdZ
defdZdee   deee   ef   fdZdedefdZdedeej*                  ej.                  f   fdZdedefdZdedefdZy)r*   mappingsNr   flatten_sharded_tensorsdedup_replicated_tensorsdedup_save_to_lowest_rankreturnc                 l    || _         || _        i | _        || _        |t        j                  d       y y )NzDefaultSavePlanner's `dedup_replicated_tensors` argument is being deprecated, and no longer has any effect. Please remove this argument from your call.)r   r2   r1   r4   r)   warning)selfr   r2   r3   r4   s        _/var/www/html/venv/lib/python3.12/site-packages/torch/distributed/checkpoint/default_planner.py__init__zDefaultSavePlanner.__init__E   s?     #5'>$)B&#/NN" 0    
state_dictstorage_metais_coordinatorc                     | j                   rt        |      \  }| _        | j                  rt        |      }|| _        || _        y N)r   r1   r2   r   r<   r>   )r8   r<   r=   r>   s       r9   set_up_plannerz!DefaultSavePlanner.set_up_plannerW   s@     ""(::(F%J''1*=J$,r;   c                     t        | j                  | j                        }| j                  r!t	        j
                  || j                        }|| _        | j                  S )Nplanner_data)r.   r<   r>   r   dataclassesreplacer1   plan)r8   rG   s     r9   create_local_planz$DefaultSavePlanner.create_local_pland   sH    -doot?R?RS""&&t$--HD	yyr;   	all_plansc                 h   t        || j                        }t        |      \  }}| j                  rA|D cg c]  }|j                   }}t        t        |       }t        j                  ||      }t        ||      st        d      || _        || _        | j                  | j                  fS c c}w )NrC   zFailed to validate global plan)r   r4   r/   r   rD   dictr   rE   rF   _validate_global_plan
ValueErrorglobal_planmetadata)r8   rI   rN   rO   pplanner_data_dictmerged_mappingss          r9   create_global_planz%DefaultSavePlanner.create_global_planl   s     %Y0N0NO	 ?	 JX""
 :E EA E E"8->#?@O"**8/RH$[(;=>>& .. !Fs   B/new_planc                     || _         |S r@   )rG   r8   rT   s     r9   finish_planzDefaultSavePlanner.finish_plan   s    	r;   
write_itemc                 \    | j                  |j                        }| j                  ||      S r@   )lookup_objectindextransform_object)r8   rX   objects      r9   resolve_datazDefaultSavePlanner.resolve_data   s+    ##J$4$45$$Z88r;   r[   c                 .    t        | j                  |      S zSExtension from the planner interface to make it easy to extend the default planner.r%   r<   r8   r[   s     r9   rZ   z DefaultSavePlanner.lookup_object       %doou==r;   r]   c                     |j                   t        j                  k(  r,t        j                         }t        j                  ||       |}|S r`   )typer    BYTE_IOioBytesIOtorchsave)r8   rX   r]   bytess       r9   r\   z#DefaultSavePlanner.transform_object   s7    ??m333JJLEJJvu%Fr;   )TTNFNF)__name__
__module____qualname__r   __annotations__boolr	   r:   r   r   rA   r   rH   r   r
   r   rS   rW   r   r   ri   Tensorrg   rh   r^   r   r   rZ   r\    r;   r9   r*   r*   B   s    $((,37*/  "& #+4.	
 $( 
* /3$	-#- {+- 	-
 
-8 /h/	tH~x'	(/0H  9y 9U5<<;S5T 9>= >S >9 c r;   r*   c            	       F   e Zd ZU dZeed<   eed<   	 	 	 ddedededdfd	Z	 	 dd
ede	e
   deddfdZdefdZdee   dee   fdZdedefdZdedej&                  ddfdZdefdZdedej.                  ddfdZdedej.                  fdZdedej.                  fdZy)r+   ak  
    DefaultLoadPlanner that adds multiple features on top of LoadPlanner.

    In particular it adds the following:

    flatten_state_dict: Handle state_dict with nested dicts
    flatten_sharded_tensors: For FSDP in 2D parallel mode
    allow_partial_load: If False, will raise a runtime error if a key is present in state_dict, but not in the checkpoint.
    original_state_dictr1   r   r2   allow_partial_loadr5   Nc                 J    || _         || _        i | _        i | _        || _        y r@   )r   r2   ru   r1   rv   )r8   r   r2   rv   s       r9   r:   zDefaultLoadPlanner.__init__   s+     #5'>$#% "4r;   r<   rO   r>   c                     t        |       || _        | j                  rt        |      }| j                  rt	        |      \  }| _        || _        || _        || _        y r@   )	r$   ru   r2   r   r   r1   r<   rO   r>   )r8   r<   rO   r>   s       r9   rA   z!DefaultLoadPlanner.set_up_planner   sW     	$#- ''1*=J""(::(F%J$ ,r;   c                    | j                   J | j                  rt        | j                  j	                               }t        | j                   j
                  j	                               }||z
  }|r[dt        _        t        | j                        \  }}t        |j	                               }||z  r||c| _        | _	        d t        _        t        | j                  | j                   | j                         S )N2_3)rO   r   setr<   keysstate_dict_metadatar(   _derived_versionru   r1   r,   rv   )r8   current_keys	load_keysmissing_keysold_state_dictold_mappingsold_keyss          r9   rH   z$DefaultLoadPlanner.create_local_plan   s    }}(((""$ t3356LDMM==BBDEI$|3L,1)/A,,0, ~2245l*5C\2DOT] -1)-OOT]]0G0G,G
 	
r;   rN   c                     t        |      S r@   )r-   )r8   rN   s     r9   rS   z%DefaultLoadPlanner.create_global_plan   s    .{;;r;   rT   c                     |S r@   rs   rV   s     r9   rW   zDefaultLoadPlanner.finish_plan   s    r;   	read_itemvaluec                 (   | j                   rNt        | j                  | j                  |j                  j
                     t        j                  |d             y t        j                  |d      | j                  |j                  j
                  <   y )NF)weights_only)	r   r   ru   r1   
dest_indexfqnri   loadr<   )r8   r   r   s      r9   
load_byteszDefaultLoadPlanner.load_bytes   sl    ""((i22667

5u5 9>

E9DOOI00445r;   c                 \    | j                  |j                        }| j                  ||      S r@   )lookup_tensorr   transform_tensorr8   r   tensors      r9   resolve_tensorz!DefaultLoadPlanner.resolve_tensor   s+    ##I$8$89$$Y77r;   r   c                      y r@   rs   r   s      r9   commit_tensorz DefaultLoadPlanner.commit_tensor  s    r;   r[   c                 .    t        | j                  |      S r`   ra   rb   s     r9   r   z DefaultLoadPlanner.lookup_tensor  rc   r;   c                 D    t        ||j                  |j                        S r`   )r   dest_offsetslengthsr   s      r9   r   z#DefaultLoadPlanner.transform_tensor
  s    %fi.D.DiFWFWXXr;   )TTFrl   )rm   rn   ro   __doc__r   rp   r   rq   r:   r	   r   rA   r   rH   r   rS   rW   r   rg   rh   r   r   ri   rr   r   r   r   r   rs   r;   r9   r+   r+      s7    )( $((,#(	
5 
5 "&
5 !	
5
 

5 (,$	-#- 8$- 	-
 
-&%
8 %
N<d8n <h <H  
H 
RZZ 
D 
8 8x  $ >= >U\\ >Y( YELL Yr;   r+   c            	       `     e Zd ZdZd fd	ZdededefdZ	 	 dde	de
e   d	eddf fd
Z xZS )_EmptyStateDictLoadPlannera  
    Extension of DefaultLoadPlanner, which rebuilds state_dict from the saved metadata.
    Useful for loading in state_dict without first initializing a model, such as
    when converting a DCP checkpoint into a Torch save file.

    . N.B. `state_dict` must be an empty dictionary when used with this LoadPlanner

    .. warning::
        Because the entire state dict is initialized, It's recommended to only utilize
        this LoadPlanner on a single rank or process to avoid OOM.

    Nc                 2    || _         t        |   |i | y r@   )r|   superr:   )r8   r|   argskwargs	__class__s       r9   r:   z#_EmptyStateDictLoadPlanner.__init__  s    	$)&)r;   keyrO   r5   c           	      4     j                   y| j                   v r	 g }|j                  j                  |      }|D ]D  }|r/|j                  dj	                  |d   t        |      g             4|j                  |       F t         fd|D              ryy)NT.c              3   :   K   | ]  }|j                   v   y wr@   )r|   ).0unflattened_keyr8   s     r9   	<genexpr>zA_EmptyStateDictLoadPlanner._should_include_key.<locals>.<genexpr>3  s     T$))+Ts   F)r|   rD   getappendjoinstrany)r8   r   rO   unflattened_keysrD   r   s   `     r9   _should_include_keyz._EmptyStateDictLoadPlanner._should_include_key!  s    99$))&(,,005+ 	9O ''HH.r2C4HIJ
 !''8	9 TCSTTr;   r<   r>   c                    |rJ |J |j                   j                         D ]  \  }}| j                  ||      st        |t              r5t        j                  |j                  |j                  j                        }||j                  v rt        ||j                  |   |       |||<    t        | 5  |||       y )N)dtype)r}   itemsr   
isinstancer   ri   emptysize
propertiesr   rD   r   r   rA   )r8   r<   rO   r>   kvr   s         r9   rA   z)_EmptyStateDictLoadPlanner.set_up_planner8  s     ~### 00668 		"DAq++Ax8!23KKall.@.@AH)))J(=(=a(@!D !
1		" 	z8^Dr;   r@   rl   )rm   rn   ro   r   r:   r   r   rq   r   r   r	   rA   __classcell__)r   s   @r9   r   r     sj    *s h 4 4 (,$	E#E 8$E 	E
 
E Er;   r   r<   rO   strictr5   c                 D   g }	 | j                         D ]  \  }}||j                  vr|rt        d| d      &|j                  |   }t        |t              r,|j
                  j                         `|t        |||      z  }q|t        |||      z  } t        |      S )Nz&Missing key in checkpoint state_dict: r   )	r   r}   RuntimeErrorr   r&   device_meshget_coordinater"   r   )r<   rO   r   requestsr   objmds          r9   r,   r,   P  s     H $$& 9Sh222"%KC5PQ#RSS))#. c7#--/;.sB<<*3C88H9" Hr;   rI   c                     | S )z
    Create global load plan used by DefaultLoadPlanner.

    The default load behavior involved no global coordination and this function
    currently doesn't change the local plans.
    rs   )rI   s    r9   r-   r-   r  s
     r;   r>   c                     g }| j                         D ]O  \  }}t        |t              r+|j                  j	                         1|t        ||      z  }A|t        ||      z  }Q t        |      S )a  
    Create the ``SavePlan`` used by DefaultSavePlanner.

    On non-coordinator ranks, this function ignores tensors and non-tensor objects,
    only producing writes for ShardedTensor objects.

    On the coordinator rank, produce writes for all values.
    )r   r   r&   r   r   r#   r   )r<   r>   r   r   r   s        r9   r.   r.   ~  sw     H$$& 
6S c7#--/;/S99
 +C55H
6 Hr;   rewrite_index_hintsc                 .   i }g }| D ]  }g }|j                   D ]  }|j                  t        j                  k(  s|j                  j
                  |vsJ |j                  t        j                  k(  r3t               ||j                  j
                  <   |j                  |       |j                  J t        t        |j                  |j                  j
                  t        |j                  j                  |j                  j                  g                   }|}|rKt        j                   |j                  t#        |j$                              }	t        j                   ||	      }|j                  |       |j                  j&                  J d|j                  j
                   d       |j$                  j                  |j                  j&                          |j                  t        j                   ||              |t)        |      fS )a6  
    Create the global plan and metadata used by DefaultSavePlanner.

    Metadata is produced by concatenating the metadata of all ``WriteItem`` from the supplied plans.

    The only global planning change is to update index hints in all ``MetadataIndex`` objects if
    ``rewrite_index_hints`` is True.
    )r   r   chunks)r[   zZ
                    Cannot create MD for tensor without bounds.
                    FQN: z
                )r   )r   re   r    SHARDr[   r   rf   r   r   tensor_datar   r   
setdefaultr   r   rE   rF   lenr   chunkr   )
rI   r   r   	new_plansrG   	new_itemsitem	tensor_mdnew_item	new_indexs
             r9   r/   r/     s    $&BI %E	JJ "	@D99 3 33zz~~R///yyM111%9%;4::>>"  &''333 )MM

-'+'7'7'B'B!%!1!1!6!6#%
	  & + 3 3

#i.>.>*?!I  +224yIH  * $$**6**..) *6
   ''(8(8(>(>?E"	@F 	,,TCDK%EL x|$$r;   c                 :    t        |       }t        |g      \  }}|S )zTReturn the ``Metadata`` if DefaultSavePlanner was used to checkpoint ``state_dict``.)r!   r/   )r<   rG   _r   s       r9   _create_default_local_metadatar     s!    -j9D+TF3EArIr;   box0box1c                    t        | j                        }t        |      D ]d  }| j                  |   |j                  |   |j                  |   z   k\  r y|j                  |   | j                  |   | j                  |   z   k\  sd y y)z9Check if two boxes overlap. Tuples are (offset, lengths).FT)r   offsetsrangesizes)r   r   ndimsis       r9   _check_box_overlapr     sz     E5\ <<?dll1o

1==<<?dll1o

1==	 r;   outer_box_size	inner_boxc                     t        t        |             D ]Q  }|j                  |   dk  r y|j                  |   dk  r y|j                  |   |j                  |   z   | |   kD  sQ y y)Nr   FT)r   r   r   r   )r   r   r   s      r9   _check_box_boundsr     su     3~&' Q!#??1!Q)//!"44~a7HH r;   rN   c           	         d}|j                   j                         D ]5  \  }}t        |t              rt	        |j
                        dk(  r1d}t        |j                        D ]  \  }}t        |j
                  |      s$t        j                  d||j
                  |       d}|t        t        j                  |j                  d      z  }|j                  |dz   d  D ])  }t        ||      st        j                  d|||       d}+  t        t        j                  |j
                  d      }	||	k7  st        j                  d||	|       d}8 |S )NTr   z~
                        key:%s has out of bounds chunk:
                        tensor-size:%s chunk: %s
                    Fr'   z$key:%s has overlapping chunks: %s %szq
                    key:%s invalid fill tensor-volume:
                    %s chunks-volume: %s
                )r}   r   r   r   r   r   	enumerater   r   r)   r7   r   operatormulr   r   )
rN   rO   all_goodr   r   chunks_volume	chunk_idxchunk0chunk1tensor_volumes
             r9   rL   rL     sN   H2288: )
Ue12uzz?a!*5<<!8 	%Iv$UZZ8 JJ !VHLL&,,BBM  ,,y1}7 %%ff5NN>VV  %H%!	%0 x||UZZ;M)NN  HS)V Or;   )T)LrE   rg   loggingr   collectionsr   	functoolsr   typingr   r   r   r   r	   r
   r   ri   torch.distributed._shard._utilsr   .torch.distributed.checkpoint._dedup_save_plansr   )torch.distributed.checkpoint._nested_dictr   r   2torch.distributed.checkpoint._sharded_tensor_utilsr   &torch.distributed.checkpoint._traverser   %torch.distributed.checkpoint.metadatar   r   r   r   r   r   r   r   $torch.distributed.checkpoint.plannerr   r   r   r   r   r   r    ,torch.distributed.checkpoint.planner_helpersr!   r"   r#   r$   "torch.distributed.checkpoint.utilsr%   torch.distributed.tensorr&    r(   	getLoggerrm   r)   Loggerrp   __all__r*   r+   r   r   rq   r,   r-   r.   r/   r   r   Sizer   rL   rs   r;   r9   <module>r     s    	      @ @ @  B K X >	 	 	    F ,  +**84 4T TnsY sYl>E!3 >ED DHS#X*2<@D	H~		(^	S#X04: !%4%H~4%4% 4>8#$4%n 8 1 9M RV  JJ+?	-tH~ - -d -r;   