U
    d?                     @   s&  d dl Z d dlZ d dlm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 zd dlZW n ek
rx   Y nX G dd deZG dd	 d	eZe Zd
d Zdd Zdd Zdd Zdd Z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!d&d' Z"d(d) Z#dS )+    N)check_serializing_named_tensor)register_after_fork)ForkingPickler)Unionc                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	StorageWeakRefzA weak reference to a Storage.

    The cdata member is a Python number containing the integer representation of
    the Storage pointer.c                 C   s   |  | _tjj| _d S N)Z	_weak_refcdatatorchStorage_free_weak_ref)selfstorage r   D/tmp/pip-unpacked-wheel-ua33x9lu/torch/multiprocessing/reductions.py__init__   s    
zStorageWeakRef.__init__c                 C   s   t j| jS r   )r	   r
   Z_expiredr   r   r   r   r   expired"   s    zStorageWeakRef.expiredc                 C   s   |  | j d S r   )r   r   r   r   r   r   __del__%   s    zStorageWeakRef.__del__N)__name__
__module____qualname____doc__r   r   r   r   r   r   r   r      s   r   c                   @   s8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )SharedCachez9dictionary from multiprocessing handles to StorageWeakRefc                 C   s   d| _ |   t| tj d S )N   )limit_after_forkr   r   r   r   r   r   r   ,   s    zSharedCache.__init__c                 C   s   t  | _d S r   )	threadingLocklockr   r   r   r   r   6   s    zSharedCache._after_forkc              
   C   s*   | j  t| |W  5 Q R  S Q R X d S r   )r   dictget)r   keyr   r   r   r    9   s    zSharedCache.getc              	   C   s:   | j * t| || t| | jkr,|   W 5 Q R X d S r   )r   r   __setitem__lenr   free_dead_references)r   r!   storage_refr   r   r   r"   =   s    zSharedCache.__setitem__c                 C   sF   d}t |  D ] \}}| r(| |= q|d7 }qtd|d | _d S )Nr      r      )listitemsr   maxr   )r   Zliver!   r%   r   r   r   r$   C   s    
z SharedCache.free_dead_referencesN)	r   r   r   r   r   r   r    r"   r$   r   r   r   r   r   )   s   
r   c                 C   s   t jj| |S r   )r	   cudaEventZfrom_ipc_handle)devicehandler   r   r   rebuild_eventQ   s    r/   c                 C   s   |   }t| j|ffS r   )Z
ipc_handler/   r-   )eventr.   r   r   r   reduce_eventU   s    r1   c                 C   sJ   |\}}}}t j||||}| t jjjkr@t jjj||d}n||_|S )Nrequires_grad)r	   _utils_rebuild_tensornn	parameter	Parameterr3   )clsr   metadatastorage_offsetsizestrider3   tr   r   r   rebuild_tensorZ   s    r?   c              
   C   s   |d ks|dkr |d||d}nZt |||	f}|d krjtj  |||||	||||}t|t||	f< n|j|||d tj	tj
j| |d|||}| tjjjkrtjjj||
d}n|
|_|S )Nr   )dtyper-   )r-   wrap_storager@   r2   )storage_from_cacher	   r+   Z
_lazy_initZ_new_shared_cudar   shared_cacheZ_release_ipc_counterr4   r5   r   _TypedStorageZ_untypedr6   r7   r8   r3   )Z
tensor_clsZtensor_sizeZtensor_stridetensor_offsetZstorage_clsr@   Zstorage_deviceZstorage_handlestorage_size_bytesstorage_offset_bytesr3   ref_counter_handleref_counter_offsetevent_handleevent_sync_requiredr   r>   r   r   r   rebuild_cuda_tensorg   s6    
	  rM   c                 C   s   |   }| jr| jstdt|  tjj|  |j	r|
 \}}}}}}}}	|  }
