U
    ©Ê¹j‰?  ã                   @   s\  d dddddgZ ddlZddlZddlmZmZmZmZmZ ddl	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dd ddgZ e dddg¡Zdd„ ZdZejdeƒ d�aet_tjrÆet_dd„ Zdd„ Zejej fdd„Z!dd „ Z"dd„ Z#ej$ddfdd„Z%dd„ Z&dd„ Z'd-d d!„Z(d"d#„ Z)d$d%„ Z*d&d'„ Z+d(d)„ Z,d*d+„ Z-ed,e%e-ƒ dS ).Úinit_backendÚbackend_registeredÚconstruct_rpc_backend_optionsÚregister_backendÚBackendTypeÚBackendValueé    N)ÚcastÚDictÚListÚSetÚTupleé   )Ú_group_membership_managementÚ_update_group_membership)Úapi)Ú	constantsÚ%construct_rpc_backend_options_handlerÚinit_backend_handlerc                 C   s
   d| j  S )NzBackendType.)Úname)Úself© r   úe/var/www/html/bwave/python/venv/lib/python3.8/site-packages/torch/distributed/rpc/backend_registry.pyÚ_backend_type_repr   s    r   zï
    An enum class of available backends.

    PyTorch ships with a builtin ``BackendType.TENSORPIPE`` backend.
    Additional ones can be registered using the
    :func:`~torch.distributed.rpc.backend_registry.register_backend` function.
©ÚvalueÚnamesc                 C   s   | t j ¡ kS )zø
    Checks if backend_name is registered as an RPC backend.

    Args:
        backend_name (str): string to identify the RPC backend.
    Returns:
        True if the backend has been registered with ``register_backend``, else
        False.
    )r   Ú__members__Úkeys)Úbackend_namer   r   r   r   +   s    
c                 C   sf   t | ƒrtd| › d�ƒ‚dd„ tD ƒ}t| t||d�if|Ž}tjd|d�att_tj	r^t
t_	t|  S )aÐ  Registers a new RPC backend.

    Args:
        backend_name (str): backend string to identify the handler.
        construct_rpc_backend_options_handler (function):
            Handler that is invoked when
            rpc_backend.construct_rpc_backend_options(**dict) is called.
        init_backend_handler (function): Handler that is invoked when the
            `_init_rpc_backend()` function is called with a backend.
             This returns the agent.
    zRPC backend z: already registeredc                 S   s   i | ]}|j |j“qS r   )r   r   )Ú.0Úmemberr   r   r   Ú
