o
    h9                  	   @   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   b/var/www/html/ai/venv/lib/python3.10/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planner_data)r(   r3   r4   r   dataclassesreplacer*   plan)r/   r:   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   r8   r9   _validate_global_plan
ValueErrorglobal_planmetadata)r/   r<   rC   rD   planner_data_dictmerged_mappingsr0   r0   r1   create_global_planf   s   
z%DefaultSavePlanner.create_global_plannew_planc                 C   s
   || _ |S r.   )r:   r/   rH   r0   r0   r1   finish_plan   s   zDefaultSavePlanner.finish_plan
write_itemc                 C      |  |j}| ||S r.   )lookup_objectindextransform_object)r/   rK   objectr0   r0   r1   resolve_data   s   zDefaultSavePlanner.resolve_datarN   c                 C      t | j|S zo
        This is an extension from the planner interface to make it easy to extend the default planner
        r!   r3   r/   rN   r0   r0   r1   rM         z DefaultSavePlanner.lookup_objectrP   c                 C   s(   |j tjkrt }t|| |}|S rS   )typer   BYTE_IOioBytesIOtorchsave)r/   rK   rP   bytesr0   r0   r1   rO      s
   z#DefaultSavePlanner.transform_object)TTT)__name__
__module____qualname__r   __annotations__boolr2   r   r5   r   r;   r   r   r   rG   rJ   r   r   r[   TensorrY   rZ   rQ   r   r   rM   rO   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+   rd   r*   )r/   r   r+   r0   r0   r1   r2      s   
zDefaultLoadPlanner.__init__r3   rD   r4   c                 C   s>   || _ | jr
t|}| jrt|\}| _|| _|| _|| _d S r.   )rd   r+   r   r   r*   r3   rD   r4   )r/   r3   rD   r4   r0   r0   r1   r5      s   
z!DefaultLoadPlanner.set_up_plannerc                 C   s   t | j| jS r.   )r&   r3   rD   )r/   r0   r0   r1   r;      s   z$DefaultLoadPlanner.create_local_planrC   c                 C   s   t |S r.   )r'   )r/   rC   r0   r0   r1   rG      s   z%DefaultLoadPlanner.create_global_planrH   c                 C   s   |S r.   r0   rI   r0   r0   r1   rJ         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"   rd   r*   
dest_indexfqnr[   loadr3   )r/   rf   rg   r0   r0   r1   
load_bytes   s   zDefaultLoadPlanner.load_bytesc                 C   rL   r.   )lookup_tensorrh   transform_tensorr/   rf   tensorr0   r0   r1   resolve_tensor   s   z!DefaultLoadPlanner.resolve_tensorro   c                 C   s   d S r.   r0   rn   r0   r0   r1   commit_tensor   re   z DefaultLoadPlanner.commit_tensorrN   c                 C   rR   rS   rT   rU   r0   r0   r1   rl      rV   z DefaultLoadPlanner.lookup_tensorc                 C   s   t ||j|jS rS   )r
   dest_offsetslengthsrn   r0   r0   r1   rm      s   
z#DefaultLoadPlanner.transform_tensor)TT)r^   r_   r`   __doc__r   ra   r   rb   r2   r   r5   r   r;   r   rG   rJ   r   rY   rZ   rk   rp   r[   rc   rq   r   rl   rm   r0   r0   r0   r1   r%      s<   
 	



r%   r3   rD   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   rD   requestsri   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)	ru   rw   r   rx   ry   r   r[   rc   r   )r3   r4   rz   ri   r{   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)rN   zZ
                    Cannot create MD for tensor without bounds.
                    FQN: z
                )ru   )ru   rW   r   SHARDrN   ri   rX   r   appendtensor_datar	   r   
setdefaultr~   r   r8   r9   lenr   chunkr   )
r<   r}   r|   	new_plansr:   	new_itemsitem	tensor_mdnew_item	new_indexr0   r0   r1   r)   .  sJ   

r)   c                 C   s   t | }t|g\}}|S )z^
    Return the ``Metadata`` if DefaultSavePlanner was used to checkpoint ``state_dict``.
    )r   r)   )r3   r:   _r|   r0   r0   r1   _create_default_local_metadatae  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 )zC
    Checks if two boxes overlap. Tuples are (offset, lengths)
    FT)r   offsetsrangesizes)r   r   ndimsir0   r0   r1   _check_box_overlapn  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_bounds  s   r   rC   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
                )rv   ru   rw   r   r   r   	enumerater   r   r#   warningr   operatormulr   r   )
rC   rD   all_goodkeyrg   chunks_volume	chunk_idxchunk0chunk1tensor_volumer0   r0   r1   rA     s@   

rA   )T)Fr8   rY   loggingr   collectionsr   	functoolsr   typingr   r   r   r   r   r	   r[   torch.distributed._shard._utilsr
   torch.distributed._tensorr   $torch.distributed.checkpoint.plannerr   r   r   r   r   r   r   %torch.distributed.checkpoint.metadatar   r   r   r   r   r   r   ,torch.distributed.checkpoint.planner_helpersr   r   r   )torch.distributed.checkpoint._nested_dictr   r   2torch.distributed.checkpoint._sharded_tensor_utilsr   +torch.distributed.checkpoint._dedup_tensorsr    "torch.distributed.checkpoint.utilsr!   &torch.distributed.checkpoint._traverser"   	getLogger__file__r#   Loggerra   __all__r$   r%   strr&   r'   rb   r(   r)   r   r   Sizer   rA   r0   r0   r0   r1   <module>   s   
 $$

XR





7	

