U
    ©Ê¹jƒ0  ã                   @   sœ  d dl Z d dlZd dlmZmZmZmZmZmZm	Z	m
Z
mZ d dlmZ ddl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 ddlmZmZ d	d
gZedƒZedƒZ eeeef  ee!ef dœdd„Z"G dd„ dƒZ#eeedœdd„Z$ej%eej%dœdd	„Z&eee	dœdd
„Z'ee! ee! ee! dœdd„Z(ee! ee! ee! dœdd„Z)G dd„ dej*ƒZ+ej*e!e!ej*dœd d!„Z,e-e!e-d"œd#d$„Z.dS )%é    N)	ÚListÚCallableÚOptionalÚUnionÚTypeVarÚDictÚAnyÚcastÚSequenceé   )ÚCheckpointExceptionÚ_wrap_exceptionÚ_is_wrapped_exceptionÚWRAPPED_EXCEPTION)ÚShardedTensor)ÚShard)ÚDTensor)ÚSTATE_DICT_TYPEÚMetadataIndexÚfind_tensor_shardÚfind_state_dict_objectÚTÚR)ÚresultsÚreturnc                 C   s    t tttf dd„ t| ƒD ƒƒS )Nc                 S   s   i | ]\}}t |ƒr||“qS © )r   )Ú.0ÚiÚerrr   r   úa/var/www/html/bwave/python/venv/lib/python3.8/site-packages/torch/distributed/checkpoint/utils.pyÚ
<dictcomp>.   s       z%_get_failure_dict.<locals>.<dictcomp>)r	   r   Úintr   Ú	enumerate)r   r   r   r   Ú_get_failure_dict)   s    
þr#   c                   @   s,  e Zd ZdZeej eedœdd„Z	edœdd„Z
edœdd	„Zee ed
œdd„Zeeee  d
œdd„Zeee d
œdd„Zeee  edœdd„Zeeg ef eee gee f edœdd„Zeeg ef eee gef edœdd„Zeeg ef ee dœdd„Zeeg ef edœdd„ZdS )Ú_DistWrapperaH  
    This is a wrapper around PG that provides a series of features around object collectives.

    It works without distributed initialized, where most collectives turns into nops.

    All variants that take functions are exception robust, meaning that if one or more
    ranks raise errors, all ranks will observe those.
    )ÚgroupÚuse_distÚcoordinator_rankc                 C   sB   || _ || _|| _| jr2t |¡| _| j|k| _nd| _d| _d S )Nr   T)r%   r&   r'   ÚdistÚget_rankÚrankÚis_coordinator)Úselfr%   r&   r'   r   r   r   Ú__init__<   s    z_DistWrapper.__init__©r   c                 C   s   | j S ©N)r*   ©r,   r   r   r   r)   L   s    z_DistWrapper.get_rankc                 C   s   | j rt | j¡S dS )Nr   )r&   r(   Úget_world_sizer%   r0   r   r   r   r1   O   s    z_DistWrapper.get_world_size)Úobjectr   c                 C   s.   |g}| j r tj|| j| jd� tt|d ƒS )z\
        Same as c10d::broadcast_object_list but works without distributed enabled.
        )Úobject_listr%   Úsrcr   )r&   r(   Zbroadcast_object_listr%   r'   r	   r   )r,   r2   r3   r   r   r   Úbroadcast_objectT   s    ýz_DistWrapper.broadcast_objectc                 C   s\   | j rR| jr(ttt dgt | j¡ ƒnd}tj|| jr<|nd| j	| jd� |}n|g}|S )zT
        Same as c10d::gather_object but works without distributed enabled.
        N)ÚobjZobject_gather_listÚdstr%   )
r&   r+   r	   r   r   r(   r1   r%   Úgather_objectr'   )r,   r2   Úgather_objsÚresultr   r   r   r8   a   s    ÿýüz_DistWrapper.gather_objectc                 C   s@   | j r6ttt dgt | j¡ ƒ}tj||| jd� n|g}|S )zX
        Same as c10d::all_gather_object but works without distributed enabled.
        N)r3   r6   r%   )r&   r	   r   r   r(   r1   r%   Úall_gather_object)r,   r2   r9   r   r   r   r;   w   s     ÿ  ÿz_DistWrapper.all_gather_object)r3   r   c                 C   sX   | j r@ttt dgƒ}tj|| jr&|nd| j| jd� |d }n|dk	sLt	‚|d }|S )zU
        Same as c10d::scatter_object but works without distributed enabled.
        N)Zscatter_object_output_listZscatter_object_input_listr4   r%   r   )
