U
    ©Ê¹j<+  ã                   @   s   d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlmZ d dl	Z	d dl
mZ d dlmZ dddddgZe ¡ aejZejZG d	d„ deƒZG d
d„ dƒZeƒ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Ze  ddddg¡Z e  dddg¡Z!dS )é    N)ÚEnum)Ú_get_current_rpc_agentÚRPCExecModeÚ	serializeÚdeserializeÚ	PythonUDFÚRemoteExceptionc                   @   s   e Zd ZdZdZdZdZdS )r   ÚsyncÚasyncZ	async_jitÚremoteN)Ú__name__Ú
__module__Ú__qualname__ZSYNCÚASYNCZ	ASYNC_JITZREMOTE© r   r   ú]/var/www/html/bwave/python/venv/lib/python3.8/site-packages/torch/distributed/rpc/internal.pyr      s   c                   @   st   e Zd ZdZdd„ Zdd„ Zedd„ ƒZdd	„ Zed
d„ ƒZ	dd„ Z
dd„ Zedd„ ƒZdd„ Zdd„ Zdd„ ZdS )Ú_InternalRPCPicklera	  
    This class provides serialize() and deserialize() interfaces to serialize
    data to be "binary string + tensor table" format
    So for RPC python UDF function and args, non tensor data will be serialized
    into regular binary string, tensor data will be put into thread local tensor
    tables, this serialization format is consistent with builtin operator and args
    using JIT pickler. This format will make tensor handling in C++ much easier,
    e.g. attach tensor to distributed autograd graph in C++
    c                 C   s$   t j ¡ | _| j| jtj< i | _d S ©N)ÚcopyregÚdispatch_tableÚcopyÚ_dispatch_tableÚ_tensor_reducerÚtorchZTensorÚ_class_reducer_dict)Úselfr   r   r   Ú__init__)   s    z_InternalRPCPickler.__init__c                 C   s   || j kr|| j |< d S r   )r   )r   Z	obj_classZreducerr   r   r   Ú_register_reducer0   s    
z%_InternalRPCPickler._register_reducerc                 C   s
   t j| S r   )Ú_thread_local_tensor_tablesÚrecv_tables)ÚclsÚtensor_indexr   r   r   Ú_tensor_receiver5   s    z$_InternalRPCPickler._tensor_receiverc                 C   s&   t j |¡ tt jƒd }tj|ffS )Né   )r   Úsend_tablesÚappendÚlenr   r"   )r   Ztensorr!   r   r   r   r   :   s    z#_InternalRPCPickler._tensor_reducerc                 C   s   t jj |¡S r   )ÚdistÚrpcÚPyRRefZ_deserialize)r    Úrref_fork_datar   r   r   Ú_py_rref_receiver@   s    z%_InternalRPCPickler._py_rref_receiverc                 C   s   |  ¡ }tj|ffS r   )Z
_serializer   r+   )r   Zpy_rrefr*   r   r   r   Ú_py_rref_reducerD   s    z$_InternalRPCPickler._py_rref_reducerc                 C   s
   |   |¡S r   )r,   )r   Zrrefr   r   r   Ú_rref_reducerH   s    z!_InternalRPCPickler._rref_reducerc                 C   s   t  |¡}tj |¡}|S )zŽ
        Given a serialized representation of a ScriptModule created with torch.jit.save,
        loads and returns the ScriptModule.
        )ÚioÚBytesIOr   ÚjitÚload)r    Zscript_module_serializedÚfÚmr   r   r   Ú_script_module_receiverK   s    
z+_InternalRPCPickler._script_module_receiverc                 C   s&   t  ¡ }tj ||¡ tj| ¡ ffS )z,
        Serializes a ScriptModule.
        )r.   r/   r   r0   Úsaver   r4   Úgetvalue)r   Zscript_moduler2   r   r   r   Ú_script_module_reducerU   s    z*_InternalRPCPickler._script_module_reducerc                 C   sÀ   t  ¡ }t|ƒ}| j|_| j|jtjj< | j	|jtjj
< t|tjjƒrT| j|j|j< | j ¡ D ]}| j| |j|< q^ttdƒr†tj}nd}g t_| |¡ tj}|dk	r°|t_nt`| ¡ |fS )ze
        Serialize non tensor data into binary string, tensor data into
        tensor table
        r$   N)r.   r/   Ú_picklerr   r   r,   r'   r(   r)   r-   ZRRefÚ
isinstancer   r0   ZScriptModuler7   Ú	__class__r   ÚkeysÚhasattrr   r$   Údumpr6   )r   Úobjr2   ÚpÚ
class_nameZold_send_tablesZtensorsr   r   r   r   ]   s&    

z_InternalRPCPickler.serializec              
   C   sŒ   t tdƒrtj}nd}|t_ztt |¡ƒ}| ¡ }W n< tk
rr } zt|ƒd }t|ƒ}||_	W 5 d}~X Y nX |dk	r„|t_nt`|S )zJ
        Deserialize binary string + tensor table to original obj
        r   NzŽ Default RPC pickler does not serialize
            function code. Ensure that UDFs are defined on both caller and
            callee modules.)