<dictcomp>J   s      z$register_backend.<locals>.<dictcomp>)r   r   r   r   )r   ÚRuntimeErrorr   Údictr   ÚenumÚEnumr   Ú__repr__Ú__doc__Ú_backend_type_doc)r   r   r   Zexisting_enum_dictZextended_enum_dictr   r   r   r   8   s$     þÿÿù
c                 K   s   | j j||f|ŽS ©N)r   r   )ÚbackendÚrpc_timeoutÚinit_methodÚkwargsr   r   r   r   \   s     ÿÿc                 O   s   | j j||ŽS r)   )r   r   )r*   Úargsr-   r   r   r   r   g   s    c                 C   s‚   t j}t | |||¡}|d k	s&tdƒ‚|dkrR|| ¡ krRtd|› d| ¡ › �ƒ‚|dkr~|| ¡ kr~td|› d| ¡ › �ƒ‚|S )Nz*Failed to initialize default ProcessGroup.éÿÿÿÿzrank argument z doesn't match pg rank zworld_size argument z doesn't match pg size )Úrpc_constantsZDEFAULT_PROCESS_GROUP_TIMEOUTÚdistZProcessGroupGlooÚAssertionErrorÚrankr"   Úsize)Ústorer3   Ú
world_sizeZprocess_group_timeoutÚgroupr   r   r   Ú_init_process_groupj   s    ÿÿr8   c                 K   s   ddl m} || ||||d�S )Nr   ©ÚTensorPipeRpcBackendOptions)r+   r,   Únum_worker_threadsÚ_transportsÚ	_channels)Ú r:   )r+   r,   r;   r<   r=   r-   r:   r   r   r   Ú1_tensorpipe_construct_rpc_backend_options_handler~   s    ûr?   c                    s   t ‡ fdd„| D ƒƒS )Nc                 3   s<   | ]4}|j d kp2|j dko2d|j  ko.ˆ k n  V  qdS )ÚcpuÚcudar   N)ÚtypeÚindex)r   Úd©Údevice_countr   r   Ú	<genexpr>’   s   ÿz/_tensorpipe_validate_devices.<locals>.<genexpr>)Úall)ÚdevicesrF   r   rE   r   Ú_tensorpipe_validate_devices‘   s    þrJ   c                 C   s’   dd„ t | ¡ ƒD ƒ}t || |||f|¡ dd„ |D ƒ}dd„ |D ƒ}dd„ |D ƒ}dd„ |D ƒ}	t||||	ƒ t| ||ƒ}
t|||
ƒ}|
|fS )Nc                 S   s   g | ]}d di g f‘qS )r>   r   r   )r   Ú_r   r   r   Ú
<listcomp>Ÿ   s     zB_tensorpipe_exchange_and_check_all_device_maps.<locals>.<listcomp>c                 S   s   g | ]\}}}}|‘qS r   r   )r   r   rK   r   r   r   rL   £   s    
 c                 S   s   i | ]\}}}}||“qS r   r   )r   r   ÚcountrK   r   r   r   r!   ¤   s    
  zB_tensorpipe_exchange_and_check_all_device_maps.<locals>.<dictcomp>c                 S   s   i | ]\}}}}||“qS r   r   )r   r   rK   Úmap_r   r   r   r!   ¥   s    
  c                 S   s   i | ]\}}}}||“qS r   r   )r   r   rK   rI   r   r   r   r!   ¦   s    
  )Úranger4   r1   Zall_gather_objectÚ_validate_device_mapsÚ_create_reverse_mappingÚ_create_device_list)Úmy_nameZmy_device_countÚmy_device_mapsÚ
my_devicesr7   ZgatheredÚ	all_namesÚall_device_countsÚall_device_mapsÚall_devicesÚreverse_device_mapsr   r   r   Ú._tensorpipe_exchange_and_check_all_device_mapsš   s    þ 
 ÿr[   Tc           
      C   s  | D ]`}|| }t t|ƒƒt |ƒkr8td|› d|› �ƒ‚t||| ƒstd|› d|› d|| › �ƒ‚q| D �]”}|r¬t||  ¡ ƒ | ¡s¬td|› d||  ¡ › d| › �ƒ‚||  ¡ D �]D\}}	t t|	 ¡ ƒƒt |	ƒkrôtd|› d|› d|	› �ƒ‚|| �r<t|	 ¡ ƒ || ¡�sttd|› d	|› d|	› d
|| › �ƒ‚n8t|	 ¡ || ƒ�sttd|› d|› d|	› d|| › �ƒ‚| |g ¡�rÀt|	 ¡ ƒ || ¡�sþtd|› d|› d|	› d
|| › �ƒ‚q¸||kr¸t|	 ¡ || ƒs¸td|› d|› d|	› d|| › �ƒ‚q¸qjd S )NzNode z" has duplicated devices
devices = z, has devices with invalid indices
devices = z
device count = z@ has invalid target node names in its device maps
device maps = z
node names = z5 has duplicated target devices in its device map for z
device map = z5 has unexpected source devices in its device map for z
devices = z? has source devices with invalid indices in its device map for z5 has unexpected target devices in its device map for z? has target devices with invalid indices in its device map for )	ÚlenÚsetÚ
ValueErrorrJ   r   ÚissubsetÚitemsÚvaluesÚget)
rV   rW   rX   rY   Úis_static_groupÚnoderI   Zsource_nodeZtarget_noderN   r   r   r   rP   ¯   sX    ÿÿ
ÿÿ
ÿ ÿÿÿ
 ÿÿrP   c                 C   sn   | sZt ƒ }| ¡ D ]}| | ¡ ¡ q| ¡ D ]}| | ¡ ¡ q.| t d¡¡ t|ƒ} t| dd„ d�} | S )Nr@   c                 S   s   | j S r)   )rC   )rD   r   r   r   Ú<lambda>ù   ó    z%_create_device_list.<locals>.<lambda>)Úkey)	r]   ra   Úupdater   ÚdiscardÚtorchZdeviceÚlistÚsorted)rU   rT   rZ   Zdevices_setrN   r   r   r   rR   ð   s    rR   c                 C   s<   i }|D ].}| || krdd„ || |    ¡ D ƒ||< q|S )Nc                 S   s   i | ]\}}||“qS r   r   )r   ÚkÚvr   r   r   r!      s     z+_create_reverse_mapping.<locals>.<dictcomp>)r`   )rS   rV   rX   rZ   rd   r   r   r   rQ   ü   s    ÿrQ   c                  C   sT   ddl m}  t| t ¡ ƒ}| ¡ }tj ¡ }tj 	¡ rF|j