r&   r	   r   r   r(   Zscatter_object_listr+   r'   r%   ÚAssertionError)r,   r3   Zgather_resultZlocal_replyr   r   r   Úscatter_object‡   s    ÿú	
z_DistWrapper.scatter_object)ÚstepÚmap_funÚ
reduce_funr   c           
   
   C   s   z
|ƒ }W n* t k
r4 } zt|ƒ}W 5 d}~X Y nX |  |¡}d}| jrä|dk	sVt‚t|ƒ}t|ƒdkrÄz(ttt	t
tf  |ttt |ƒƒƒ}W n0 t k
rÂ } zt|ƒ|| j< W 5 d}~X Y nX t|ƒdkrät||ƒg|  ¡  }|  |¡}	t|	tƒrü|	‚|	S )a^  
        Compute a value on each rank, then do centralized reduce on a single rank, followed by a scatter.

        This method operates in the following way:
            Run ``map_fun`` on all ranks
            Gather results on rank 0
            Call ``reduce_fun`` on all those values
            Scatter to each rank part of the result.
        Nr   )ÚBaseExceptionr   r8   r+   r<   r#   Úlenr	   r   r   r   r   r   r*   r1   r=   Ú
isinstance)
r,   r>   r?   r@   Ú
local_dataÚeÚall_dataÚall_resultsÚnode_failuresr:   r   r   r   Úreduce_scatterœ   s4    

þ ÿþ

z_DistWrapper.reduce_scatterc           
   
   C   sê   z
|ƒ }W n* t k
r4 } zt|ƒ}W 5 d}~X Y nX |  |¡}d}| jrÈ|dk	sVt‚t|ƒ}t|ƒdkr²z|ttt	 |ƒƒ}W n0 t k
r° } zt|ƒ|| j
< W 5 d}~X Y nX t|ƒdkrÈt||ƒ}|  |¡}	t|	tƒrà|	‚tt|	ƒS )aa  
        Compute a value on each rank, then do centralized reduce on a single rank, followed by a broadcast.

        This method operates in the following way:
            Run ``map_fun`` on all ranks
            Gather results on rank 0
            Call ``reduce_fun`` on all those values
            Broadcast the reduced value to all ranks.
        Nr   )rA   r   r8   r+   r<   r#   rB   r	   r   r   r*   r   r5   rC   r   )
r,   r>   r?   r@   rD   rE   rF   r:   rH   Úfinal_resultr   r   r   Ú
all_reduceË   s(    

 


z_DistWrapper.all_reduce)r>   r?   r   c              
   C   sl   z
|ƒ }W n* t k
r4 } zt|ƒ}W 5 d}~X Y nX |  |¡}t|ƒ}t|ƒdkr^t||ƒ‚ttt |ƒS )zÐ
        Compute a value on each rank, then all_gather them.

        This method operates in the following way:
            Run ``map_cp`` on all ranks
            all_gather the values to all ranks
        Nr   )	rA   r   r;   r#   rB   r   r	   r   r   )r,   r>   r?   r:   rE   rG   rH   r   r   r   Ú
all_gatheró   s    


z_DistWrapper.all_gatherc              
   C   sn   d}| j rLz
|ƒ }W n6 tk
rJ } zt|| jt|ƒiƒ}W 5 d}~X Y nX |  |¡}t|tƒrd|‚tt|ƒS )z¶
        Compute a value on rank 0 and broadcast it.

        This method operates in the following way:
            Run ``map_cp`` on rank 0
            broadcast the value
        N)	r+   rA   r   r*   r   r5   rC   r	   r   )r,   r>   r?   r:   rE   rJ   r   r   r   Ú	broadcast  s    
 ÿ