r<   r   r   Ú
_unpicklerr.   r/   r1   ÚAttributeErrorÚstrÚ	__cause__)r   Úbinary_dataÚtensor_tableZold_recv_tablesZ	unpicklerÚretÚeÚ
except_strr   r   r   r   ’   s$    
ÿÿz_InternalRPCPickler.deserializeN)r   r   r   Ú__doc__r   r   Úclassmethodr"   r   r+   r,   r-   r4   r7   r   r   r   r   r   r   r      s   



	5r   c                 C   s
   t  | ¡S r   )Ú_internal_rpc_picklerr   )r>   r   r   r   r   ¼   s    c                 C   s   t  | |¡S r   )rL   r   )rE   rF   r   r   r   r   À   s    c              
   C   sŠ   z"t | tƒr| ‚| j| j| jŽ}W nb tk
r„ } zDdtƒ  ¡ › dt|ƒ› dt	 
¡ › �}t|tjd� t|t|ƒƒ}W 5 d}~X Y nX |S )zò
    This function is exclusively called from C++.
    See ``torch/csrc/distributed/rpc/python_rpc_handler.cpp``.

    Runs a Python UDF and returns its return value.
    Wraps any exception in ``RemoteException`` if the function raises.
    zOn z:
Ú
)ÚfileN)r9   rB   ÚfuncÚargsÚkwargsÚ	Exceptionr   Zget_worker_infoÚreprÚ	tracebackÚ
format_excÚprintÚsysÚstderrr   Útype)Z
python_udfÚresultrH   rI   r   r   r   Ú_run_functionÄ   s    
"ÿ r[   c              
   C   s|   t | tƒrx| j d¡ d¡}d }z|  |¡}W n< tk
rj } ztdt|ƒ› d|› �ƒ|‚W 5 d }~X Y nX |d k	rx|‚d S )Nzutf-8Zunicode_escapez8Failed to create original exception type. Error msg was z' Original exception on remote side was )	r9   r   ÚmsgÚencodeÚdecodeÚexception_typeÚBaseExceptionÚRuntimeErrorrC   )rZ   Zexception_msgÚexcrH   r   r   r   Ú_handle_exceptionÛ   s    
ÿýrc   c              	   C   s$   d| j › d|› d|› d|› d�	}|S )aÓ  
    Builds the key that RPC calls are profiled with using the autograd profiler.
    This will be the name of the corresponding Event recorded in the profiler.

    Args:
        exec_type (RPCExecMode): Type of RPC/RRef call
        func_name (str): Name of function being profiled.
        current_worker_name (str): Name of current worker.
        dst_worker_name (str): Name of the destination worker.

    Returns:
        String representing profiling key
    Úrpc_ú#ú(ú -> ú))Úvalue)Ú	exec_typeÚ	func_nameÚcurrent_worker_nameZdst_worker_nameÚprofile_keyr   r   r   Ú_build_rpc_profiling_keyí   s     rn   c              	   C   sR   t j ¡ stdƒ‚d| j› dt|ƒ› d|› d|› d�	}t j ¡ }t j ||¡ |S )ar  
    This function should be called from RPC/RRef functions to create a
    RecordFunction object for profiling. This function also runs the before
    callbacks that start the profiling, though the user is responsible for
    running the appropriate callbacks when the function to be profiled finishes.

    Args:
        exec_type (RPCExecMode): Type of RPC/RRef call
        func_name (str): Name of function being profiled.
        current_worker_name (str): Name of current worker.
        dest_worker_name (str): Name of the destination worker.

    Returns:
        An instance of `torch.autograd._RecordFunction`.
    z$Autograd profiler should be enabled.rd   re   rf   rg   rh   )r   ZautogradZ_profiler_enabledÚAssertionErrorri   rC   Z_RecordFunctionZ_run_before_callbacks)rj   rk   rl   Zdest_worker_namerm   Úrfr   r   r   Ú_start_record_function  s
    $
rq   rO   rP   rQ   r\   r_   )"Úcollectionsr   r.   ÚpicklerW   Ú	threadingrT   Úenumr   r   Ztorch.distributedÚdistributedr'   Ztorch._C._distributed_rpcr   Ú__all__Úlocalr   ÚPicklerr8   Ú	UnpicklerrA   r   r   rL   r   r   r[   rc   rn   rq   Ú
namedtupler   r   r   r   r   r   Ú<module>   s4    