t|t|< tt| |  |  |
t|| j||||| j||||	ffS |  |  |  | jf}tt| ||ffS )NzCowardly refusing to serialize non-leaf tensor which requires_grad, since autograd does not support crossing process boundaries.  If you just want to transfer the data, call detach() on the tensor before serializing (e.g., putting it on the queue).)r   r3   Zis_leafRuntimeErrorr   r	   utilshooksZwarn_if_has_hooksis_cudaZ_share_cuda_r;   r   rD   rM   typer<   r=   r@   r?   )Ztensorr   r-   r.   rG   rH   rI   rJ   rK   rL   rF   r:   r   r   r   reduce_tensor   sR    \rS   c                 C   s   t | }|j|jfS r   )osfstatst_inost_dev)fdstatr   r   r   fd_id  s    
rZ   c                 C   s$   t |}|d krd S tj|jS r   )rD   r    r	   _UntypedStorageZ_new_with_weak_ptrr   )r9   r!   r%   r   r   r   rC   !  s    
rC   c              	   C   s\   |  }zBt| t|}|d k	r(|W &S | ||}t|tt|< |W S t| X d S r   )detachrT   closerC   rZ   Z_new_shared_fd_cpur   rD   )r9   dfr<   rX   r   r   r   r   rebuild_storage_fd(  s    r_   c                 C   sv   t | |}|d k	r| S |d kr4tj|||}n.|tj| }tj|||}tj||d}t|t	|< | S NrA   )
rC   Z_shared_decrefr	   r[   Z_new_shared_filename_cpur4   Z_element_sizerE   r   rD   )r9   managerr.   r<   r@   r   Z	byte_sizeZuntyped_storager   r   r   rebuild_storage_filename5  s    
rb   c                 C   s   |  S r   r   )r9   r   r   r   rebuild_storage_emptyE  s    rc   c                 C   s   t jj| |dS r`   )r	   r   rE   )r   r@   r   r   r   rebuild_typed_storageH  s    rd   c                 C   s   t | j| jffS r   )rd   _storager@   r   r   r   r   reduce_typed_storageL  s    rg   c                 C   s
   || dS )N)rB   r   )r   Zstorage_typer   r   r   rebuild_typed_storage_childO  s    rh   c                 C   s   t | jt| ffS r   )rh   re   rR   rf   r   r   r   reduce_typed_storage_childS  s    ri   c                 C   s   ddl m} | jrtdn| dkr\|  }|d }t}t| tjrR|| j	f7 }| 
  nF|  dkrvtt| ffS |  \}}tj|}t|}||f}t}t| t|< |t| f| fS )Nr&   )get_sharing_strategyz>Cannot pickle CUDA storage; try pickling a CUDA tensor insteadZfile_systemr   ) rj   rQ   rN   Z_share_filename_cpu_rb   
isinstancer	   rE   r@   Z_shared_increfr<   rc   rR   Z_share_fd_cpu_multiprocessingZ	reductionZDupFdrZ   r_   r   rD   )r   rj   r:   	cache_keyZrebuildrX   r<   r^   r   r   r   reduce_storageV  s&    


ro   c                  C   s   t tjjt tjD ](} | jdkr2t | t qt | t	 qt tj
jt tjD ]} t | t qVt tjt t tjjjt d S )Nr[   )r   registerr	   r+   r,   r1   Z_storage_classesr   ro   ri   r   rE   rg   Z_tensor_classesrS   ZTensorr6   r7   r8   )r>   r   r   r   init_reductionsp  s    


rq   )N)$r	   Ztorch.utils.hooksZtorch._namedtensor_internalsr   rT   r   rm   Zmultiprocessing.utilr   Zmultiprocessing.reductionr   typingr   Zmultiprocessing.resource_sharerImportErrorobjectr   r   r   rD   r/   r1   r?   rM   rS   rZ   rC   r_   rb   rc   rd   rg   rh   ri   ro   rq   r   r   r   r   <module>   s@   %& 