rFtj ¡  ||j|j
fS )Nr   ©ÚTensorPipeAgent)r>   rp   r   r   Z_get_current_rpc_agentÚ_get_backend_optionsrj   rA   rF   Úis_availablerI   ÚinitÚdevice_maps)rp   ÚagentÚoptsrF   r   r   r   Ú_get_device_infos  s    

rw   c                 C   s  ddl m} t|| ƒ} |  ¡ }|j}|  ¡ }i i i g f\}}}}|D ]j}	|	j}
|
|krjt |
t¡\}}}n"|  	¡ }t
j ¡ |j|j  }}}|||
< |||
< |||
< | |
¡ qDt||||dd� t|||ƒ}|D ]8}
t||
 ||
 |ƒ||
< tj|
t|||
 |dfd� qÒd S )Nr   ro   F)rc   T)r.   )r>   rp   r   Zget_worker_infor   Zget_worker_infosr   Zrpc_syncrw   rq   rj   rA   rF   rt   rI   ÚappendrP   rQ   rR   r   )ru   rp   Zmy_worker_inforS   Zall_worker_infosrW   rX   rY   rV   Zworker_infoZworker_namerF   Z
device_maprI   rv   rZ   r   r   r   Ú#_set_devices_and_reverse_device_map  s.    
ÿry   c              
   C   sR  ddl m} ddl m} t| tjƒs2td| › �ƒ‚t||ƒsJtd|› �ƒ‚tj 	¡ }|r\dnd}|rÞt
| ||ƒ}	t|||j|j|	ƒ\}
}tj ¡ r |r tj ¡  || |||||
|ƒ}t |¡ tjd |jd� |	 ¡  ¡  |S t| |dƒ�^ || ||||i g ƒ}t |¡ zt|ƒ W n  tk
�r6   t ¡  ‚ Y nX |W  5 Q R £ S Q R X d S )	Nr   ro   r9   z`store` must be a c10d::Store. z?`rpc_backend_options` must be a `TensorPipeRpcBackendOptions`. TF)Útimeout)r>   rp   r:   Ú
isinstancer1   ÚStoreÚ	TypeErrorrj   rA   rF   r8   r[   rt   rI   rr   rs   r   Z_init_rpc_statesZ_all_gatherr+   ZbarrierÚwaitr   ry   Ú	ExceptionÚshutdown)r5   r   r3   r6   Zrpc_backend_optionsrp   r:   rF   rc   r7   rZ   rI   ru   r   r   r   Ú _tensorpipe_init_backend_handler/  sn     ÿÿ
û
ù

ù	
r�   Z
TENSORPIPE)T).Ú__all__Úcollectionsr$   Útypingr   r	   r
   r   r   rj   Ztorch.distributedÚdistributedr1   Z_utilsr   r   r>   r   r   r0   Ú
namedtupler   r   r(   r%   r#   r   r&   r'   r   r   ZDEFAULT_RPC_TIMEOUT_SECZDEFAULT_INIT_METHODr   r   r8   ZDEFAULT_NUM_WORKER_THREADSr?   rJ   r[   rP   rR   rQ   rw   ry   r�   r   r   r   r   Ú<module>   s\    ÿ ÿ
&ý
û
	
A		!Xý