z_DistWrapper.broadcastN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r(   ZProcessGroupÚboolr!   r-   r)   r1   r   r5   r   r8   r;   r=   Ústrr   r   rI   rK   rL   rM   r   r   r   r   r$   2   s:   ü
û1
û*
ü
ür$   )ÚtensorÚindexr   c                 C   s¤   |j d krtd|j› d�ƒ‚|  ¡ }|jd k	r`t|ƒ|jkr`t ||j jj	¡|j kr`||j S |D ] }t |jj	¡|j krd|  S qdtd|j › d|j› d�ƒ‚d S )NzCannot lookup z5 since its a ShardedTensor and no offset was providedzCould not find shard at 'z' for FQN: 'ú')
ÚoffsetÚ
ValueErrorÚfqnZlocal_shardsrU   rB   ÚtorchÚSizeÚmetadataZshard_offsets)rT   rU   ZshardsZshardr   r   r   Ú_find_shard&  s&    
ÿ
ÿÿþ

ÿr]   c                 C   sr   t | tƒr|  ¡ S t | tƒr(t| |ƒjS |jd k	rn|jt dgt	|  
¡ ƒ ¡krT| S td|j› d|j› d�ƒ‚| S )Nr   úFQN: 'ú1' is not a ShardedTensor, can't find by offset: 'rV   )rC   r   Zto_localr   r]   rT   rW   rZ   r[   rB   ÚsizerX   rY   )rT   rU   r   r   r   r   >  s    


ÿ)Ú
state_dictrU   r   c                 C   sd   |j | krtd|j › d�ƒ‚| |j  }t|tjƒr<t||ƒS |jd k	r`td|j › d|j› d�ƒ‚|S )NzCould not find FQN: 'rV   r^   r_   )rY   rX   rC   rZ   ÚTensorr   rW   )ra   rU   r6   r   r   r   r   O  s    



ÿ)ÚaÚbr   c                 C   s   dd„ t | |ƒD ƒS )Nc                 S   s   g | ]\}}|| ‘qS r   r   ©r   Zi_aZi_br   r   r   Ú
<listcomp>`  s     z%_element_wise_add.<locals>.<listcomp>©Úzip©rc   rd   r   r   r   Ú_element_wise_add_  s    rj   c                 C   s   dd„ t | |ƒD ƒS )Nc                 S   s   g | ]\}}|| ‘qS r   r   re   r   r   r   rf   d  s     z%_element_wise_sub.<locals>.<listcomp>rg   ri   r   r   r   Ú_element_wise_subc  s    rk   c                       s|   e Zd Zejeedœ‡ fdd„Zejfeeedœdd„Z	edœdd	„Z
edœd
d„Zedœdd„Zdd„ Zddd„Z‡  ZS )Ú_ReaderView)Úbase_streamrW   rB   c                    s*   t ƒ  ¡  || _|| _|| _|  d¡ d S )Nr   )Úsuperr-   rW   rB   rm   Úseek)r,   rm   rW   rB   ©Ú	__class__r   r   r-   h  s
    
z_ReaderView.__init__)Ú_ReaderView__offsetÚ_ReaderView__whencer   c                 C   sD   |t jkr| j| }n |t jkr6t j}| j| j | }| j ||¡S r/   )ÚosÚSEEK_SETrW   ÚSEEK_ENDrB   rm   ro   )r,   rr   rs   r   r   r   ro   o  s    

z_ReaderView.seekr.   c                 C   s   | j  ¡ | j S r/   )rm   ÚtellrW   r0   r   r   r   rw   w  s    z_ReaderView.tellc                 C   s
   | j  ¡ S r/   )rm   Úreadabler0   r   r   r   rx   z  s    z_ReaderView.readablec                 C   s
   | j  ¡ S r/   )rm   Úseekabler0   r   r   r   ry   }  s    z_ReaderView.seekablec                 C   s   | j  |¡S r/   )rm   Úreadinto)r,   rd   r   r   r   rz   €  s    z_ReaderView.readintoéÿÿÿÿc                 C   s   | j  |¡S r/   )rm   Úread)r,   r`   r   r   r   r|   ƒ  s    z_ReaderView.read)r{   )rN   rO   rP   ÚioÚIOBaser!   r-   rt   ru   ro   rw   rR   rx   ry   rz   r|   Ú__classcell__r   r   rp   r   rl   g  s   rl   )ÚfilerW   Úlengthr   c                 C   s   t | ||ƒS r/   )rl   )r€   rW   r�   r   r   r   Ú_create_file_view‡  s    r‚   )Údevice_typeÚ	device_idr   c                 C   s   | dkrdS | › d|› �S )z$
    Device info normalization.
    Úcpuú:r   )rƒ   r„   r   r   r   Ú_normalize_device_infoŒ  s    r‡   )/rt   r}   Útypingr   r   r   r   r   r   r   r	   r
   Ztorch.distributedÚdistributedr(   Úapir   r   r   r   rZ   Z'torch.distributed._shard.sharded_tensorr   Z-torch.distributed._shard.sharded_tensor.shardr   Ztorch.distributed._tensorr   r\   r   r   Ú__all__r   r   r!   r#   r$   r]   rb   r   r   rj   rk   r~   rl   r‚   rS   r‡   r   r   r   r   Ú<module>   s>   ,
þ	 u þ þ 