U
    Jcn#                     @   s   d dl Zd dlZd dl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mZ dd	lmZ d
d Zeeejeej ddddZejdddZdddZee ejee	jedddZeee  dddZdS )    N)OptionalListSequence)distributed_c10d)rpc)check_tensor(validate_non_overlapping_shards_metadata)ShardMetadata   )TensorPropertiesShardedTensorMetadata)Shardc                 C   s   |d krt d| }| }| }t| s^|d k	r^|dk sP|t| kr^t d| |d k	rt s|t	d| t
  }|D ]}|j|kr|j|f  S qt d| ||fS )Nzremote device is Noner   zInvalid rank: z>RPC framework needs to be initialized for using worker names: zInvalid worker name: )
ValueErrorworker_namerankdevicer   Z_rank_not_in_groupZget_world_sizer   Z_is_current_rpc_agent_setRuntimeErrorZ_get_current_rpc_agentZget_worker_infosnameid)pgZremote_devicer   r   r   workersZworker r   Q/tmp/pip-unpacked-wheel-gikjz4vx/torch/distributed/_shard/sharded_tensor/utils.py!_parse_and_validate_remote_device   s"    

r   )my_rankdst_ranksize
dst_tensorreturnc                 C   s`   || krP|d krt d| t|| kr\t dt|  dt| n|r\t dd S )Nz>Argument ``dst_tensor`` must be specified on destination rank z"Argument ``dst_tensor`` have size z,but should be zGArgument ``dst_tensor`` must NOT be specified on non-destination ranks.)r   tupler   )r   r   r   r   r   r   r   "_validate_output_tensor_for_gather+   s    r    )r   c                 C   s\   t | dkr(t| d tjjr(t|  }nt| }|D ]}t|ts4td| q4t	|S )zR
    Checks if tensor size is valid, then flatten/return a torch.Size object.
    r
   r   z*size has to be a sequence of ints, found: )
len
isinstancecollectionsabcr   listint	TypeErrortorchSize)r   ZdimsZdimr   r   r   _flatten_tensor_sizeA   s    

r*   Tc                 C   s   |rJt |tst| |krtd| d| d| d|  d| d| dnTt|dksZt| |krtd| d	| d|  d
|d  d| d| d
|d  dd S )NzLocal shards' tensor z& property need to be the same on rank:z! Found one local shard tensor =z, the other local shard tensor .   zShardedTensor z5 property does not match from different ranks! Found 	 on rank:r   z, and r
   )r"   r&   AssertionErrorr   r!   )expectedactualZ	prop_nameZranksis_localr   r   r   _raise_if_mismatchP   s    0r3   )local_shardsglobal_sizecurrent_rankr   r   c                 C   sl  t | dkstdg }| d jj}| d jj}| d jj}| d j }t| D ]\}	}
|
j}|
j}|	| t
||j\}}|jtjks|j|krtd|j d| d| std||krtd| d| |j|krtd	|j d
| t|jt| d| t| |d| t|j|d| t|j|d| qRt|||tj|d}t|||d}|S )Nr   zmust have local shards!z<Only torch.strided layout is currently supported, but found r.   !zBOnly torch.contiguous_format memory_format is currently supported!zxLocal shard metadata's rank does not match with the rank in its process group! Found current rank in the process group: z(, local ShardMetadata placement's rank: zhLocal shard tensor device does not match with local Shard's placement! Found local shard tensor device: z), local shard metadata placement device: r   
pin_memorydtyperequires_grad)r9   layoutr:   Zmemory_formatr8   )shards_metadatar   tensor_properties)r!   r/   Ztensorr9   r;   r:   	is_pinned	enumeratemetadataappendr   Z	placementr(   Zstridedr   Zis_contiguousr   r3   Zshard_sizesr%   r   r   Zcontiguous_formatr   )r4   r5   r6   r   Zlocal_shard_metadatasZfirst_shard_dtypeZfirst_shard_layoutZfirst_shard_requires_gradZfirst_shard_is_pinnediZlocal_shardZlocal_shard_tensorZlocal_shard_metar   Zlocal_deviceZlocal_tensor_propertiesZlocal_sharded_tensor_metadatar   r   r    build_metadata_from_local_shards`   sT    

rC   )gathered_metadatasc                 C   s   d }d}t | D ]\}}|d kr"q|d kr:t|}|}qt|j|jd||gdd t|jj|jjd||gdd t|jj|jjd||gdd t|jj|jjd||gdd |j	
|j	 q|d k	rt|j	 t|j	|j ntd|S )	Nr   r5   F)r2   r9   r:   r8   z0ShardedTensor have no local shards on all ranks!)r?   copydeepcopyr3   r   r=   r9   r:   r8   r<   extendr   r   r   )rD   Zglobal_sharded_tensor_metadataZglobal_metadata_rankr   Zrank_metadatar   r   r   build_global_metadata   sL    

rH   )T)collections.abcr#   rE   typingr   r   r   r(   Ztorch.distributedr   r   Z1torch.distributed._shard.sharding_spec._internalsr   r   Z!torch.distributed._shard.metadatar	   r@   r   r   Zshardr   r   r&   r)   ZTensorr    r*   r3   ZProcessGrouprC   rH   r   r   r   r   <module>   s2   
C