o
    H&i:                  	   @   s0  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 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mZmZmZm Z m!Z!m"Z"m#Z# d d	l$m%Z%m&Z&m'Z' d d
l(m)Z)m*Z* d dl+m,Z, d dl-m.Z. d dl/m0Z0 d dl1m2Z2 e3e4Z5ej6e7d< g dZ8G dd deZ9G dd deZ:dee;ef de!defddZ<de	e de	e fddZ=dee;ef de>defddZ?	 d1de	e d!e>de
e	e e!f fd"d#Z@de"de!fd$d%ZAd&ed'ede>fd(d)ZBd*ejCd+ede>fd,d-ZDd.e	e de!de>fd/d0ZEdS )2    N)ChainMap)reduce)ListTupleDictAnyUnioncast)narrow_tensor_by_index)DTensor)SavePlannerLoadPlannerSavePlanLoadPlanReadItem	WriteItemWriteItemType)BytesStorageMetadataChunkStorageMetadataTensorStorageMetadataMetadataIndexMetadataSTATE_DICT_TYPESTORAGE_TYPES)_create_read_items_create_write_items"_create_default_metadata_only_plan)FLATTEN_MAPPINGflatten_state_dict)_flatten_sharded_tensors)dedup_tensors)find_state_dict_object)set_elementlogger)DefaultSavePlannerDefaultLoadPlannercreate_default_local_load_plancreate_default_global_load_plancreate_default_local_save_plancreate_default_global_save_planc                	   @   s   e Zd ZU eed< 			ddedededdfdd	Zd
ededdfddZde	fddZ
dee	 deee	 ef fddZde	de	fddZdedeejejf fddZdedefddZdedefddZdS ) r$   mappingsTr   flatten_sharded_tensorsdedup_replicated_tensorsreturnNc                 C   s   || _ || _|| _i | _d S N)r   r+   r,   r*   )selfr   r+   r,    r0   WC:\wamp64\www\opt\env\Lib\site-packages\torch/distributed/checkpoint/default_planner.py__init__G   s   
zDefaultSavePlanner.__init__
state_dictis_coordinatorc                 C   s2   | j r
t |\}| _| jrt|}|| _|| _d S r.   )r   r*   r+   r   r3   r4   )r/   r3   r4   r0   r0   r1   set_up_plannerR   s   
z!DefaultSavePlanner.set_up_plannerc                 C   s0   t | j| j}| jrtj|| jd}|| _| jS )NZplanner_data)r(   r3   r4   r   dataclassesreplacer*   plan)r/   r9   r0   r0   r1   create_local_plan\   s   z$DefaultSavePlanner.create_local_plan	all_plansc                 C   sr   | j rt|}t|\}}| jr$dd |D }tt| }tj||d}t||s-t	d|| _
|| _| j
| jfS )Nc                 S   s   g | ]}|j qS r0   r6   ).0pr0   r0   r1   
<listcomp>s   s    z9DefaultSavePlanner.create_global_plan.<locals>.<listcomp>r6   zFailed to validate global plan)r,   r    r)   r   dictr   r7   r8   _validate_global_plan
ValueErrorglobal_planmetadata)r/   r;   rB   rC   Zplanner_data_dictZmerged_mappingsr0   r0   r1   create_global_planf   s   
z%DefaultSavePlanner.create_global_plannew_planc                 C   s
   || _ |S r.   )r9   r/   rE   r0   r0   r1   finish_plan   s   zDefaultSavePlanner.finish_plan
write_itemc                 C      |  |j}| ||S r.   )lookup_objectindextransform_object)r/   rH   objectr0   r0   r1   resolve_data   s   zDefaultSavePlanner.resolve_datarK   c                 C      t | j|S zSExtension from the planner interface to make it easy to extend the default planner.r!   r3   r/   rK   r0   r0   r1   rJ         z DefaultSavePlanner.lookup_objectrM   c                 C   s(   |j tjkrt }t|| |}|S rP   )typer   BYTE_IOioBytesIOtorchsave)r/   rH   rM   bytesr0   r0   r1   rL      s
   z#DefaultSavePlanner.transform_object)TTT)__name__
__module____qualname__r   __annotations__boolr2   r   r5   r   r:   r   r   r   rD   rG   r   r   rX   TensorrV   rW   rN   r   r   rJ   rL   r0   r0   r0   r1   r$   D   sF   
 





r$   c                   @   s   e Zd ZU dZeed< eed< 		d&dededdfd	d
Zdede	deddfddZ
defddZdee dee fddZdedefddZdedejddfddZdefddZdedejddfdd Zd!edejfd"d#Zdedejfd$d%ZdS )'r%   z
    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
    original_state_dictr*   Tr   r+   r-   Nc                 C   s   || _ || _i | _i | _d S r.   )r   r+   ra   r*   )r/   r   r+   r0   r0   r1   r2      s   
zDefaultLoadPlanner.__init__r3   rC   r4   c                 C   s>   || _ | jr
t|}| jrt|\}| _|| _|| _|| _d S r.   )ra   r+   r   r   r*   r3   rC   r4   )r/   r3   rC   r4   r0   r0   r1   r5      s   
z!DefaultLoadPlanner.set_up_plannerc                 C   s   t | j| jS r.   )r&   r3   rC   )r/   r0   r0   r1   r:      s   z$DefaultLoadPlanner.create_local_planrB   c                 C   s   t |S r.   )r'   )r/   rB   r0   r0   r1   rD      s   z%DefaultLoadPlanner.create_global_planrE   c                 C   s   |S r.   r0   rF   r0   r0   r1   rG         zDefaultLoadPlanner.finish_plan	read_itemvaluec                 C   s@   | j rt| j| j|jj t| d S t|| j|jj< d S r.   )	r   r"   ra   r*   
dest_indexfqnrX   loadr3   )r/   rc   rd   r0   r0   r1   
load_bytes   s   zDefaultLoadPlanner.load_bytesc                 C   rI   r.   )lookup_tensorre   transform_tensorr/   rc   tensorr0   r0   r1   resolve_tensor   s   z!DefaultLoadPlanner.resolve_tensorrl   c                 C   s   d S r.   r0   rk   r0   r0   r1   commit_tensor   rb   z DefaultLoadPlanner.commit_tensorrK   c                 C   rO   rP   rQ   rR   r0   r0   r1   ri      rS   z DefaultLoadPlanner.lookup_tensorc                 C   s   t ||j|jS rP   )r
   Zdest_offsetslengthsrk   r0   r0   r1   rj      s   
z#DefaultLoadPlanner.transform_tensor)TT)r[   r\   r]   __doc__r   r^   r   r_   r2   r   r5   r   r:   r   rD   rG   r   rV   rW   rh   rm   rX   r`   rn   r   ri   rj   r0   r0   r0   r1   r%      s<   
 	



r%   r3   rC   r-   c                 C   sd   g }	 |   D ]&\}}|j| }t|tr%|j d ur$|t|||7 }q|t|||7 }qt|S r.   )itemsstate_dict_metadata
isinstancer   device_meshget_coordinater   r   )r3   rC   requestsrf   objmdr0   r0   r1   r&      s   


r&   r;   c                 C   s   | 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.
    r0   )r;   r0   r0   r1   r'     s   	r'   r4   c                 C   sd   g }|   D ]'\}}t|tr|j dur|t||7 }qt|tjs&|r-|t||7 }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.
    N)	rq   rs   r   rt   ru   r   rX   r`   r   )r3   r4   rv   rf   rw   r0   r0   r1   r(     s   
r(   Trewrite_index_hintsc           
      C   s   i }g }| D ]}g }|j D ]q}|jtjks|jj|vsJ |jtjkr0t ||jj< || q|j	dus7J t
t||jjt|j	j|j	jg d}|}|ratj|jt|jd}	tj||	d}|| |j	jdusvJ d|jj d|j|j	j q|tj||d q|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.
    N)
propertiessizechunks)rK   zZ
                    Cannot create MD for tensor without bounds.
                    FQN: z
                )rq   )rq   rT   r   ZSHARDrK   rf   rU   r   appendZtensor_datar	   r   
setdefaultrz   r{   r7   r8   lenr|   chunkr   )
r;   ry   rx   Z	new_plansr9   Z	new_itemsitemZ	tensor_mdZnew_itemZ	new_indexr0   r0   r1   r)   &  sJ   

r)   c                 C   s   t | }t|g\}}|S )zTReturn the ``Metadata`` if DefaultSavePlanner was used to checkpoint ``state_dict``.)r   r)   )r3   r9   _rx   r0   r0   r1   _create_default_local_metadata]  s   r   box0box1c                 C   sd   t | j}t|D ]&}| j| |j| |j|  kr dS |j| | j| | j|  kr/ dS q	dS )z9Check if two boxes overlap. Tuples are (offset, lengths).FT)r   offsetsrangesizes)r   r   Zndimsir0   r0   r1   _check_box_overlapd  s   
r   outer_box_size	inner_boxc                 C   s`   t t| D ]'}|j| dk r dS |j| dk r dS |j| |j|  | | kr- dS qdS )Nr   FT)r   r   r   r   )r   r   r   r0   r0   r1   _check_box_boundsv  s   r   rB   c           
   	   C   s   d}|j  D ]j\}}t|trqt|jdkrqd}t|jD ]:\}}t|j|s5t	
d||j| d}|ttj|jd7 }|j|d d  D ]}t||rYt	
d||| d}qHq ttj|jd}	||	krqt	
d||	| d}q|S )NTr   z~
                        key:%s has out of bounds chunk:
                        tensor-size:%s chunk: %s
                    F   z$key:%s has overlapping chunks: %s %szq
                    key:%s invalid fill tensor-volume:
                    %s chunks-volume: %s
                )rr   rq   rs   r   r   r{   	enumerater|   r   r#   warningr   operatormulr   r   )
rB   rC   all_goodkeyrd   Zchunks_volumeZ	chunk_idxZchunk0Zchunk1Ztensor_volumer0   r0   r1   r@     s@   

r@   )T)Fr7   rV   loggingr   collectionsr   	functoolsr   typingr   r   r   r   r   r	   rX   Ztorch.distributed._shard._utilsr
   Ztorch.distributed._tensorr   Z$torch.distributed.checkpoint.plannerr   r   r   r   r   r   r   Z%torch.distributed.checkpoint.metadatar   r   r   r   r   r   r   Z,torch.distributed.checkpoint.planner_helpersr   r   r   Z)torch.distributed.checkpoint._nested_dictr   r   Z2torch.distributed.checkpoint._sharded_tensor_utilsr   Z+torch.distributed.checkpoint._dedup_tensorsr    Z"torch.distributed.checkpoint.utilsr!   Z&torch.distributed.checkpoint._traverser"   	getLoggerr[   r#   Loggerr^   __all__r$   r%   strr&   r'   r_   r(   r)   r   r   Sizer   r@   r0   r0   r0   r1   <module>   s   
 $$

TN





7

